Matplotlib: Pyplot By Example

Last updated:
Matplotlib: Pyplot By Example
Source
Table of Contents

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()

set_size_inches 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()

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

Set Figure Title and Font size for a Figure

Use Figure.suptitle()

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()

set figure title pyplot 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)
Twitter Linkedin YC Hacker News Reddit

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()

set legend size 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()

rotate-ticks-on-pyplot 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)

axis-labels-and-fontsize 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()

y-axis-limit-and-x-axis-limit 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-label-on-bar-plots 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()

xticks-more-frequent 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()

grid-lines-in-pyplot 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()

plot-without-explicitly-setting-labels If you don't set labels,
each label is the value itself
         
matplotlib-bar-plot-with-strings-for-labels 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()

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


References

Dialogue & Discussion