Unfortunately, the defaults for matplotlib are terrible. Ugh!
Enter prettyplotlib -- this library applies some of the work of several key influencers in the visual design space (Tufte, Brewer) to matplotlib. We eliminate chartjunk, add some better fonts, remove some redundant axes, add some better colours, and get the following:
Much better! Now how do we go about serving this type of a plot via Flask? We will have to have two views, one that creates the image, and another one that serves the template that will contain the image. Our template, contained at templates/image.html should be as follows:
<html> <head> <title>{{ title }} - image</title> </head> <body> <img src="/fig/" alt="Image Placeholder"> </body> </html>
and our main application file, titled run.py, should contain the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | from io import BytesIO from flask import Flask, render_template, send_file, make_response from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas import numpy as np import prettyplotlib as ppl import matplotlib.pyplot as plt app = Flask(__name__) @app.route('/fig/') def fig(): fig, ax = plt.subplots(1) ppl.bar(ax, np.arange(10), np.abs(np.random.randn(10))) canvas = FigureCanvas(fig) img = BytesIO() fig.savefig(img) img.seek(0) return send_file(img, mimetype='image/png') @app.route('/image/') def images(): return render_template("image.html") if __name__ == '__main__': app.run(debug=True) |
The key is line 14 -- rather than calling matplotlib's plt.bar, we call prettyplotlib's plt.bar . Just like that, our output is much more visually appealing and easier to read!
For further reading, check out the following Stack Overflow thread about serving matplotlib files via Flask, this Gist about plotting a PNG using matplotlib (uses Python 2 -- you'll have to adapt it to use the io library if you'd like to try something similar in Python 3) and the official prettyplotlib documentation.


Unfortunately, prettyplotlib is dead at this point. The author recommends using seaborn instead. Simply importing seaborn `import seaborn as sns` will automatically change the styling.
ReplyDeleteAlternatively, the newer matplotlib provides styling with `matplotlib.style.use`. There is not currently an exact duplicate of prettyplotlib's style that I can see, but some are similar. You could also create your own style, post it in a gist and use the URL.
The article presents a practical use case for serving Matplotlib-generated images through a Flask application when lightweight, non-dynamic visualization generation is sufficient. The discussion also highlights an important design consideration: simply generating a chart is not enough when the default visualization contains unnecessary elements that reduce clarity.
ReplyDeleteThe introduction of prettyplotlib is interesting because the article connects visualization design principles with the technical process of generating charts in Python. Applying ideas such as reducing chartjunk, improving typography, simplifying redundant axes, and refining colors provides useful context for learners exploring a Matplotlib Course.
The combination of Flask for serving generated images and Matplotlib for visualization also demonstrates how visualization can be integrated into a Python web application. This makes the example relevant to a Flask Course only if a Flask-specific course URL is available; otherwise, the supplied Flask tag should not be substituted with an unrelated framework URL.
ReplyDelete