Search code examples
pythonplotlymathjaxf-string

Unable to display a multi-line equation annotation in plotly (Python)


I'm attempting to create an annotation that consists of a fit equation and optimal parameters. I've used a string label that was also used to generate a similar output using matplotlib. The label has mathematical symbols/notation.

A minimum example:

import plotly.graph_objects as go

# make up some points
xpts = [0, 1, 2, 3, 4]
ypts = [0, 2, 4, 6, 8]

# the annotation to display
func_label = "".join(["$f(x) = mx + b$\n",
                      f"$m = 2.0$ \n",
                      f"$b = 0.0$\n",
                      f"$R^2 = 0.99$\n",
                      f"$RMSE = 0.01$",])

fig = go.Figure(
    data=[go.Scatter(x=xpts,
                     y=ypts,
                     mode='markers',
                     name="Data"
                     ),
          ],
    layout=go.Layout(title="Plot Title",
                     xaxis_title="X-axis",
                     yaxis_title="Y-axis")
)

# add the annotation
fig.add_annotation(x=0.25, y=6, text="<br>".join(func_label.split('\n')), showarrow=False)

fig.show(renderer="browser")

The resulting plot output only shows the first line of the annotation: Plot with only 1 line of the annotation!

It seems like the $ may be causing an issue, as when I remove them it prints all lines. Is there a way to do this while preserving the math rendering?


Solution

  • OK,

    I seem to have found a solution. In mathjax a newline is denoted by \\ (see here https://stackoverflow.com/a/32507429/13752965 for example). In order to use this with Python + plotly, I have to add an extra escape character \ (although I haven't quite worked out why).

    So using

    func_label = '$f(x) = mx + b \\\ m = 2.0 \\\ b = 0.0 \\\ R^2 = 0.99 \\\ RMSE = 0.01$'
    

    I'm able to get the multi-line annotation with equation formatting that I want. enter image description here

    I'm still tinkering with whether I can use the split and join approach in the question, but this is a reasonable alternative.