22

Is it possible to show a simple matplotlib plot (the kind usually generated by plt.show()) in plotly's Dash framework? Or just plotly-like graphs with plotly's Scatters and Data traces?

Specifically I guess I need a different component than Graph (see below) and a way to return the simple plot in the update_figure function.

Example:

import dash
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
import matplotlib.pyplot as plt

app = dash.Dash()

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),

    dcc.Slider(
        id='n_points',
        min=10,
        max=100,
        step=1,
        value=50,
    ),

    dcc.Graph(id='example') # or something other than Graph?...
])

@app.callback(
    dash.dependencies.Output('example', 'figure'),
    [dash.dependencies.Input('n_points', 'value')]
)

def update_figure(n_points):
    #create some matplotlib graph
    x = np.random.rand(n_points)
    y = np.random.rand(n_points)
    plt.scatter(x, y)
    # plt.show()
    return None # return what, I don't know exactly, `plt`?

if __name__ == '__main__':
    app.run_server(debug=True)
2
  • 1
    Idea: handle the matplotlib plot as a normal image and set it as a background image for a plotly graph Commented Jun 24, 2018 at 19:23
  • The answer to your question is given in this question - stackoverflow.com/questions/65960506/… Commented Jun 21, 2022 at 16:05

3 Answers 3

18

Refer to https://plot.ly/matplotlib/modifying-a-matplotlib-figure/ . There is a mpl_to_plotly function in plotly.tools library that will return a plotly figure(which can then be returned to Graph's figure attribute) from matplotlib figure.

Edit: Just noticed you asked this a while back. Maybe the above is a new feature but its the cleanest way.

Sign up to request clarification or add additional context in comments.

2 Comments

The above link is hitting a 404. Any alternatives?
This feature is considered deprecated see github.com/plotly/plotly.py/issues/1568
18

If you don't want an interactive plot, you can return a static one (found from this help)


import io
import base64

...
    
app.layout = html.Div(children=[
    ...,

    html.Img(id='example') # img element
])

@app.callback(
    dash.dependencies.Output('example', 'src'), # src attribute
    [dash.dependencies.Input('n_points', 'value')]
)
def update_figure(n_points):
    #create some matplotlib graph
    x = np.random.rand(n_points)
    y = np.random.rand(n_points)
    buf = io.BytesIO() # in-memory files
    plt.scatter(x, y)
    plt.savefig(buf, format = "png")
    plt.close()
    data = base64.b64encode(buf.getbuffer()).decode("utf8") # encode to html elements
    buf.close()
    return "data:image/png;base64,{}".format(data)

2 Comments

When I took this approach, I was perpetually able to reaccess images. Thus, the RAM built during deployment until crashing. Can anyone advise?
sr i forgot to close the stream : buf.close() just before return
2
UserWarning: Starting a Matplotlib GUI outside of the main thread will likely fail

in my case it works, despite the warning message 👍👍

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.