Correct way to save Makie plot to IOBuffer

I am generating a web page including a data URL for a Makie plot. I would like to avoid saving the plot to a file if possible. I figured this out but I would like to know if there is a better way.

using Makie, CairoMakie, Base64

# test data 
t=0:0.1:2π
y=sin.(t)

# make a plot
CairoMakie.activate!(type="png")
fig = Figure()
ax = Axis(fig[1,1], title="test", ylabel="value", xlabel="time")
xlims!(ax, 0, t[end])
ylims!(ax, -1.1, 1.1)
lns = lines!(ax, t, y)
fig[1,2] = Legend(fig, [lns], ["lines"])

# save to IOBuffer
io = IOBuffer()
Makie.backend_show(Makie.current_backend[], io, MIME"image/png"(), fig.scene)
# extract bytes and create data uri
img_data_uri = "data:image/png;base64,$(base64encode(take!(io)))";

Specifically, backend_show looks like something I shouldn’t be messing with.

2 Likes

show(io, MIME"image/png"(), fig) should work I think

Huh, that works great in the REPL but fails when called in the full code with

MethodError: no method matching show(::IOBuffer, ::Type{MIME{Symbol("image/png")}}, ::Makie.Figure)

Adding a call to methods immediately before the call to show only makes me more confused, the method is right there!

methods(show, [IO, MIME"image/png", Any]) = # 2 methods for generic function "show":
[1] show(io::IO, m::MIME, figlike::Union{Makie.Figure, Makie.FigureAxisPlot, Makie.Scene}) in Makie at /home/user/.julia/packages/Makie/Ppzqh/src/display.jl:114
[2] show(io::IO, ::MIME{Symbol("image/png")}, surface::Cairo.CairoSurface) in Cairo at /home/user/.julia/packages/Cairo/smWIA/src/Cairo.jl:441

I’ll continue to investigate.

Take care to do MIME"..."() with the parentheses, the dispatch is not defined for the Type so you need to instantiate the MIME object

That was it, thank you very much!