marimo-team / marimo

A reactive notebook for Python — run reproducible experiments, execute as a script, deploy as an app, and version with git.
https://marimo.io
Apache License 2.0
6.15k stars 200 forks source link

LaTeX displayed as raw text instead of math formulae in plotly #2060

Open metaboulie opened 3 weeks ago

metaboulie commented 3 weeks ago

Describe the bug

Plotly uses MathJax to render LaTeX mathematical formulas and notation.

But marimo doesn't use MathJax

This makes LaTeX displayed as raw text instead of math formulae in plotly

In Jupyter

Screenshot 2024-08-21 at 17 36 40

In marimo

Screenshot 2024-08-21 at 17 35 03

Thoughts:

Implement a logic to render LaTeX correctly in plotly formatter

Environment

{
  "marimo": "0.8.0",
  "OS": "Darwin",
  "OS Version": "22.3.0",
  "Processor": "arm",
  "Python Version": "3.12.4",
  "Binaries": {
    "Browser": "--",
    "Node": "v22.5.1"
  },
  "Requirements": {
    "click": "8.1.7",
    "importlib-resources": "missing",
    "jedi": "0.19.1",
    "markdown": "3.7",
    "pymdown-extensions": "10.9",
    "pygments": "2.18.0",
    "tomlkit": "0.13.2",
    "uvicorn": "0.30.6",
    "starlette": "0.38.2",
    "websockets": "12.0",
    "typing-extensions": "missing",
    "ruff": "0.6.1"
  }
}

Code to reproduce

# import marimo as mo
import plotly.express as px

px.line(
    x=[1, 2, 3, 4],
    y=[1, 4, 9, 16],
    title=r"$\alpha_{1c} = 352 \pm 11 \text{ km s}^{-1}$",
).update_layout(
    xaxis_title=r"$\sqrt{(n_\text{c}(t|{T_\text{early}}))}$",
    yaxis_title=r"$d, r \text{ (solar radius)}$",
)
mscolnick commented 3 weeks ago

Thanks for finding this! Do you know how jupyter is handling this / hooking in to the formatter?

rgouveiamendes commented 3 weeks ago

Hi! Did you try this? https://stackoverflow.com/questions/44333065/string-variable-as-latex-in-pyplot

metaboulie commented 3 weeks ago

@rgouveiamendes Thanks for pointing this out. Yeah, this works for matplotlib, but doesn't work for plotly.

metaboulie commented 3 weeks ago

Thanks for finding this! Do you know how jupyter is handling this / hooking in to the formatter?

Sorry, I have limited knowledge of Jupyter, have no idea

metaboulie commented 3 weeks ago

I think Jupyter actually does nothing for plotly, at least I can't find any relevant code in their repo.

The reason might be that, in Jupyter user needs to call fig.show() to display the figure, but in marimo user doesn't need to call fig.show(), just fig can do the job.

However, if calling fig.show() in marimo, the jumped figure renders LaTeX correctly.

So it's about fig.show() and fig I suppose

mscolnick commented 3 weeks ago

thanks for the investigation @metaboulie!

it might be our custom formatter for plotly (maybe missing config, or not converting to the plotly json correctly) marimo/_output/formatters/plotly_formatters.py

metaboulie commented 3 weeks ago

I tried to modify plotly_formatters as below:

html_content = build_stateless_plugin(
    component_name="marimo-plotly",
    args={"figure": json, "config": resolved_config},
)

# Include MathJax script for LaTeX rendering
mathjax_script = (
    '<script type="text/javascript" async '
    'src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML">'
    '</script>'
)

return Html(mathjax_script + html_content)

because pio.to_html(include_mathjax="cdn") appears to do the same thing, adding a script tag that references a MathJax CDN location to the output.

However, it doesn't work

https://plotly.com/python-api-reference/generated/plotly.io.to_html.html