Skip to content

Instantly share code, notes, and snippets.

@illume
Last active September 21, 2022 02:14
Show Gist options
  • Save illume/1f19a2cf9f26425b1761b63d9506331f to your computer and use it in GitHub Desktop.
Save illume/1f19a2cf9f26425b1761b63d9506331f to your computer and use it in GitHub Desktop.
Shows how to use flask and matplotlib together.
""" Shows how to use flask and matplotlib together.
Shows SVG, and png.
The SVG is easier to style with CSS, and hook JS events to in browser.
python3 -m venv venv
. ./venv/bin/activate
pip install flask matplotlib
python flask_matplotlib.py
"""
import io
import random
from flask import Flask, Response, request
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.backends.backend_svg import FigureCanvasSVG
from matplotlib.figure import Figure
app = Flask(__name__)
@app.route("/")
def index():
""" Returns html with the img tag for your plot.
"""
num_x_points = int(request.args.get("num_x_points", 50))
# in a real app you probably want to use a flask template.
return f"""
<h1>Flask and matplotlib</h1>
<h2>Random data with num_x_points={num_x_points}</h2>
<form method=get action="/">
<input name="num_x_points" type=number value="{num_x_points}" />
<input type=submit value="update graph">
</form>
<h3>Plot as a png</h3>
<img src="/matplot-as-image-{num_x_points}.png"
alt="random points as png"
height="200"
>
<h3>Plot as a SVG</h3>
<img src="/matplot-as-image-{num_x_points}.svg"
alt="random points as svg"
height="200"
>
"""
# from flask import render_template
# return render_template("yourtemplate.html", num_x_points=num_x_points)
@app.route("/matplot-as-image-<int:num_x_points>.png")
def plot_png(num_x_points=50):
""" renders the plot on the fly.
"""
fig = Figure()
axis = fig.add_subplot(1, 1, 1)
x_points = range(num_x_points)
axis.plot(x_points, [random.randint(1, 30) for x in x_points])
output = io.BytesIO()
FigureCanvasAgg(fig).print_png(output)
return Response(output.getvalue(), mimetype="image/png")
@app.route("/matplot-as-image-<int:num_x_points>.svg")
def plot_svg(num_x_points=50):
""" renders the plot on the fly.
"""
fig = Figure()
axis = fig.add_subplot(1, 1, 1)
x_points = range(num_x_points)
axis.plot(x_points, [random.randint(1, 30) for x in x_points])
output = io.BytesIO()
FigureCanvasSVG(fig).print_svg(output)
return Response(output.getvalue(), mimetype="image/svg+xml")
if __name__ == "__main__":
import webbrowser
webbrowser.open("http://127.0.0.1:5000/")
app.run(debug=True)
@Loncor
Copy link

Loncor commented Sep 21, 2022

Thanks, using SVG is a great idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment