Creative report designed only with Matplotlib, without office software
In this article, our aim is to create an intuitive report with Matplotlib. Attention: during the work, none of the office software will be demanded. What we only use, is Python.
A series of meaningful data plots works usually as ingredients in a report. As spoken, a good chart is better than a speech. If we have obtained these precious ingredients in advance, the last step is how to place them in a proper way.
Of course, we can use Microsoft Word, Powerpoint, etc. But not necessary. Here I present my recipe with Matplotlib.
1. Short introduction of data and charts
Based on the excel file, we have gotten some representative charts (bar plot and donut plot). If you don't know how to handle this, please check my previous stories. The links are given, please check them one after one if you feel the tasks not easy or new for you.
- Introduction to the factory — the data contributor
- write data into a data frame with Pandas and plot them
- go deeper with data and explore potential information
- how to draw a donut plot
Therewith, we have gathered some charts consisting of one bar plot and nine donut plots.
2. Design layout and basic setting with Matplotlib
import matplotlib.pyplot as plt
# set font
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = 'STIXGeneral'# set A4 paper
fig, ax = plt.subplots(figsize=(8.5, 11)) # Decorative Lines
ax.axvline(x=.01, ymin=0, ymax=1, color='#44A0AD', alpha=0.3, linewidth=120)
plt.axvline(x=.99, color='#5244AD', alpha=0.3, linewidth=120)
plt.axhline(y=.95, xmin=0.14, xmax=0.86, color='#446BAD', linewidth=5,alpha=0.3)
# set background color
ax.set_facecolor('white')
# remove axes
plt.axis('off')
If you enter “plt.show()” now, the figure looks like below
Next, we should add content (title, charts, etc.) to the blank paper.
Header = 'Annual Report of XXX Factory'
Contact = 'Reporter:____________ \n\nDate:________________ \n\nPlace:_______________ '
page = 'Page 1'
# add text
plt.annotate(Header, (.22,.98), weight='regular', fontsize=20, alpha=.6 )
plt.annotate(Contact, (.34,.18), weight='bold', fontsize=14,alpha=.6)
plt.annotate(page, (.48,.02), weight='medium', fontsize=10)
#add a vital bar chart
from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
import matplotlib.image as mpimg
first_plot = mpimg.imread('barplot3.png')
imagebox1 = OffsetImage(first_plot, zoom=0.4)
a = AnnotationBbox(imagebox1, (0.48, 0.68),frameon=False)
ax.add_artist(a)
Now, the first page of the report is finished.
Similarly, we continue the style on the second page, which should be filled with detailed donut plots for each year.
To make the content clear, we have to arrange the plots neatly.
fig, ax = plt.subplots(figsize=(8.5, 11))
# Decorative Lines
ax.axvline(x=.01, ymin=0, ymax=1, color='#44A0AD', alpha=0.3, linewidth=120)
plt.axhline(y=.95, xmin=0.14, xmax=0.99, color='#446BAD', linewidth=5,alpha=0.3)
# set background color
ax.set_facecolor('white')
# remove axes
plt.axis('off')
Header = 'Annual Report of XXX Factory'
page2= 'Page 2'
# add text
plt.annotate(Header, (.22,.98), weight='regular', fontsize=20, alpha=.6 )
plt.annotate(page2, (.48,.02), weight='medium', fontsize=10)
first_plot = mpimg.imread('donutplot1.png')
imagebox1 = OffsetImage(first_plot, zoom=0.25)
a1 = AnnotationBbox(imagebox1, (0.29, 0.80),frameon=False)
ax.add_artist(a1)
second_plot = mpimg.imread('donutplot2.png')
imagebox2 = OffsetImage(second_plot, zoom=0.25)
b1 = AnnotationBbox(imagebox2, (0.58, 0.80),frameon=False)
ax.add_artist(b1)
third_plot = mpimg.imread('donutplot3.png')
imagebox3 = OffsetImage(third_plot, zoom=0.1875)
c1 = AnnotationBbox(imagebox3, (0.87, 0.80),frameon=False)
ax.add_artist(c1)
fourth_plot = mpimg.imread('donutplot4.png')
imagebox4 = OffsetImage(fourth_plot, zoom=0.25)
a2 = AnnotationBbox(imagebox4, (0.29, 0.50),frameon=False)
ax.add_artist(a2)
fifth_plot = mpimg.imread('donutplot5.png')
imagebox5 = OffsetImage(fifth_plot, zoom=0.25)
b2 = AnnotationBbox(imagebox5, (0.58, 0.50),frameon=False)
ax.add_artist(b2)
sixth_plot = mpimg.imread('donutplot6.png')
imagebox6 = OffsetImage(sixth_plot, zoom=0.1875)
c2 = AnnotationBbox(imagebox6, (0.87, 0.50),frameon=False)
ax.add_artist(c2)seventh_plot = mpimg.imread('donutplot7.png')
imagebox7 = OffsetImage(seventh_plot, zoom=0.25)
a3 = AnnotationBbox(imagebox7, (0.29, 0.20),frameon=False)
ax.add_artist(a3)
eighth_plot = mpimg.imread('donutplot8.png')
imagebox8 = OffsetImage(eighth_plot, zoom=0.25)
b3 = AnnotationBbox(imagebox8, (0.58, 0.20),frameon=False)
ax.add_artist(b3)
ninth_plot = mpimg.imread('donutplot9.png')
imagebox9 = OffsetImage(ninth_plot, zoom=0.1875)
c3 = AnnotationBbox(imagebox9, (0.87, 0.20),frameon=False)
ax.add_artist(c3)
plt.savefig('report_2.png', dpi=300, bbox_inches='tight')
Therewith, the second page is well decorated with nine donut plots.
Additionally, what we can improve is to draw a conclusion of these plots, which I didn't have time to write within the report. For example, due to the covid-19 pandemic, the total sales in 2020 are dramatically falling.
3. Summary
In this short article, the approach to generate a report is explained in detail, which doesn’t need Word or Powerpoint. Our report created by Matplotlib presents relevant information directly obtained by data processing and analysis, which means if you are used to processing data in Python, there is no need to switch apps or platforms.
The code is submitted in Github, which you can download and review.