Fill a bounding box of a text in Makie

I’d like to add background color to a text object in a Makie plot – fill the bounding box of the text with some color.
If I understood it correctly, text does not have a size property, so bb here has size zero:

t = text!(scene, "text")
bb = boundingbox(t)

Is there some way to accomplish this?

Background: I’m plotting circles with specific radii, and I want to add a text label on the edge of each circle with its radius. The problem is that the edge of the circle is visible through the text, and I’d like the text to obscure the edge of the circle behind it, all to improve readability. Kind of like:
screenshot_2021-05-06_12:46:30

I now realize that this might not be simple/easy as attested by

and

This works:

using GLMakie
using GLMakie: Quaternionf0

positions = rand(Point2f0, 5)
fig, ax, textplot = text([(string(Tuple(round.(x, digits=2))), x) for x in positions], align=(:center, :center))

layouts = textplot._glyphlayout[]
strings = textplot[1][]
bbs = map(strings, layouts) do str, l 
    GLMakie.AbstractPlotting.data_text_boundingbox(str[1], l, Quaternionf0(0,0,0,1), Point3f0(0))
end
scatter!(ax, positions, markersize=widths.(bbs), marker=Rect)
reverse!(ax.scene.plots)
display(fig)

1 Like

Hell, this works pretty well:

for radius in (30, 60, 90, 120, 150)
  lines!(ax, Circle(zero(Point2f0), radius))
  scatter!(ax, Point2f0(0, radius), color = :white, markersize = round(Int, length(string(radius))*45/3)*1px, strokewidth = 0)
  text!(ax, string(radius), position = Point2f0(0, radius), align = (:center, :center))
end

mwe

1 Like

reverses the order of everything, so it messes things up a bit. I’ll try and see how I can reverse the order of only the text and scatter point.

This did it:

ax.scene.plots[end-1:end] .= ax.scene.plots[[end, end-1]]

2 Likes

In theory, one could also calculate the bbs before… But this is simpler :wink: We should just add a good recipe for text with backround going forward!

3 Likes

For the sake of reactivity, it would be better to have the bbs depend on the text object so that if the user changes it too will change. Also, it might be simpler to wrap the text in a container where the first element is that scatter object, thus removing the need to reverse the order after the fact.

Thanks for the help Simon!

@sdanisch just discovered this doesn’t work with CairoMakie (regardless if the output is png or pdf). Which is really strange…
I’ll try with my scatter hack… OK, my scatter hack worked…

I suspect Rect as a marker in CairoMakie doesn’t work…