Makie / GLMakie: Plot image into an axis object

Regarding the function image() I have two questions

  1. If I use space=:pixel, how can I get the current upper offset / padding?
  2. Is it possible to plot a SVG-figure into a GLMakie-figure?

I had to struggle to understand the concept of the parameter space of the function image() / image!() and in the end the concept is now clear to me, below my snippet that should help others to get started with the Makie-function image() / image!():

using GLMakie
using FileIO: load
# --- params:
case_nr     = 5  # space options: #1 :data, #2 :pixel, #3 :relative, #4 :clip (top, left), #5 :clip (center, center) 
y_scale     = 1.0
fig_width   = 800
fig_hight   = 600
x_offset    = +0
y_offset    = -80
x_img_frac  = 0.1

# ---
img_            = load(assetpath("icon_transparent.png"));
# img_            = load(assetpath("icon_transparent.svg"));
aspect_ratio    = size(img_)[1] / size(img_)[2]

# --- plot:
fig_    = Figure(resolution = (fig_width, fig_hight))
ax_     = Axis(fig_[1, 1])

x_vec   = [0, 0.2, 0.4, 0.6, 0.8, 1] 
y_vec   = y_scale .* x_vec
scatter!(ax_, x_vec, y_vec)

# --- space: ---
# --- space::Symbol = :data sets the transformation space for the position of the image. See Makie.spaces() for possible inputs.
# --- spaces() = (:data, :pixel, :relative, :clip)
if case_nr == 1
    Δx_img = x_img_frac * abs(x_vec[end] - x_vec[1])
    # image!(ax_, [x_vec[end] - Δx_img, x_vec[end]], [y_vec[1], y_vec[1] + aspect_ratio * Δx_img], img_, space = :data, overdraw = true, transparency = true)
    x_range = [x_vec[1], x_vec[1] + Δx_img]
    y_range = [y_vec[end] - aspect_ratio * Δx_img, y_vec[end]]
    @show x_range y_range
    image!(ax_, x_range, y_range, img_, space = :data, overdraw = true, transparency = true)
    ax_.title = "space = :data"
elseif case_nr == 2
    Δx_img  = x_img_frac * fig_width
    x_range = x_offset .+ [0, Δx_img]
    y_range = y_offset .+ [fig_hight - aspect_ratio * Δx_img, fig_hight] 
    @show x_range y_range
    image!(ax_, x_range, y_range, img_, space = :pixel, overdraw = true, transparency = true)
    ax_.title = "space = :pixel"
elseif case_nr == 3
    image!(ax_, [0.0, 0.1], [0.9, 1.0], img_, space = :relative, overdraw = true, transparency = true)
    ax_.title = "space = :relative"
elseif case_nr == 4
    image!(ax_, [-1.0, -0.8], [0.8, 1.0], img_, space = :clip, overdraw = true, transparency = true)
    ax_.title = "space = :clip (top. left)"
elseif case_nr == 5
    image!(ax_, [-0.1, 0.1], [-0.1, 0.1], img_, space = :clip, overdraw = true, transparency = true)
    ax_.title = "space = :clip (center, center)"
else
    error("Case not defined!")
end

screen_ = display(fig_)
  1. if you mean the axis’s padding, ax_.layoutobservables.computedbbox[] gives you the axis rectangle in pixel space.
  2. kind of, I had this at some point in MakieTeX but it’s not easy to do. I would make the SVG into a PNG and plot it that way, it’s easier all around.

Thanks for the replay! - I have the impression that in my case 80 pixel is a good estimation for the top
boarder, but this is not in agreement with the four numbers, that the variable computedbbox[] reports.

ah, you might also try suggestedbbox (which is the size of the layout cell) then.

It’s useful to note that the rectangle type which these bboxes are stored as is composed of origin and widths, not corners - use maximum(bbox) to get the top right corner.

I am lost, the result of suggestedbbox differs, first time the value is larger then in the 2nd statement:

using GLMakie
using FileIO: load
# --- params:
case_nr     = 3  # space options: #1 :data, #2 :pixel, #3 :relative, #4 :clip (top, left), #5 :clip (center, center) 
y_scale     = 1.0
fig_width   = 800
fig_hight   = 600
x_img_frac  = 0.1

# --- plot:
fig_    = Figure(resolution = (fig_width, fig_hight))
ax_     = Axis(fig_[1, 1])
# --- scatter:
x_vec   = collect(0:0.1:1) 
y_vec   = y_scale .* x_vec
scatter!(ax_, x_vec, y_vec)
# --- image:
icon_               = load(assetpath("icon_transparent.png"));
aspect_ratio_icon   = size(icon_)[1] / size(icon_)[2]
suggestedbbox_      = ax_.layoutobservables.suggestedbbox[]
y_top               = suggestedbbox_.widths[2] 
Δx_img              = x_img_frac * fig_width
x_range             = [0, Δx_img]
y_range             = [y_top - aspect_ratio_icon * Δx_img, y_top] 
@show y_top x_range y_range    
image!(ax_, x_range, y_range, icon_, space = :pixel, overdraw = true, transparency = true)
ax_.title           = "space = :pixel"

# --- repetition:
suggestedbbox_      = ax_.layoutobservables.suggestedbbox[]
computedbbox_       = ax_.layoutobservables.computedbbox[]
@show suggestedbbox_.widths[2] computedbbox_.widths[2];

# --- display:
screen_ = display(fig_)