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

Add SymPy equation rendering support such that the ouput is on parity with Jupyter's rendering when using SymPy. #1412

Closed
kamyuen opened this issue May 19, 2024 · 4 comments · Fixed by #2261
Labels
good first issue Good for newcomers help wanted Extra attention is needed

Comments

@kamyuen
Copy link

kamyuen commented May 19, 2024

Description

There is currently no way to render equations properly when using SymPy. In Jupyter notebook one usually just calls init_printing() at the beginning of a notebook to allow all subsequent output to be rendered in mathematical notation.
Importing SymPy in and calling init_printing() has absolutely no effect and equations are simple output as text.
To see the issue just follow the SymPy documentation for setting up this feature https://docs.sympy.org/latest/tutorials/intro-tutorial/printing.html

Suggested solution

Since SymPy has multiple fallbacks on how to render the output, it may be a case of initially capturing the resulting MathJax and rendering using Marimo's md function, just a guess.

Alternative

No response

Additional context

No response

@mscolnick
Copy link
Contributor

In the meantime, you can do this:

from sympy import latex
import marimo as mo

def print_sympy(obj):
    return mo.md(f"""
    \[
    {latex(obj)}
    \]
    """)

Playground: https://marimo.app/l/n2kkic

@mscolnick mscolnick added good first issue Good for newcomers help wanted Extra attention is needed labels May 19, 2024
@agostof
Copy link
Contributor

agostof commented Jul 23, 2024

Adding on to the solution by @mscolnick, you can try adding the _mime_ method to the classes you want to render.

...
from sympy import Symbol as SymbolSympy
from sympy import Integral as IntegralSympy

class Symbol(SymbolSympy):
    def _mime_(self) -> tuple[str, str]:
         return ("text/html", print_sympy(self).text)

class Integral(IntegralSympy):
    def _mime_(self) -> tuple[str, str]:
        return ("text/html", print_sympy(self).text)
...
x, y, z = symbols('x y z', cls=Symbol)
...

Playground: https://marimo.app/l/t1huwf

Updating to add that if you would rather like to use monkey-patching for adding the rendering method, you could change print_sympy, or create a new e.g. sympy_html, to return the mime type and the content (playground https://marimo.app/l/nhxml3):

def patch_sympy(*objs):
    """adds the _mime_() method to the sympy objects
    e.g.
    Symbol._mime_ = sympy_html
    example:
    patch_sympy(Symbol, Integral)
    """
    for obj in objs:
        # the lambda below is our sympy_html 
        obj._mime_ = lambda obj: ("text/html", mo.md(f"""\[{latex(obj)}\]""").text)
...
from sympy import Symbol, Integral
patch_sympy(Symbol, Integral)
...
x, y, z = symbols('x y z')

@mscolnick
Copy link
Contributor

@agostof - your patch is quite nice

if you or @kamyuen or anyone else wants to make a contribution to the repo - you can add this to marimo/_output/formatters

@agostof
Copy link
Contributor

agostof commented Sep 8, 2024

@mscolnick Thanks!

It turns out that patching sympy.core.basic.Printable works nicely.
I am adding a formatter and will submit a PR.

akshayka pushed a commit that referenced this issue Sep 8, 2024
* add preliminar sympy to md rendering

* cleanup sympy formatter

* cleanup sympy formatter

* sympy dependency

* add tests, cleanup

* add sympy optional dependency, fix typos
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants