Get help from the marimo community

Updated 3 months ago

Show matplotlib inline plot as svg instead of png

At a glance

The community member is experiencing blurry inline matplotlib plots on a 4k monitor, and they have tried changing the code to save the plots as SVG instead of PNG. However, the plots still show up as PNG. Another community member provides a solution that does not require updating the marimo library, by using plt.savefig() to save the plot as SVG and then displaying it using mo.Html(). The community members express appreciation for the solution.

The inline matplotlib plots are shown as png and look blurry on my 4k monitor. Increasing the plots dpi only scales it up. Is it possible to display them as a svg instead?

I already tried locally changing:
marimo/_output/mpl.py
Plain Text
def _internal_show(canvas: FigureCanvasBase) -> None:
    buf = io.BytesIO()
    buf.seek(0)
    canvas.figure.savefig(buf, format="png", bbox_inches="tight")
    plt.close(canvas.figure)
    mimetype: KnownMimeType = "image/png"
    plot_bytes = base64.b64encode(buf.getvalue())
    CellOp.broadcast_console_output(
        channel=CellChannel.MEDIA,
        mimetype=mimetype,
        data=build_data_url(mimetype=mimetype, data=plot_bytes),
        cell_id=None,
        status=None,
    )

to
Plain Text
def _internal_show(canvas: FigureCanvasBase) -> None:
    buf = io.BytesIO()
    buf.seek(0)
    canvas.figure.savefig(buf, format="svg", bbox_inches="tight")
    plt.close(canvas.figure)
    mimetype: KnownMimeType = "image/svg+xml"
    plot_bytes = base64.b64encode(buf.getvalue())
    CellOp.broadcast_console_output(
        channel=CellChannel.MEDIA,
        mimetype=mimetype,
        data=build_data_url(mimetype=mimetype, data=plot_bytes),
        cell_id=None,
        status=None,
    )

but it still shows up as a png.
M
H
2 comments
You can do this without needing to update marimo:
Plain Text
import marimo as mo
import matplotlib.pyplot as plt
import io

plt.plot([1, 2, 3], [4, 5, 6])
svg_buffer = io.StringIO()

plt.savefig(svg_buffer, format='svg')

svg_buffer.seek(0)
svg_data = svg_buffer.getvalue()
mo.Html(svg_data)


and of course, you can create a function to reuse this across multiple plots
Many thanks for putting this together!
Add a reply
Sign up and join the conversation on Discord