# Matplotlib: Pyplot By Example

Last updated:

Pyplot or Matplotlib? What's The difference?

All examples can be found online on this notebook

## Change size of Figure

After plotting, get a reference to the current figure and call set_size_inches(width,height):

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

plt.scatter(x,y)

# get reference to the current figure
fig = plt.gcf()
fig.set_size_inches(8,3)

plt.show()


Customized image with 8x3 inches.
(Default size is 6x4)

## Save plot to file (instead of displaying it)

Use plt.savefig().

The image format is deduced from the extension ('png', 'jpg', 'svg', etc)

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

plt.scatter(x,y)

plt.savefig('out.png')


## Multiple subplots in the same Figure

Call plt.subplots() to get a figure reference and individual Axes references (one for each subplot):

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

# passing 2,2 as parameters indicates that you will
# get 4 subplots (2 rows and 2 columns)
fig, axes = plt.subplots(2,2)

# just plot things on each individual axes
axes[0][0].scatter(x,y,c='red',marker='+')
axes[0][1].bar(x,y)
axes[1][0].scatter(x,y,marker='x')

axes[1][1].barh(x,y)
# optionally, add a title to this subplot only
axes[1][1].set_title('Plot 4')

plt.show()


Create a figure with 4 individual subplots using plt.subplots()

## Set Figure Title and Font size for a Figure

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

plt.scatter(x,y)

# get reference to the current figure
fig = plt.gcf()

fig.suptitle('IMAGE TITLE HERE', fontsize=18)

plt.show()


suptitle() acceps parameters you would normally use in matplotlib.Text

## Set Title and Font size for a single Axis

Similar to the above, but acts on a single Axis (useful if you have multiple suplots on the same Figure)

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

plt.scatter(x,y)

# get reference to the current axis
ax = plt.gca()

ax.set_title('title for this axis only', fontsize=20)


## Change legend text and location

Use plt.legend() using the text and the location string (e.g. 'upper left' or 'lower right') as arguments.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

plt.plot(x,y)

# when legend is called on the global pyplot
# namespace like this, it acts on the current axes
plt.legend(['Example legend'],loc='upper center')

plt.show()


Function legend() is available on pyplot but also on individual
Axes instances

## Disable legend

this must be AFTER the call to plot

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

plt.plot(x,y)

# get current axis and disable legend
plt.gca().legend_.remove()

plt.show()


## Change tick label rotation

Use plt.xticks() or plt.yticks and set the rotation argument (degrees)

If you want to call this on an Axes object instead, do: ax.set_xticklabels(ax.get_xticks(),rotation=60)

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

plt.plot(x,y)

# rotating labels on the xaxis
plt.xticks(rotation=60)
# y axis
plt.yticks(rotation=60)

plt.show()


You can change the label rotation for both the x-axis and the y-axis

## Set Axis labels and fontsize

Use plt.xlabel() or plt.ylabel, using the same arguments that are accepted by plt.text().

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

plt.plot(x,y)

plt.xlabel('time (s)',color='red',fontsize=30)
plt.ylabel('temperature (C)', fontsize=15)


You can use any other arguments from plt.text() too.

## Set y-axis, x-axis limits

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

# for the whole plot
plt.plot(x,y)

plt.ylim(-5,15)
plt.xlim(-30,130)

plt.show()


Same data as before, with more room around it.

## Label points in a plot

This was inspired by a guy on stackoverflow but I can't remember. If you know please send a message.

First define a function called plot_value_labels() and call it on your axis:

def plot_value_labels(axis):
rects = axis.patches

# For each bar: Place a label
for rect in rects:
# Get X and Y placement of label from rect.
y_value = rect.get_height()
x_value = rect.get_x() + rect.get_width() / 2

label = '{:.2f}'.format(y_value)

# Vertical alignment for positive values
va = 'bottom'

# If value of bar is negative: Place label below bar
if y_value < 0:
# Invert space to place label below
space *= -1
# Vertically align label at top
va = 'top'

# Create annotation
axis.annotate(label, (x_value, y_value),
xytext=(0, 2),
textcoords="offset points",
ha='center',
rotation=45,
va=va)

# now the actual code
import matplotlib.pyplot as plt
import numpy as np

# generate sample data
x = np.linspace(0.0,10,10)
y = np.random.uniform(low=0,high=6,size=10)

# plot bar plot
plt.bar(x,y)

# call the function we defined
plot_value_labels(plt.gca())

plt.show()


Simple labels on top of bars in a bar plot

## Set tick frequency

Use plt.xticks with np.arange (for the y-axis, use yticks instead).

Template: plt.xticks(np.arange(<start>,<end>,<step>)).

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

plt.plot(x,y)

# make the limits a bit larger so that we can see the results
plt.ylim(0,10)
plt.xlim(0,100)

# tell pyplot to write a x-axis tick every 5 units
plt.xticks(np.arange(0, 100, 5))
plt.show()


X-Axis ticks are drawn every 5 units, as per the call to xticks

## Add grid lines

import matplotlib.pyplot as plt
import numpy as np

# generate sample data
x = np.linspace(0.0,100,50)
y = np.random.uniform(low=0,high=10,size=50)

# enable grid lines in the axis
plt.gca().grid(True)

# select both y axis and x axis
gridlines = plt.gca().get_xgridlines() + plt.gca().get_ygridlines()

# choose line width
line_width = 0.7

for line in gridlines:
line.set_linestyle(':')
line.set_linewidth(line_width)

plt.plot(x,y)
plt.show()


0.7 is a reasonable setting for the line width

## Plot histogram for values in a numpy array

View all API options: pyplot docs: pyplot.hist

import matplotlib.pyplot as plt
import numpy as np

# generate sample data following a normal distribution
values = np.random.normal(size=100)
# array([ 0.49671415, -0.1382643 ,  0.64768854,...

# see all examples in the API link
plt.hist(values,rwidth=0.9,bins=[-3,-2,-1,0,1,2,3])

plt.show()


## String axis labels, bar plot

Call plt.xticks(x_values, labels):

import matplotlib.pyplot as plt
import numpy as np

# generate data
xs = [1,2,3,4,5,6,7,8,9,10,11,12]
ys = np.random.normal(loc=3.0,size=12)
labels = ['jan','feb','mar','apr','may','jun','jul','aug','sept','oct','nov','dec']

plt.bar(xs,ys)

# tell pyplot which labels correspond to which x values
plt.xticks(xs,labels)

plt.show()


If you don't set labels,
each label is the value itself

Set string labels using plt.xticks(xs,labels)

## Twin plots: Bars and lines on the same graph

import matplotlib.pyplot as plt
import numpy as np

xs = [1,2,3,4,5,6,7,8,9,10,11,12]
ys_bars = np.random.normal(loc=3.0,size=12)
ys_lines = np.random.normal(loc=5.0,size=12,scale=0.5)

ax1=plt.gca()
ax1.bar(xs,ys_bars,color='green')

# order is important when setting ticks.
# Ticks must be set after the plot has been drawn
ax1.set_yticks(np.arange(0,10,1))
ax1.set_yticklabels(np.arange(0,10,1),color='green')

# create the 'twin' axis on the right
ax2=ax1.twinx()
ax2.plot(xs,ys_lines,color='red')

ax2.set_yticks(np.arange(0,10,1))
ax2.set_yticklabels(np.arange(0,10,1),color='red')

plt.show()


Plot two different series on the same graph.
Note that each axis has a different scale.