## 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:

### 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.

• If I want to achieve this using matplotlib 0.99.1 (Without grid2spec), is it possible? Thank you.

Liked by 1 person

• Joanna Diong

Hi James, I have not tested the code in older versions of Matplotlib but there is a simpler way to plot subplots of different sizes without using gridspec, explained in this post. Cheers

Like

• Gabriel

Thanks Joanna, to redirect us to this link. It’s absolutely helpful and keeps the script neat and clean. But James’ post has helped me to get a quite difficult set of subplots spanning over more than 2 rows running, while the link didn’t. Or at least I couldn’t get it running.

Like

• Thanks mate. Nice clear explanation.

Liked by 1 person