Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tut] Matplotlib Subplot – A Helpful Illustrated Guide
1
Matplotlib Subplot – A Helpful Illustrated Guide

Too much stuff happening in a single plot? No problem—use multiple subplots!

This in-depth tutorial shows you everything you need to know to get started with Matplotlib’s
Code:
subplot()
function.


If you want, just hit “play” and watch the explainer video. I’ll then guide you through the tutorial:



To create a matplotlib subplot with any number of rows and columns, use the
Code:
plt.subplot()
function.

It takes 3 arguments, all of which are integers and positional only i.e. you cannot use keywords to specify them.

Code:
plt.subplot(nrows, ncols, index)
  • Code:
    nrows
    – the number of rows

  • Code:
    ncols
    – the number of columns

  • Code:
    index
    – the
    Code:
    Subplot
    you want to select (starting from 1 in the top left)

So,
Code:
plt.subplot(3, 1, 1)
has 3 rows, 1 column (a 3 x 1 grid) and selects
Code:
Subplot
with index 1.

After
Code:
plt.subplot()
, code your plot as normal using the
Code:
plt.
functions you know and love. Then, select the next subplot by increasing the index by 1 –
Code:
plt.subplot(3, 1, 2)
selects the second
Code:
Subplot
in a 3 x 1 grid. Once all
Code:
Subplots
have been plotted, call
Code:
plt.tight_layout()
to ensure no parts of the plots overlap. Finally, call
Code:
plt.show()
to display your plot.

Code:
# Import necessary modules and (optionally) set Seaborn style import matplotlib.pyplot as plt import seaborn as sns; sns.set() import numpy as np # Generate data to plot linear = [x for x in range(5)] square = [x**2 for x in range(5)] cube = [x**3 for x in range(5)] # 3x1 grid, first subplot plt.subplot(3, 1, 1) plt.plot(linear) # 3x1 grid, second subplot plt.subplot(3, 1, 2) plt.plot(square) # 3x1 grid, third subplot plt.subplot(3, 1, 3) plt.plot(cube) plt.tight_layout() plt.show()
[Image: img0.png]
Matplotlib Subplot Example

The arguments for
Code:
plt.subplot()
are intuitive:

Code:
plt.subplot(nrows, ncols, index)

The first two – nrows and ncols – stand for the number of rows and number of columns respectively.

If you want a 2×2 grid, set nrows=2 and ncols=2. For a 3×1 grid, it’s nrows=3 and ncols=1.

The index is the subplot you want to select. The code you write immediately after it is drawn on that subplot. Unlike everything else in the Python universe, indexing starts from 1, not 0. It continues from left-to-right in the same way you read.

So, for a 2 x 2 grid, the indexes are

[Image: img1.png]

For a 3 x 1 grid, they are

[Image: img2.png]

The arguments for
Code:
plt.subplot()
are positional only. You cannot pass them as keyword arguments.

Code:
>>> plt.subplot(nrows=3, ncols=1, index=1) AttributeError: 'AxesSubplot' object has no property 'nrows'

However, the comma between the values is optional, if each value is an integer less than 10.

Thus, the following are equivalent – they both select index 1 from a 3×1 grid.

Code:
plt.subplot(3, 1, 1) plt.subplot(311)

I will alternate between including and excluding commas to aid your learning.

Let’s look at the default subplot layout and the general outline for your code.

Code:
plt.subplot(3, 1, 1) <em># First subplot here</em> plt.subplot(3, 1, 2) <em># Second subplot here</em> plt.subplot(3, 1, 3) <em># Third subplot here</em> plt.show()
[Image: img3.png]

This looks ok but the x-axis labels are hard to read on the top 2 subplots.

You have a few ways to solve this problem.

First, you can manually adjust the xticks with the matplotlib xticks function –
Code:
plt.xticks()
– and either:

  1. make them transparent by setting
    Code:
    alpha=0
    , or

  2. move them and decrease their font size with the
    Code:
    position
    and
    Code:
    size
    arguments

Code:
# Make xticks of top 2 subplots transparent plt.subplot(3, 1, 1) plt.xticks(alpha=0) plt.subplot(3, 1, 2) plt.xticks(alpha=0) # Plot nothing on final subplot plt.subplot(3, 1, 3) plt.suptitle('Transparent Xticks - plt.xticks(alpha=0)') plt.show()
[Image: img4.png]
Code:
# Move and decrease size of xticks on all subplots plt.subplot(3, 1, 1) plt.xticks(position=(0, 0.1), size=10) plt.subplot(3, 1, 2) plt.xticks(position=(0, 0.1), size=10) plt.subplot(3, 1, 3) plt.xticks(position=(0, 0.1), size=10) plt.suptitle('Smaller Xticks In A Better Position') plt.show()
[Image: img5.png]

