In [1]:
%load_ext watermark

In [2]:
%watermark -u -v -d -p matplotlib,numpy


Last updated: 11/08/2014 

CPython 3.4.1
IPython 2.1.0

matplotlib 1.3.1
numpy 1.8.1

[More info](http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/ipython_magic/watermark.ipynb) about the `%watermark` extension


In [3]:
%matplotlib inline



Formatting I: subplots, markers, colors, axes



Sections



Subplots


In [4]:
import numpy as np
import matplotlib.pyplot as plt

x = range(10)
y = range(10)

fig, ax = plt.subplots(2)

for sp in ax:
    sp.plot(x, y)




m x n subplots


In [5]:
import matplotlib.pyplot as plt

x = range(10)
y = range(10)

fig, ax = plt.subplots(nrows=2,ncols=2)

for row in ax:
    for col in row:
        col.plot(x, y)
        
plt.show()



In [6]:
fig, ax = plt.subplots(nrows=2,ncols=2)

plt.subplot(2,2,1)
plt.plot(x, y)

plt.subplot(2,2,2)
plt.plot(x, y)
    
plt.subplot(2,2,3)
plt.plot(x, y)

plt.subplot(2,2,4)
plt.plot(x, y)
    
plt.show()




Labeling a subplot grid like a matrix


In [32]:
import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(nrows=3, ncols=3, 
                         sharex=True, sharey=True,
                         figsize=(8,8)
                         )
x = range(5)
y = range(5)

for row in axes:
    for col in row:
        col.plot(x, y)

for ax, col in zip(axes[0,:], ['1', '2', '3']):
    ax.set_title(col, size=20)
    
for ax, row in zip(axes[:,0], ['A', 'B', 'C']):
    ax.set_ylabel(row, size=20, rotation=0, labelpad=15)
  
plt.show()




Shared X- and Y-axes


In [14]:
import matplotlib.pyplot as plt

x = range(10)
y = range(10)

fig, ax = plt.subplots(nrows=2,ncols=2, sharex=True, sharey=True)

for row in ax:
    for col in row:
        col.plot(x, y)
    
plt.show()




Setting title and labels


In [20]:
import matplotlib.pyplot as plt

x = range(10)
y = range(10)

fig, ax = plt.subplots(nrows=2,ncols=2)

for row in ax:
    for col in row:
        col.plot(x, y)
        col.set_title('title')  
        col.set_xlabel('x-axis')
        col.set_ylabel('x-axis')
                
fig.tight_layout()
            
plt.show()




Hiding redundant subplots

Sometimes we create more subplots for a rectangular layout (here: 3x3) than we actually need. Here is how we hide those redundant subplots. Let's assume that we only want to show the first 7 subplots:


In [6]:
import matplotlib.pyplot as plt

x = range(10)
y = range(10)

fig, axes = plt.subplots(nrows=3,ncols=3)

for cnt, ax in enumerate(axes.ravel()):
    if cnt < 7:    
        ax.plot(x, y)
    else:
        ax.axis('off') # hide subplot
plt.show()




Defining colors



3 ways to define colors

Matplotlib supports 3 different ways to encode colors, e.g, if we want to use the color blue, we can define colors as

  • RGB color values (range 0.0 to 1.0) -> (0.0, 0.0, 1.0)
  • matplotlib supported names -> 'blue' or 'b'
  • HTML hex values -> '#0000FF'

In [18]:
import matplotlib.pyplot as plt

samples = range(1,4)

for i, col in zip(samples, [(0.0, 0.0, 1.0), 'blue', '#0000FF']):
    plt.plot([0, 10], [0, i], lw=3, color=col) 

plt.legend(['RGB values: (0.0, 0.0, 1.0)', 
            "matplotlib names: 'blue'", 
            "HTML hex values: '#0000FF'"],
           loc='upper left')    
plt.title('3 alternatives to define the color blue')
    
plt.show()




matplotlib color names

The color names that are supported by matplotlib are

b: blue
g: green
r: red
c: cyan
m: magenta
y: yellow
k: black
w: white

where the first letter represents the shortcut version.


In [19]:
import matplotlib.pyplot as plt

cols = ['blue', 'green', 'red', 'cyan',  'magenta', 'yellow', 'black', 'white']

samples = range(1, len(cols)+1)

for i, col in zip(samples, cols):
    plt.plot([0, 10], [0, i], label=col, lw=3, color=col) 

plt.legend(loc='upper left')    
plt.title('matplotlib color names')
    
plt.show()




Colormaps


In [4]:
import numpy as np
import matplotlib.pyplot as plt

fig, (ax0, ax1) = plt.subplots(1,2, figsize=(14, 7))
samples = range(1,16)

# Default Color Cycle

for i in samples:
    ax0.plot([0, 10], [0, i], label=i, lw=3) 

# Colormap    
    
colormap = plt.cm.Paired
plt.gca().set_color_cycle([colormap(i) for i in np.linspace(0, 0.9, len(samples))])

