Introduction to matplotlib library#
Unless specified differently, these slides are copyright CINECA 2019 and are released under the Attribution–NonCommercial–NoDerivs (CC BY-NC-ND) Creative Commons license, version 3.0.
Uses not allowed by the above license need explicit, written permission from the copyright owner. For more information see:
http://creativecommons.org/licenses/by-nc-nd/3.0/
Slides were authored by Susana Bueno.
## Matplotlib, a python 2D plotting library
from IPython.display import IFrame
IFrame(src='https://matplotlib.org/', width=900, height=320)
matplotlib, a Python 2D plotting library#
Outline#
library for generating 2D data visualization
limited set of tools for 3D figures [mplot3d toolkit]
fully developed in python language
uses
numpyarrays for numeric processingit contains excelent features for the generation of scientific figures, as the possibility to use LaTeX syntax to add formulas on graphics
matplotlib hierarchy & main components#
I. scripting layer#
pyplot module: simple functions are used to add plot elements (lines, images, text, etc.) to the current axes in the current figure.
II. artist layer: what should be rendered (parts of the plot)#
The whole Figure keeps track of all the Axes, a group of ‘special’ Artists (Axis, titles, figure legends, colorbars, etc), and even nested subfigures.

III. backend layer: how it should be rendered#
figure canvas: area where Figure is drawn
renderer: knows how to draw
output backend: the frontend is the user facing code…
interactive: graphics for output on various types of GUIs [Tk, GTK, Qt, OSX, WX, …]
non interactive: hardcopy backends to make image files [PNG, SVG, PDF, PS, …]
Setting up our backend to the jupyter notebook#
%matplotlib inline
# this magic function sets the backend of matplotlib to the 'inline' backend.
# With this backend, the output of plotting commands is displayed inline within
# frontends like the Jupyter notebook, directly below the code cell that produced it.
# The resulting plots will then also be stored in the notebook document.
Using Matplotlib state-based interface#
matplotlib.pyplot is a module in matplotlib
Each pyplot function works on a single plot window (figure):
creates a figure ==> the whole window in the user interface
creates a plotting area inside the figure ==> Axes
draw graphs inside the plotting area
decorates a plot with labels, or other graphic items
pyplot is stateful:
tracks the status of the figure and its plotting area
the plotting functions works on the current figure
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-1.0,1.0,50, endpoint=True)
y=x**3
plt.plot(x,y)
plt.show()
we observe that:
no title, no labels, no annotations, no legend
default line color “blue”
axes dimension fits perfectly with the graph range
ticks marks are regularly spaced each 0.25 units
# controlling line properties using keyword arguments on function plot()
plt.plot(x,y, color='red', linestyle='--', marker='o')
# set the grapth title and axes labels:
plt.title('My_Title')
plt.xlabel('my_x_label')
plt.ylabel('my_y_label')
plt.show()
# controlling line properties using keyword arguments on function plot()
plt.plot(x,y, color='red', linestyle='--', marker='o')
# set the grapth title and axes labels:
plt.title('My_Title')
plt.xlabel('my_x_label')
plt.ylabel('my_y_label')
# set axes dimension: pyplot.axis([Xmin,Xmax,Ymin,Ymax])
plt.axis([-1.25,1.25, -1.1,1.1])
# modify tick marks on axes:
plt.xticks([0.25*k for k in range(-5,6)])
plt.yticks([-0.9,-0.4,0.0,0.3,0.6,0.85] , ['A','B','C','D','E','F'])
plt.show()
# add a second graph to the plot and additonal syntax
# color, marker and label:
plt.plot(x, x**6, 'r--', label='$x^{6}$')
plt.plot(x, x**2, 'bs', label='$x^{2}$')
# Matplotlib has great support for LaTeX.
# All we need to do is to use dollar signs to encapsulate LaTeX
# in any text (legend, title, label, etc.)
# add a legend to the graph:
plt.legend(loc='upper center')
plt.show()
# subplots:
plt.subplot(121)
plt.plot(x, x**6, 'r--', label='$x^{6}$')
plt.plot(x, x**2, 'bs', label='$x^{2}$')
plt.legend(loc='upper center')
plt.title('subplot 121')
#plt.grid(True)'$x^{6}$
plt.subplot(122)
plt.plot(x, -x**6, 'r--', label='$x^{6}$')
plt.plot(x, -x**2, 'bs', label='$x^{2}$')
plt.legend(loc='lower center')
plt.title('subplot 122')
plt.grid(True)
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10 , right=0.95, hspace=0.25, wspace=0.35)
Using matplotlib Object-Oriented API#
Increase the control over your display#
The next level down in the hierarchy is the first level of the object-oriented interface, in which pyplot is used only for a few functions such as figure creation, and the user explicitly creates and keeps track of the figure and axes objects.
At this level, the user uses pyplot to create figures, and through those figures, one or more axes objects can be created. These axes objects are then used for most plotting actions.
import matplotlib.pyplot as plt
# the wrapper that creates a figure and a set of subplots in a single call
# returns figure and axes object/array of axes objects
fig, (ax0, ax1) = plt.subplots(nrows=1,ncols=2, sharey=True, figsize=(7, 4))
# first Axes:
ax0.plot(x, x*2, 'p--', x, x**3, 'rs')
ax0.axvline(x=0, color='b', label='Label_1', linestyle='--', linewidth=1)
ax0.legend().set_visible(True)
# second Axes:
ax1.barh(x, x**3, color='green')
ax1.axvline(x=0, color='b', label='Label_2', linestyle='--', linewidth=5)
ax1.legend().set_visible(True)
fig = plt.figure(figsize=(8,3))
# Choose the postition of the Axes in the figure canvas:
ax1 = fig.add_axes([0, 0, 0.8, 0.8])
ax2 = fig.add_axes([0.75, 0.75, 0.4, 0.4]) # inset axes
ax1.plot(-x**3, y, 'r', label='plot_1')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax1.set_xlim(-1,1)
ax1.set_ylim(-1,1)
ax1.set_title('my_title_1', loc='left')
ax1.legend(loc=3)
ax2.plot(y, x, 'g', label='plot_2')
ax2.set_xlabel('y')
ax2.set_ylabel('x')
ax2.set_title('my_title_2',loc='right');
ax2.legend(loc=0)
plt.show()
# Create grid-shaped combinations of axes
fig1, f1_axes = plt.subplots(ncols=3, nrows=2, constrained_layout=True, figsize=(7,4))
# create subplots that span rows and columns:
# and/or sbuplots of different widths:
fig = plt.figure()
ax1 = plt.subplot2grid((2, 3), (0, 0), colspan=2)
ax2 = plt.subplot2grid((2, 3), (0, 2), rowspan=2)
ax2.plot(x, x**2, 'g', label='plot_2')
ax2.text(0.15, 0.2, r"$y=x^2$", fontsize=20, color="blue")
ax3 = plt.subplot2grid((2, 3), (1, 0))
ax4 = plt.subplot2grid((2, 3), (1, 1))
fig.tight_layout()
plt.show()
Operations on axis and annotations#
my_data = [0, 6, 12, 24, 48, 64, 128, 48, 16, 8]
ind = [0,1,2,3,4,5,6,7,8,9]
fig, ax = plt.subplots()
rects = ax.bar(ind, my_data, width=0.75, color='blue')
### axes labels:
ax.set_title('My Title', size=20)
ax.set_xlabel('My Data', size=10)
ax.set_ylabel('My Values', size=10)
### axis ticks:
ax.set_xticks(ind)
### axis labels
labels = ['x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']
ax.set_xticklabels(labels, size=10)
### add labels to bars
def mybarlabels(rects):
above = 1.02 * min([r.get_height() for r in rects])
for rect in rects:
height = rect.get_height()
# Add the text to the axes at location x, y in data coordinates
ax.text(rect.get_x() + rect.get_width()/2, 1.05*height, '%d'%int(height), ha='center', va='bottom')
mybarlabels(rects)
Change the styling for the plots#
The style package adds support for easy-to-switch plotting “styles” with the same parameters as a matplotlib rc file (which is read at startup to configure matplotlib)
# Customize the plot using style sheets
print(plt.style.available)
['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']
# change the global styling for the plots:
#plt.style.use('seaborn-darkgrid')
plt.style.use('seaborn-darkgrid')
fig, ax = plt.subplots()
ax.plot(y, x, 'g--')
ax.set_xlim(-1,1)
ax.set_ylim(-1,1)
plt.show()
with plt.style.context('dark_background'):
plt.plot(y, x, 'y--', marker='o', linewidth=2, markersize=8)
plt.show()
plt.style.use('default')
import numpy as np
with plt.xkcd():
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x1 = np.linspace(-15, 15, 1000)
y2 = np.sin(x1) / x1
y1 = np.cos(x1)
ax.plot(x1, y1)
ax.plot(x1, y2)
ax.set_xlabel("the abscissa")
ax.set_ylabel("some casual functions")
plt.title("a XKCD$^{**}$ style graph")
fig.text(0.5, -0.1,
'$^{**}$see xkcd by Randall Munroe @ https://xkcd.com',
ha='center')
findfont: Font family ['xkcd', 'xkcd Script', 'Humor Sans', 'Comic Neue', 'Comic Sans MS'] not found. Falling back to DejaVu Sans.
findfont: Font family ['xkcd', 'xkcd Script', 'Humor Sans', 'Comic Neue', 'Comic Sans MS'] not found. Falling back to DejaVu Sans.
findfont: Font family ['xkcd', 'xkcd Script', 'Humor Sans', 'Comic Neue', 'Comic Sans MS'] not found. Falling back to DejaVu Sans.
# Enable interactive plot
%matplotlib notebook
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
line, = ax.plot([]) # A tuple unpacking to unpack the only plot
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1.1, 1.1)
def animate(frame_num):
y = np.sin(x1 + 2*np.pi * frame_num/100)
line.set_data((x1, y))
return line
anim = FuncAnimation(fig, animate, frames=100, interval=20)
plt.show()
# Fixing random state for reproducibility
np.random.seed(19680801)
# Create new Figure and an Axes which fills it.
fig = plt.figure(figsize=(7, 7))
ax = fig.add_axes([0, 0, 1, 1], frameon=False)
ax.set_xlim(0, 1), ax.set_xticks([])
ax.set_ylim(0, 1), ax.set_yticks([])
# Create rain data
n_drops = 50
rain_drops = np.zeros(n_drops, dtype=[('position', float, (2,)),
('size', float),
('growth', float),
('color', float, (4,))])
# Initialize the raindrops in random positions and with
# random growth rates.
rain_drops['position'] = np.random.uniform(0, 1, (n_drops, 2))
rain_drops['growth'] = np.random.uniform(50, 200, n_drops)
# Construct the scatter which we will update during animation
# as the raindrops develop.
scat = ax.scatter(rain_drops['position'][:, 0], rain_drops['position'][:, 1],
s=rain_drops['size'], lw=0.5, edgecolors=rain_drops['color'],
facecolors='none')
def update(frame_number):
# Get an index which we can use to re-spawn the oldest raindrop.
current_index = frame_number % n_drops
# Make all colors more transparent as time progresses.
rain_drops['color'][:, 3] -= 1.0/len(rain_drops)
rain_drops['color'][:, 3] = np.clip(rain_drops['color'][:, 3], 0, 1)
# Make all circles bigger.
rain_drops['size'] += rain_drops['growth']
# Pick a new position for oldest rain drop, resetting its size,
# color and growth factor.
rain_drops['position'][current_index] = np.random.uniform(0, 1, 2)
rain_drops['size'][current_index] = 5
rain_drops['color'][current_index] = (0, 0, 0, 1)
rain_drops['growth'][current_index] = np.random.uniform(50, 200)
# Update the scatter collection, with the new colors, sizes and positions.
scat.set_edgecolors(rain_drops['color'])
scat.set_sizes(rain_drops['size'])
scat.set_offsets(rain_drops['position'])
# Construct the animation, using the update function as the animation director.
animation = FuncAnimation(fig, update, interval=10)
plt.show()
Saving figures to a file#
# Matplotlib supports many different formats for saving files
# what is supported by my local system?
fig.canvas.get_supported_filetypes()
{'eps': 'Encapsulated Postscript',
'jpg': 'Joint Photographic Experts Group',
'jpeg': 'Joint Photographic Experts Group',
'pdf': 'Portable Document Format',
'pgf': 'PGF code for LaTeX',
'png': 'Portable Network Graphics',
'ps': 'Postscript',
'raw': 'Raw RGBA bitmap',
'rgba': 'Raw RGBA bitmap',
'svg': 'Scalable Vector Graphics',
'svgz': 'Scalable Vector Graphics',
'tif': 'Tagged Image File Format',
'tiff': 'Tagged Image File Format'}
fig, ax = plt.subplots()
ax.plot(x,y,'g:o',label='$x^{1/2}$' )
ax.plot(x,-y**2,'r:^',label='$x^2$')
ax.legend(loc='upper left')
# 1. use the savefig method in the Figure class
# 2. choose one supported format for your file
# 3. choose the resolution of your image
# and many other options...
fig.savefig("outfile.png", dpi=200, transparent=False)
A large gallery showing the various types of plots that matplotlib can create…#
from IPython.display import IFrame
IFrame(src='https://matplotlib.org/stable/index.html', width=1300, height=320)
References#
https://matplotlib.org/stable/tutorials/index.html
http://www.aosabook.org/en/matplotlib.html
https://github.com/jrjohansson/scientific-python-lectures/blob/master/Lecture-4-Matplotlib.ipynb
http://www.loria.fr/~rougier/teaching/matplotlib