Python: How to show matplotlib in flask

Question:

I’m very new to Flask and Matplotlib. I’d like to be able to show a simple chart I generated in some html, but I’m having a very hard time figuring out how. Here is my Python code:

from flask import Flask, render_template
import numpy as np
import pandas
import matplotlib.pyplot as plt

app = Flask(__name__)
variables = pandas.read_csv('C:\path\to\variable.csv')
price =variables['price']


@app.route('/test')
def chartTest():
    lnprice=np.log(price)
    plt.plot(lnprice)
    return render_template('untitled1.html', name = plt.show())

if __name__ == '__main__':
   app.run(debug = True)

And here is my HTML:

<!doctype html>
<html>
   <body>

      <h1>Price Chart</h1>

      <p>{{ name }}</p>

      <img src={{ name }} alt="Chart" height="42" width="42">

   </body>
</html>
Asked By: SVill

||

Answers:

As @d parolin pointed out, the figure generated by matplotlib will need to be saved before being rendered by the HTML. In order to serve images in flask by HTML, you will need to store the image in your flask file directory:

static/
  images/
    plot.png --> store plots here
templates/

Therefore, in your application, use plt.savefig:

@app.route('/test')
def chartTest():
  lnprice=np.log(price)
  plt.plot(lnprice)   
  plt.savefig('/static/images/new_plot.png')
  return render_template('untitled1.html', name = 'new_plot', url ='/static/images/new_plot.png')

Then in untitled1.html:

  <p>{{ name }}</p>

  <img src={{ url}} alt="Chart" height="42" width="42">
Answered By: Ajax1234

You can generate the image on-the-fly in Flask URL route handler:

import io
import random
from flask import Response
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

@app.route('/plot.png')
def plot_png():
    fig = create_figure()
    output = io.BytesIO()
    FigureCanvas(fig).print_png(output)
    return Response(output.getvalue(), mimetype='image/png')

def create_figure():
    fig = Figure()
    axis = fig.add_subplot(1, 1, 1)
    xs = range(100)
    ys = [random.randint(1, 50) for x in xs]
    axis.plot(xs, ys)
    return fig

Then you need to include the image in your HTML template:

<img src="/plot.png" alt="my plot">
Answered By: Messa
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.