but it seems that using GLMakie and CarioMakie at the same time causes issues, my plots don’t show and a file display.png opens. Is there a way to have an application based on GLMakie create svg files?
Hm the quality deteriorating is probably because the screen can only have one px_per_unit at the time, although you set 2 so that should usually be sufficient unless you have a very unusual screen setup. Maybe there’s a bug there, though.
With CairoMakie it would still only make sense to save a png with this technique as colorbuffer makes a bitmap. If you had said you wanted an svg I wouldn’t have suggested that solution. I’ll try and see if there’s a similar workaround that makes sense for svg.
using GLMakie
f = Figure()
for i in 1:3, j in 1:3
Axis(f[i, j], title="$i $j")
end
Makie.save("test.png", colorbuffer(content(f[2, 2])))
Really weird, we even have a reference image test for this, which is totally borked…
Not sure how this regression got merged without the tests failing - I’m guessing it must have been in a PR where we updated all reference images, since the visual diff must be big enough even for our old thresholds to go off.
Just to me clear I can generate the png and the image file looks ok on the screen but it’s very poor quality when I print it. I saw a reference suggesting that for printing I should use svg but I’m not wedded to any particular format.
This is an example of one of the Axis that I want to print on it’s own. The others are more conventional charts.
Here is a variant that saves svg. You can’t crop an svg by throwing away pixels, so I do it by editing the width, height and viewBox attributes accordingly.
using CairoMakie
f = Figure()
for i in 1:3, j in 1:3
Axis(f[i, j], title = "$i $j")
end
function outer_bbox(ax; padding)
sbb = ax.layoutobservables.suggestedbbox[]
prot = ax.layoutobservables.protrusions[]
o = sbb.origin .- (prot.left, prot.bottom) .- padding
w = sbb.widths .+ (prot.left + prot.right, prot.bottom + prot.top) .+ 2 * padding
Rect2f(o, w)
end
function save_cropped_svg(file, scene, bbox)
sw, sh = scene.viewport[].widths
ox, oy = bbox.origin
w, h = bbox.widths
svg = repr(MIME"image/svg+xml"(), scene)
svg = replace(
svg,
r"viewBox=\".*?\"" => "viewBox=\"$ox $(sh - oy - h) $w $h\"",
r"width=\".*?\"" => "width=\"$w\"",
r"height=\".*?\"" => "height=\"$h\"",
count = 3,
)
open(file, "w") do io
write(io, svg)
end
return
end
ax = current_axis()
save_cropped_svg("test.svg", ax.blockscene, outer_bbox(ax; padding = 10))
GLMakie doesn’t do svg, so you have to use CairoMakie. And repr doesn’t have a way to specify a different backend to use. So one has to take a slight detour through save:
using CairoMakie
using GLMakie
GLMakie.activate!()
f = Figure()
for i in 1:3, j in 1:3
Axis(f[i, j], title = "$i $j")
end
display(f)
function outer_bbox(ax; padding)
sbb = ax.layoutobservables.suggestedbbox[]
prot = ax.layoutobservables.protrusions[]
o = sbb.origin .- (prot.left, prot.bottom) .- padding
w = sbb.widths .+ (prot.left + prot.right, prot.bottom + prot.top) .+ 2 * padding
Rect2f(o, w)
end
function save_cropped_svg(file, scene, bbox)
sw, sh = scene.viewport[].widths
ox, oy = bbox.origin
w, h = bbox.widths
svg = mktempdir() do dir
save(joinpath(dir, "output.svg"), scene; backend = CairoMakie)
read(joinpath(dir, "output.svg"), String)
end
svg = replace(
svg,
r"viewBox=\".*?\"" => "viewBox=\"$ox $(sh - oy - h) $w $h\"",
r"width=\".*?\"" => "width=\"$w\"",
r"height=\".*?\"" => "height=\"$h\"",
count = 3,
)
open(file, "w") do io
write(io, svg)
end
return
end
ax = current_axis()
save_cropped_svg("test.svg", ax.blockscene, outer_bbox(ax; padding = 10))