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.