Plotting graph using python and dispaying it using HTML

My suggestion would be to use the plotly.offline module, which creates an offline version of a plot for you. The plotly API on their website is horrendous (we wouldn't actually want to know what arguments each function takes, would we??), so much better to turn to the source code on Github.

If you have a look at the plotly source code, you can see that the offline.plot function takes a kwarg for output_type, which is either 'file' or 'div':

https://github.com/plotly/plotly.py/blob/master/plotly/offline/offline.py

So you could do:

from plotly.offline import plot
from plotly.graph_objs import Scatter

my_plot_div = plot([Scatter(x=[1, 2, 3], y=[3, 1, 6])], output_type='div')

This will give you the code (wrapped in <div> tags) to insert straight into your HTML. Maybe not the most efficient solution (as I'm pretty sure it embeds the relevant d3 code as well, which could just be cached for repeated requests), but it is self contained.

To insert your div into your html code using Flask, there are a few things you have to do.

In your html template file for your results page, create a placeholder for your plot code. Flask uses the Jinja template engine, so this would look like:

<body>
....some html...

{{ div_placeholder }}

...more html...
</body>

In your Flask views.py file, you need to render the template with the plot code inserted into the div_placeholder variable:

from plotly.offline import plot
from plotly.graph_objs import Scatter
from flask import Markup
...other imports....

@app.route('/results', methods=['GET', 'POST'])
def results():
    error = None
    if request.method == 'POST':
        my_plot_div = plot([Scatter(x=[1, 2, 3], y=[3, 1, 6])], output_type='div')
        return render_template('results.html',
                               div_placeholder=Markup(my_plot_div)
                              )
    # If user tries to get to page directly, redirect to submission page
    elif request.method == "GET":
        return redirect(url_for('submission', error=error))

Obviously YMMV, but that should illustrate the basic principle. Note that you will probably be getting a user request using POST data that you will need to process to create the plotly graph.


You can use the .to_html() method:

https://plot.ly/python-api-reference/generated/plotly.graph_objects.Figure.html#plotly.graph_objects.Figure.to_html

import plotly.express as px

fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])

div = fig.to_html(full_html=False)  # Get the <div> to send to your frontend and embed in an html page