Makie.jl
Makie.jl copied to clipboard
Exporting subplot with legend to svg
Feature description
It would be really nice if one could export a subplot to a svg file (including the legend) from e.g. the following MWE
using CairoMakie
CairoMakie.activate!()
fig = Figure()
gridlayout = fig[1:2,1:2] = GridLayout()
ax1 = Axis(gridlayout[1,1])
ax2 = Axis(gridlayout[2,1])
ax3 = Axis(gridlayout[1:2,2])
x = range(0,2π,100)
lines!(ax1, x, sin.(x), label = "sin")
lines!(ax2, x, cos.(x), label = "cos")
lines!(ax3, x, exp.(x), label = "exp")
ylims!(ax1, -1, 1)
ylims!(ax2, -1, 1)
legend = axislegend(ax2)
since save("cos.svg", ax2.blockscene)
do not crop the image and miss the legend, I tried to manually do this as suggested her
function extract_svg(svg_string)
# Extracts the raw SVG content from the representation
svg_start = findfirst("<svg", svg_string)[1]
start_idx = findfirst(">", svg_string[svg_start:end])[end]+svg_start
end_idx = findfirst("</svg>", svg_string)[1]-1
return svg_string[start_idx:end_idx], svg_string[1:start_idx-1]
end
function merge_svg_strings(svg1,svg2)
svg_str1, header = extract_svg(svg1)
svg_str2, _ = extract_svg(svg2)
return header * svg_str1 * svg_str2 * "</svg>\n"
end
bb = ax2.layoutobservables.suggestedbbox[]
protrusions = ax2.layoutobservables.reporteddimensions[].outer
offset = ax2.spinewidth[]/2
axis_bb = Rect2f(
bb.origin .- (protrusions.left, protrusions.bottom) .- offset,
bb.widths .+ (protrusions.left + protrusions.right, protrusions.bottom + protrusions.top) .+ 2*offset
)
pad = 0
ws = axis_bb.widths
o = axis_bb.origin
width = "$(ws[1] + 2 * pad)pt"
height = "$(ws[2] + 2 * pad)pt"
viewBox = "$(o[1] - pad) $(o[2] + ws[2] - pad) $(ws[1] + 2 * pad) $(ws[2] + 2 * pad)"
svg_string_ax = repr(MIME"image/svg+xml"(), ax2.blockscene)
svg_string_legend = repr(MIME"image/svg+xml"(), legend.blockscene)
svg_string = merge_svg_strings(svg_string_ax, svg_string_legend)
svg_string = replace(svg_string, r"""(?<=width=")[^"]*(?=")""" => width, count = 1)
svg_string = replace(svg_string, r"""(?<=height=")[^"]*(?=")""" => height, count = 1)
svg_string = replace(svg_string, r"""(?<=viewBox=")[^"]*(?=")""" => viewBox, count = 1)
open("cos.svg", "w") do io
print(io, svg_string)
end
For plot types, please add an image of how it should look like
With the result
which should have been