Passing a matplotlib figure to HTML (flask)
You have to separate the HTML and the image into two different routes.
Your /images/<cropzonekey>
route will just serve the page, and in the HTML content of that page there will be a reference to the second route, the one that serves the image.
The image is served in its own route from a memory file that you generate with savefig()
.
I obviously didn't test this, but I believe the following example will work as is or will get you pretty close to a working solution:
@app.route('/images/<cropzonekey>')
def images(cropzonekey):
return render_template("images.html", title=cropzonekey)
@app.route('/fig/<cropzonekey>')
def fig(cropzonekey):
fig = draw_polygons(cropzonekey)
img = StringIO()
fig.savefig(img)
img.seek(0)
return send_file(img, mimetype='image/png')
Your images.html
template the becomes:
<html>
<head>
<title>{{ title }} - image</title>
</head>
<body>
<img src="{{ url_for('fig', cropzonekey = title) }}" alt="Image Placeholder" height="100">
</body>
</html>
Python - Flask - MatPlotLib
Please refer to this link to learn how to do this using:
import io
import base64
https://gitlab.com/snippets/1924163
Python: How to show matplotlib in flask
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">
passing a plot from matpotlib to a flask view
What Python version are you using? On Python 3.x base64.b64encode()
returns bytes
object and that's why it probably fails. You need to decode it into a string before passing it to Flask. Also, you should URL-escape your base64-encoded string since you're printing it inside of your HTML, something like:
import urllib.parse
# ...
img = io.BytesIO() # create the buffer
plt.savefig(img, format='png') # save figure to the buffer
img.seek(0) # rewind your buffer
plot_data = urllib.parse.quote(base64.b64encode(img.read()).decode()) # base64 encode & URL-escape
return render_template('plot.html', plot_url=plot_data)
Passing matplotlib subplots generated from a pandas dataframe to HTML for display using flask
I think there are two main issues here, see my comments in the code:
travel_df_new.unstack(level=0).plot(kind='bar', subplots=True, legend=False)
# This creates a new, empty Figure. Saving this should just be an empty plot.
fig=plt.figure()
# Now you want to save the empty Figure into your img
# This won't work, because savefig works with BytesIO
canvas = FigureCanvas(fig)
img = StringIO()
fig.savefig(img)
img.seek(0)
Try something like this instead:
travel_df_new.unstack(level=0).plot(kind='bar', subplots=True, legend=False)
buff = BytesIO()
plt.savefig(buff, format='png', dpi=180)
buff.seek(0)
Note this uses io.BytesIO
instead of io. StringIO
, calls plt.savefig
and not fig.savefig
, and is a little more verbose in the savefig
arguments.
I'm also not quite sure why you call plt.ion()
in your route, you won't need interactive mode when run like this.
Related Topics
Fast Way of Counting Non-Zero Bits in Positive Integer
Django: Deploying an Application on Heroku with SQLite3 as the Database
How to Create Nested Dict in Python
How to Select and Extract Texts Between Two Elements
Ruby Hash Equivalent to Python Dict Setdefault
How to Install Python Windows Packages into Virtualenvs
How to Do Multiple Substitutions Using Regex
Differencebetween _Init_ and _Call_
Convert Column to Date Format (Pandas Dataframe)
Displaying Subprocess Output to Stdout and Redirecting It
Sqlalchemy: Print the Actual Query
Add Custom CSS Styling to Model Form Django
Comparison of R, Statmodels, Sklearn for a Classification Task with Logistic Regression
Aes Python Encryption and Ruby Encryption - Different Behaviour