for i in samples:
    ax1.plot([0, 10], [0, i], label=i, lw=3) 
    
# Annotation    
    
ax0.set_title('Default color cycle')
ax1.set_title('plt.cm.Paired colormap')
ax0.legend(loc='upper left')
ax1.legend(loc='upper left')

plt.show()




Gray-levels


In [28]:
import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(8,6))

samples = np.arange(0, 1.1, 0.1)

for i in samples:
    plt.plot([0, 10], [0, i], label='gray-level %s'%i, lw=3, 
             color=str(i)) # ! gray level has to be parsed as string

plt.legend(loc='upper left')    
plt.title('gray-levels')
    
plt.show()




Edgecolors for scatter plots


In [58]:
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(10,10))

samples = np.random.randn(30,2)

ax[0][0].scatter(samples[:,0], samples[:,1], 
            color='red',
            label='color="red"')
    
ax[1][0].scatter(samples[:,0], samples[:,1],
            c='red',
            label='c="red"')

ax[0][1].scatter(samples[:,0], samples[:,1], 
            edgecolor='white', 
            c='red',
            label='c="red", edgecolor="white"')

ax[1][1].scatter(samples[:,0], samples[:,1], 
            edgecolor='0', 
            c='1',
            label='color="1.0", edgecolor="0"')

for row in ax:
    for col in row:
        col.legend(loc='upper left') 
    
plt.show()




Color gradients


In [29]:
import matplotlib.pyplot as plt
import matplotlib.colors as col
import matplotlib.cm as cm
import numpy as np

# input data
mean_values = np.random.randint(1, 101, 100)
x_pos = range(len(mean_values))

fig = plt.figure(figsize=(20,5))

# create colormap
cmap = cm.ScalarMappable(col.Normalize(min(mean_values), 
                                       max(mean_values), 
                                       cm.hot))

# plot bars
plt.subplot(131)
plt.bar(x_pos, mean_values, align='center', alpha=0.5, 
        color=cmap.to_rgba(mean_values))
plt.ylim(0, max(mean_values) * 1.1)

plt.subplot(132)
plt.bar(x_pos, np.sort(mean_values), align='center', alpha=0.5, 
        color=cmap.to_rgba(mean_values))
plt.ylim(0, max(mean_values) * 1.1)

plt.subplot(133)
plt.bar(x_pos, np.sort(mean_values), align='center', alpha=0.5, 
        color=cmap.to_rgba(np.sort(mean_values)))
plt.ylim(0, max(mean_values) * 1.1)

plt.show()




Marker styles


In [5]:
import matplotlib.pyplot as plt

import numpy as np
import matplotlib.pyplot as plt

markers = [

'.', # point
',', # pixel
'o', # circle
'v', # triangle down
'^', # triangle up
'<', # triangle_left
'>', # triangle_right
'1', # tri_down
'2', # tri_up
'3', # tri_left
'4', # tri_right
'8', # octagon
's', # square
'p', # pentagon
'*', # star
'h', # hexagon1
'H', # hexagon2
'+', # plus
'x', # x
'D', # diamond
'd', # thin_diamond
'|', # vline

]

plt.figure(figsize=(13, 10))
samples = range(len(markers))


for i in samples:
    plt.plot([i-1, i, i+1], [i, i, i], label=markers[i], marker=markers[i], markersize=10) 


# Annotation    
    
plt.title('Matplotlib Marker styles', fontsize=20)
plt.ylim([-1, len(markers)+1])
plt.legend(loc='lower right')


plt.show()




Line styles


In [13]:
import numpy as np
import matplotlib.pyplot as plt

linestyles = ['-.', '--', 'None', '-', ':']

plt.figure(figsize=(8, 5))
samples = range(len(linestyles))


for i in samples:
    plt.plot([i-1, i, i+1], [i, i, i], 
             label='"%s"' %linestyles[i], 
             linestyle=linestyles[i],
             lw=4
             ) 

# Annotation    
    
plt.title('Matplotlib line styles', fontsize=20)
plt.ylim([-1, len(linestyles)+1])
plt.legend(loc='lower right')


plt.show()




Fancy and transparent legends


In [8]:
import numpy as np
import matplotlib.pyplot as plt

X1 = np.random.randn(100,2)
X2 = np.random.randn(100,2)
X3 = np.random.randn(100,2)

R1 = (X1**2).sum(axis=1)
R2 = (X2**2).sum(axis=1)
R3 = (X3**2).sum(axis=1)

plt.scatter(X1[:,0], X1[:,1],
            c='blue',
            marker='o',
            s=32. * R1,
            edgecolor='black',
            label='Dataset X1',
            alpha=0.7)
plt.scatter(X2[:,0], X2[:,1],
            c='gray',
            marker='s',
            s=32. * R2,
            edgecolor='black',
            label='Dataset X2',
            alpha=0.7)

plt.scatter(X2[:,0], X3[:,1],
            c='green',
            marker='^',
            s=32. * R3,
            edgecolor='black',
            label='Dataset X3',
            alpha=0.7)