Both these methods work but are fiddly. Plus, you cannot automate them which is annoying for us programmers.

You have this ticks problem whenever you create subplots. Thankfully, the matplotlib tight_layout function was created to solve this.

Matplotlib Tight_Layout

By calling
Code:
plt.tight_layout()
, matplotlib automatically adjusts the following parts of the plot to make sure they don’t overlap:

  1. axis labels set with
    Code:
    plt.xlabel()
    and
    Code:
    plt.ylabel()
    ,

  2. tick labels set with
    Code:
    plt.xticks()
    and
    Code:
    plt.yticks()
    ,

  3. titles set with
    Code:
    plt.title()
    and
    Code:
    plt.suptitle()

Note that this feature is experimental. It’s not perfect but often does a really good job. Also, note that it does not work too well with legends or colorbars – you’ll see how to work with them later.

Let’s see the most basic example without any labels or titles.

Code:
plt.subplot(311) plt.subplot(312) plt.subplot(313) plt.tight_layout() plt.show()
[Image: img6.png]

Now there is plenty of space between the plots. You can adjust this with the
Code:
pad
keyword. It accepts a float in the range [0.0, 1.0] and is a fraction of the font size.

Code:
plt.subplot(311) plt.subplot(312) plt.subplot(313) plt.tight_layout(pad=0.1) plt.show()
[Image: img7.png]

Now there is less space between the plots but everything is still readable. I use
Code:
plt.tight_layout()
in every single plot (without colobars or legends) and I recommend you do as well. It’s an easy way to make your plots look great.

Check out the docs more information and arguments that tight_layout in matplotlib accepts.

Now, let’s look at how to add more info to our subplots in matplotib.

Matplotlib Subplot Title

You can add a title to each subplot with the
Code:
plt.title()
function.

Code:
plt.subplot(2, 2, 1) plt.title('First Title') plt.subplot(2, 2, 2) plt.title('Second Title') plt.subplot(2, 2, 3) plt.title('Third Title') plt.subplot(2, 2, 4) plt.title('Fourth Title') plt.tight_layout() plt.show()
[Image: img8.png]
Matplotlib Subplot Overall Title

Add an overall title to a subplot in matplotlib with the
Code:
plt.suptitle()
function (it stands for ‘super title’).

Code:
# Same plot as above plt.subplot(2, 2, 1) plt.title('First Title') plt.subplot(2, 2, 2) plt.title('Second Title') plt.subplot(2, 2, 3) plt.title('Third Title') plt.subplot(2, 2, 4) plt.title('Fourth Title') # Add overall title to the plot plt.suptitle('My Lovely Plot') plt.tight_layout() plt.show()
[Image: img9.png]
Matplotlib Subplot Height

To change the height of a subplot in matplotlib, see the next section.

Matplotlib Subplot Size

You have total control over the size of subplots in matplotlib.

You can either change the size of the entire
Code:
Figure
or the size of the
Code:
Subplots
themselves.

Let’s look at changing the
Code:
Figure
.

Matplotlib Figure Size

First off, what is the
Code:
Figure
? To quote the AnatomyOfMatplotlib:

Quote:It is the overall window/page that everything is drawn on. You can have multiple independent figures and
Code:
Figures
can contain multiple
Code:
Subplots

In other words, the
Code:
Figure
is the blank canvas you ‘paint’ all your plots on.

If you are happy with the size of your subplots but you want the final image to be larger/smaller, change the
Code:
Figure
. Do this at the top of your code with the matplotlib figure function –
Code:
plt.figure()
.

Code:
# Make Figure 3 inches wide and 6 inches long plt.figure(figsize=(3, 6)) # Create 2x1 grid of subplots plt.subplot(211) plt.subplot(212) plt.show()
[Image: img10.png]

Before coding any subplots, call
Code:
plt.figure()
and specify the
Code:
Figure
size with the
Code:
figsize
argument. It accepts a tuple of 2 numbers –
Code:
(width, height)
of the image in inches.

Above, I created a plot 3 inches wide and 6 inches long –
Code:
plt.figure(figsize=(3, 6))
.

Code:
# Make a Figure twice as long as it is wide plt.figure(figsize=plt.figaspect(2)) # Create 2x1 grid of subplots plt.subplot(211) plt.subplot(212) plt.show()
[Image: img11.png]

You can set a more general
Code:
Figure
size with the matplotlib figaspect function. It lets you set the aspect ratio (height/width) of the
Code:
Figure
.

Above, I created a
Code:
Figure
twice as long as it is wide by setting
Code:
figsize=plt.figaspect(2)
.

