Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exporting subplot with legend to svg #4500

Open
Zetison opened this issue Oct 19, 2024 · 0 comments
Open

Exporting subplot with legend to svg #4500

Zetison opened this issue Oct 19, 2024 · 0 comments
Labels
enhancement Feature requests and enhancements

Comments

@Zetison
Copy link

Zetison commented Oct 19, 2024

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 here

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
Image
which should have been
Image

@Zetison Zetison added the enhancement Feature requests and enhancements label Oct 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Feature requests and enhancements
Projects
None yet
Development

No branches or pull requests

1 participant