plt.xlim([-3,3])
plt.ylim([-3,3])

leg = plt.legend(loc='upper left', fancybox=True)
leg.get_frame().set_alpha(0.5)

plt.show()




Hiding axes



Hiding axis ticks and labels


In [26]:
import numpy as np
import matplotlib.pyplot as plt

x = range(10)
y = range(10)

fig = plt.gca()

plt.plot(x, y)

fig.axes.get_xaxis().set_visible(False)
fig.axes.get_yaxis().set_visible(False)

plt.show()




Removing frame and ticks


In [29]:
import numpy as np
import matplotlib.pyplot as plt

x = range(10)
y = range(10)

fig = plt.gca()

plt.plot(x, y)

# removing frame
fig.spines["top"].set_visible(False)  
fig.spines["bottom"].set_visible(False)  
fig.spines["right"].set_visible(False)  
fig.spines["left"].set_visible(False) 

# removing ticks
plt.tick_params(axis="both", which="both", bottom="off", top="off",  
                labelbottom="on", left="off", right="off", labelleft="on")  

plt.show()




Aesthetic axis layout


In [4]:
import numpy as np
import math
import matplotlib.pyplot as plt

X = np.random.normal(loc=0.0, scale=1.0, size=300)
width = 0.5
bins = np.arange(math.floor(X.min())-width, 
                 math.ceil(X.max())+width, 
                 width) # fixed bin size

ax = plt.subplot(111)  

# remove axis at the top and to the right
ax.spines["top"].set_visible(False)  
ax.spines["right"].set_visible(False) 

# hide axis ticks
plt.tick_params(axis="both", which="both", bottom="off", top="off",  
                labelbottom="on", left="off", right="off", labelleft="on")

plt.hist(X,  alpha=0.5, bins=bins)
plt.grid()

plt.xlabel('x label')
plt.ylabel('y label')
plt.title('title')

plt.show()




Custom tick labels



Text and rotation


In [32]:
import matplotlib.pyplot as plt

x = range(10)
y = range(10)
labels = ['super long axis label' for i in range(10)]

fig, ax = plt.subplots()

plt.plot(x, y)

# set custom tick labels
ax.set_xticklabels(labels, rotation=45, horizontalalignment='right')

plt.show()




Adding a constant value to axis labels


In [7]:
import matplotlib.pyplot as plt

CONST = 10

x = range(10)
y = range(10)
labels = [i+CONST for i in x]

fig, ax = plt.subplots()

plt.plot(x, y)
plt.xlabel('x-value + 10')

# set custom tick labels
ax.set_xticklabels(labels)

plt.show()






Applying customization and settings globally

Everyone has a different perception of "style", and usually, we would make some little adjustments to matplotlib's default visuals here and there. After customization, it would be tedious to repeat the same code over and over again every time we produce a new plot.
However we have multiple options to apply the changes globally.



Settings for the active session only

Here, we are only interested in the settings for the current session. In this case, one way to customize matplotlibs defaults would be the 'rcParams' attribute (in the next session, you will see a handy reference for all the different matplotlib settings). E.g., if we want to make the font size of our titles larger for all plots that follow in the active session, we could type the following:


In [32]:
import matplotlib as mpl
mpl.rcParams['axes.titlesize'] = '20'

Let's see how it looks like:


In [33]:
from matplotlib import pyplot as plt
x = range(10)
y = range(10)

plt.plot(x, y)
plt.title('larger title')    
plt.show()


And if we want to revert it back to the default settings, we can use the command:


In [34]:
mpl.rcdefaults()

Note that we have to re-execute the matplotlib inline magic function afterwards:


In [35]:
%matplotlib inline

In [36]:
plt.plot(x, y)
plt.title('default title size')    
plt.show()




Modifying the matplotlibrc file

Let's assume that we decided to always prefer a particular setting over matplotlib's default (e.g., a larger font size for the title like in the previous section), we can make a change to the matplotlibrc file: This way we'd avoid to change the setting every time we start a new session or produce a new plot.

The matplotlibrc file can reside in different places depending on your sytem. An convenient way to find out the location is to use the matplotlib_fname() function.


In [43]:
import matplotlib
matplotlib.matplotlib_fname()


Out[43]:
'/Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/matplotlib/mpl-data/matplotlibrc'

If we open this file in an editor, we will see an overview of all the different matplotlib default settings and their default values. We can use this list either as a reference to apply changes dynamically (see the previous section), or we can un-comment this line here and change its default value. E.g., we want to change the title size again, we could change the following line:

axes.titlesize : 20

One thing to keep in mind is that this file becomes overwritten if we install a new version of matplotlib, and it is always recommended to keep backups as you change the settings (the file with its original default settings can be found here).

Sometimes, we even want to keep and use multiple matplotlibrc files, e.g., if we are writing articles for different journals and every journal has its own requirement for figure formats. In this case, we can load our own rc files from a different local directory:


In [ ]:
from matplotlib import rc_file
rc_file('/path/to/matplotlibrc_journalX')
import matplotlib.pyplot as plt