Note: Remember the aspect ratio (height/width) formula by recalling that
Code:
height
comes first in the alphabet.

Now let’s look at putting different sized
Code:
Subplots
on one
Code:
Figure
.

Matplotlib Subplots Different Sizes

The hardest part of creating a
Code:
Figure
with different sized
Code:
Subplots
in matplotlib is figuring out what fraction each
Code:
Subplot
takes up.

So, you should know what you are aiming for before you start. You could sketch it on paper or draw shapes in PowerPoint. Once you’ve done this, everything else is much easier.

I’m going to create this shape

[Image: img12.png]

I’ve labeled the fraction each
Code:
Subplot
takes up as we need this for our
Code:
plt.subplot()
calls.

I’ll create the biggest subplot first and the others in descending order.

[Image: img13.png]

The right-hand side is half of the plot. It is one of two plots on a
Code:
Figure
with 1 row and 2 columns. To select it with
Code:
plt.subplot()
, you need to set
Code:
index=2
.

Note that in the image, the blue numbers are the index values each
Code:
Subplot
has.

In code, this is

Code:
plt.subplot(122)
[Image: img14.png]

Now, select the bottom left
Code:
Subplot
in a a 2×2 grid i.e.
Code:
index=3

Code:
plt.subplot(223)
[Image: img15.png]

Lastly, select the top two
Code:
Subplots
on the left-hand side of a 4×2 grid i.e.
Code:
index=1
and
Code:
index=3
.

Code:
plt.subplot(421) plt.subplot(423)

When you put this altogether you get

Code:
# Subplots you have just figured out plt.subplot(122) plt.subplot(223) plt.subplot(421) plt.subplot(423) plt.tight_layout(pad=0.1) plt.show()
[Image: img16.png]

Perfect! Breaking the
Code:
Subplots
down into their individual parts and knowing the shape you want makes everything easier.

Matplotlib Subplot Size Different

You may have noticed that each of the
Code:
Subplots
in the previous example took up
Code:
1/x
fraction of space –
Code:
1/2
,
Code:
1/4
and
Code:
1/8
.

With the matplotlib subplot function, you can only create
Code:
Subplots
that are
Code:
1/x
.

[Image: img17.png]

It is not possible to create the above plot in matplotlib using the
Code:
plt.subplot()
function. However, if you use the matplotlib subplots function or GridSpec, then it can be done.

Matplotlib Subplots_Adjust

If you aren’t happy with the spacing between plots that
Code:
plt.tight_layout()
provides, manually adjust it with
Code:
plt.subplots_adjust()
.

It takes 6 optional, self-explanatory keyword arguments. Each accepts a float in the range [0.0, 1.0] and they are a fraction of the font size:
  • Code:
    left
    ,
    Code:
    right
    ,
    Code:
    bottom
    and
    Code:
    top
    is the spacing on each side of the
    Code:
    Subplot

  • Code:
    wspace
    – the width between
    Code:
    Subplots

  • Code:
    hspace
    – the height between
    Code:
    Subplots

Code:
# Same grid as above plt.subplot(122) plt.subplot(223) plt.subplot(421) plt.subplot(423) # Set horizontal and vertical space to 0.05 plt.subplots_adjust(hspace=0.05, wspace=0.05) plt.show()
[Image: img18.png]

In this example, I decreased both the height and width to just
Code:
0.05
. Now there is hardly any space between the plots.

To avoid loads of similar examples, play around with the arguments yourself to get a feel for how this function works.

Matplotlib Suplot DPI

The Dots Per Inch (DPI) is a measure of printer resolution. It is the number of colored dots placed on each square inch of paper when it’s printed. The more dots you have, the higher the quality of the image. If you are going to print your plot on a large poster, it’s a good idea to use a large DPI.

The DPI for each
Code:
Figure
is controlled by the
Code:
plt.rcParams
dictionary. It contains all the runtime configuration settings. If you print
Code:
plt.rcParams
to the screen, you will see all the variables you can modify. We want
Code:
figure.dpi
.

Let’s make a simple line plot first with the default DPI (72.0) and then a much smaller value.

Code:
# Print default DPI print(f"The default DPI in matplotlib is {plt.rcParams['figure.dpi']}") # Default DPI plt.plot([1, 2, 3, 4]) plt.title('DPI - 72.0') plt.show() # Smaller DPI plt.rcParams['figure.dpi'] = 30.0 plt.plot([1, 2, 3, 4]) plt.title('DPI - 30.0') plt.show() # Change DPI back to 72.0 plt.rcParams['figure.dpi'] = 72.0
Code:
The default DPI in matplotlib is 72.0
[Image: img19.png]
[Image: img20.png]

The
Code:
Figure
with a smaller DPI is smaller and has a lower resolution.

