Matplotlib: How to plot subplots of unequal sizes

Sometimes we would like to focus more on some data and less on others, but still provide a visual display. The matplotlib function gridspec allows subplots of unequal size to be plotted on the same figure. How this function can be applied will be demonstrated using simulated data. Let’s simulate some common probability distributions of different statistics using Python’s numpy.random module:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Import libraries
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
%matplotlib inline

# Generate data
dist_norm = np.random.normal(loc=0, scale=1, size=1000)
dist_tdis = np.random.standard_t(df=29, size=1000)
dist_fdis = np.random.f(dfnum=59, dfden=28, size=1000)
dist_chsq = np.random.chisquare(df=2, size=1000)

Lines 2-4. Import libraries and give each an alias.

Line 5. Include this line if using an IPython/ Jupyter notebook.

Line 8. Get 1000 samples from a normal distribution with mean 0, standard deviation 1.

Line 9. Get 1000 samples from a t distribution with 29 degrees of freedom.

Line 10. Get 1000 samples from a F distribution. The F distribution typically arises in an analysis of variance (ANOVA), which compares within-group to between-group variance; this comparison depends on sample size, which determines degrees of freedom in the numerator dfnum and denominator dfden.

Line 11. Get 1000 samples from a chi-square distribution with 2 degrees of freedom.

Now we can plot these data in a single figure, which will have 1 large subplot on the left, and a column of 3 small subplots on the right. The code to generate subplots is long but repetitive. You will get the hang of how to specify different parameters quickly:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Plot figure with subplots of different sizes
fig = plt.figure(1)
# set up subplot grid
gridspec.GridSpec(3,3)

# large subplot
plt.subplot2grid((3,3), (0,0), colspan=2, rowspan=3)
plt.locator_params(axis='x', nbins=5)
plt.locator_params(axis='y', nbins=5)
plt.title('Normal distribution')
plt.xlabel('Data values')
plt.ylabel('Frequency')
plt.hist(dist_norm, bins=30, color='0.30')

# small subplot 1
plt.subplot2grid((3,3), (0,2))
plt.locator_params(axis='x', nbins=5)
plt.locator_params(axis='y', nbins=5)
plt.title('t distribution')
plt.xlabel('Data values')
plt.ylabel('Frequency')
plt.hist(dist_tdis, bins=30, color='b')

# small subplot 2
plt.subplot2grid((3,3), (1,2))
plt.locator_params(axis='x', nbins=5)
plt.locator_params(axis='y', nbins=5)
plt.title('F distribution')
plt.xlabel('Data values')
plt.ylabel('Frequency')
plt.hist(dist_fdis, bins=30, color='r')

# small subplot 3
plt.subplot2grid((3,3), (2,2))
plt.locator_params(axis='x', nbins=5)
plt.locator_params(axis='y', nbins=5)
plt.title('Chi-square distribution')
plt.xlabel('Data values')
plt.ylabel('Frequency')
plt.hist(dist_chsq, bins=30, color='g')

# fit subplots and save fig
fig.tight_layout()
fig.set_size_inches(w=11,h=7)
fig_name = 'plot.png'
fig.savefig(fig_name)

Line 2. Create a figure object called fig so we can refer to all subplots in the same figure later.

Line 4. Call the function gridspec.Gridspec and specify an overall grid for the figure (in the background). Here, give the figure a grid of 3 rows and 3 columns.

Line 7. Call the function plt.subplot2grid() and specify the size of the figure’s overall grid, which is 3 rows and 3 columns (3,3). Specify the location of the large subplot: start counting from row 0 column 0 (0,0) and make a subplot across 2 columns and 3 rows colspan=2, rowspan=3. (Remember, Python indexes from 0, so the 3 rows or columns will be indexed as row or column 0, 1, 2.)

Lines 8-13. In this subplot, do the following:

  • for the x and y axes, set the number of bins to maximum of 5
  • give the plot a title
  • give the x and y axes titles
  • plot a histogram of the data with 30 bins and set the colour

Line 16. Specify the location of the first small subplot: start counting from row 0 column 2. In this subplot, do the following (similar to above) …

Line 25. Specify the location of the second small subplot: start counting from row 1 column 2. In this subplot, do the following …

Line 34. Count from row 2 column 2, do the following …

Line 43. Give the figure a tight_layout so that subplots are nicely spaced between each other. (Ironically, if you don’t specify this, the subplots are squeezed together even more tightly and text is overlaid.)

Lines 44-46. Set figure size, give it a name and save the figure

Play around with different parameter settings for each of the distributions to see how these change the properties of the distribution. The code above produces Figure 1 below:


Figure 1:

plot

Summary

In Python’s matplotlib library, the function gridspec can be applied to plot subplots of unequal sizes by specifying an overall row and column grid for a figure, then referencing location and size of individual subplots within the figure.

Note: Another way to plot subplots of unequal sizes in Matplotlib is to specify subplot parameters in a style similar to Matlab’s plotting style. Check out this tutorial.

 

3 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s