If you want to permanently change the DPI of all matplotlib
Code:
Figures
– or any of the runtime configuration settings – find the
Code:
matplotlibrc
file on your system and modify it.

You can find it by entering

Code:
import matplotlib as mpl mpl.matplotlib_fname()

Once you have found it, there are notes inside telling you what everything does.

Matplotlib Subplot Spacing

The function
Code:
plt.tight_layout()
solves most of your spacing issues. If that is not enough, call it with the optional
Code:
pad
and pass a float in the range [0.0, 1.0]. If that still is not enough, use the
Code:
plt.subplots_adjust()
function.

I’ve explained both of these functions in detail further up the article.

Matplotlib Subplot Colorbar

Adding a colorbar to each plot is the same as adding a title – code it underneath the
Code:
plt.subplot()
call you are currently working on. Let’s plot a 1×2 grid where each
Code:
Subplot
is a heatmap of randomly generated numbers.

For more info on the Python random module, check out my article. I use the Numpy random module below but the same ideas apply.

Code:
# Set seed so you can reproduce results np.random.seed(1) # Create a 10x10 array of random floats in the range [0.0, 1.0] data1 = np.random.random((10, 10)) data2 = np.random.random((10, 10)) # Make figure twice as wide as it is long plt.figure(figsize=plt.figaspect(1/2)) # First subplot plt.subplot(121) pcm1 = plt.pcolormesh(data1, cmap='Blues') plt.colorbar(pcm1) # Second subplot plt.subplot(122) pcm2 = plt.pcolormesh(data2, cmap='Greens') plt.colorbar(pcm2) plt.tight_layout() plt.show()
[Image: img21.png]

First, I created some
Code:
(10, 10)
arrays containing random numbers between 0 and 1 using the
Code:
np.random.random()
function. Then I plotted them as heatmaps using
Code:
plt.pcolormesh()
. I stored the result and passed it to
Code:
plt.colorbar()
, then finished the plot.

As this is an article on
Code:
Subplots
, I won’t discuss the matplotlib pcolormesh function in detail.

Since these plots are different samples of the same data, you can plot them with the same color and just draw one colorbar.

[Image: img22.png]

To draw this plot, use the same code as above and set the same
Code:
colormap
in both matplotlib pcolormesh calls –
Code:
cmap='Blues'
. Then draw the colorbar on the second subplot.

This doesn’t look as good as the above
Code:
Figure
since the colorbar takes up space from the second
Code:
Subplot
. Unfortunately, you cannot change this behavior – the colorbar takes up space from the
Code:
Subplot
it is drawn next to.

It is possible to draw colorbars over multiple
Code:
Subplots
but you need to use the
Code:
plt.subplots()
function. I’ve written a whole tutorial on this—so feel free to check out this more powerful function!

Matplotlib Subplot Grid

A
Code:
Grid
is the number of rows and columns you specify when calling
Code:
plt.subplot()
. Each section of the
Code:
Grid
is called a cell. You can create any sized grid you want. But
Code:
plt.subplot()
only creates
Code:
Subplots
that span one cell. To create
Code:
Subplots
that span multiple cells, use the
Code:
GridSpec
class
, the
Code:
plt.subplots()
function
or the
Code:
subplot2grid
method.

I discuss these in detail in my article on matplotlib subplots.

Summary

Now you know everything there is to know about the subplot function in matplotlib.

You can create grids of any size you want and draw subplots of any size – as long as it takes up
Code:
1/x
th of the plot. If you want a larger or smaller
Code:
Figure
you can change it with the
Code:
plt.figure()
function. Plus you can control the DPI, spacing and set the title.

Armed with this knowlege, you can now make impressive plots of unlimited complexity.

But you have also discovered some of the limits of the subplot function. And you may feel that it is a bit clunky to type
Code:
plt.subplot()
whenever you want to draw a new one.

To learn how to create more detailed plots with less lines of code, read my article on the
Code:
plt.subplots()
(with an ‘s’) function.

Where To Go From Here?

Do you wish you could be a programmer full-time but don’t know how to start?

Check out my pure value-packed webinar where I teach you to become a Python freelancer in 60 days or your money back!

https://tinyurl.com/become-a-python-freelancer

It doesn’t matter if you’re a Python novice or Python pro. If you are not making six figures/year with Python right now, you will learn something from this webinar. 

These are proven, no-BS methods that get you results fast.

This webinar won’t be online forever. Click the link below before the seats fill up and learn how to become a Python freelancer, guaranteed.
https://tinyurl.com/become-a-python-freelancer

WordPress conversion from plt.subplot.ipynb by nb2wp v0.3.1
Reply

Users browsing this thread:
1 Guest(s)


Forum Jump: