How to make an axes occupy multiple subplots with pyplot (Python)

PythonMatplotlib

Python Problem Overview


I would like to have three plots in single figure. The figure should have a subplot layout of two by two, where the first plot should occupy the first two subplot cells (i.e. the whole first row of plot cells) and the other plots should be positioned underneath the first one in cells 3 and 4. I know that matlab allows this by using the subplot command like so

subplot(2,2,[1,2]) % the plot will span subplots 1 and 2

Is it also possible in pyplot to have a single axes occupy more than one subplot? The docstring of pyplot.subplot doesn't talk about it.

Anyone got an easy solution? Thanks in advance

Python Solutions


Solution 1 - Python

You can simply do:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 7, 0.01)
    
plt.subplot(2, 1, 1)
plt.plot(x, np.sin(x))
    
plt.subplot(2, 2, 3)
plt.plot(x, np.cos(x))
    
plt.subplot(2, 2, 4)
plt.plot(x, np.sin(x)*np.cos(x))

i.e., the first plot is really a plot in the upper half (the figure is only divided into 2x1 = 2 cells), and the following two smaller plots are done in a 2x2=4 cell grid. The third argument to subplot() is the position of the plot inside the grid (in the direction of reading in English, with cell 1 being in the top-left corner): for example in the second subplot (subplot(2, 2, 3)), the axes will go to the third section of the 2x2 matrix i.e, to the bottom-left corner.

enter image description here

Solution 2 - Python

To have multiple subplots with an axis occupy, you can simply do:

from matplotlib import pyplot as plt
import numpy as np
    
b=np.linspace(-np.pi, np.pi, 100)

a1=np.sin(b)

a2=np.cos(b)

a3=a1*a2

plt.subplot(221)
plt.plot(b, a1)
plt.title('sin(x)')

plt.subplot(222)
plt.plot(b, a2)
plt.title('cos(x)')

plt.subplot(212)
plt.plot(b, a3)
plt.title('sin(x)*cos(x)')

plt.show()

enter image description here

Another way is

plt.subplot(222)
plt.plot(b, a1)
plt.title('sin(x)')

plt.subplot(224)
plt.plot(b, a2)
plt.title('cos(x)')

plt.subplot(121)
plt.plot(b, a3)
plt.title('sin(x)*cos(x)')

plt.show()

enter image description here

Solution 3 - Python

The Using Gridspec to make multi-column/row subplot layouts shows a way to do this with GridSpec. A simplified version of the example with 3 subplots would look like

import matplotlib.pyplot as plt

fig = plt.figure()

gs = fig.add_gridspec(2,2)
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, :])

plt.show()

enter image description here

Solution 4 - Python

For finer-grained control you might want to use the subplot2grid module of matplotlib.pyplot.

http://matplotlib.org/users/gridspec.html

Solution 5 - Python

A more modern answer would be: Simplest is probably to use subplots_mosaic: https://matplotlib.org/stable/tutorials/provisional/mosaic.html

import matplotlib.pyplot as plt
import numpy as np

# Some example data to display
x = np.linspace(0, 2 * np.pi, 400)
y = np.sin(x ** 2)

fig, axd = plt.subplot_mosaic([['left', 'right'],['bottom', 'bottom']],
                              constrained_layout=True)
axd['left'].plot(x, y, 'C0')
axd['right'].plot(x, y, 'C1')
axd['bottom'].plot(x, y, 'C2')
plt.show()

Example w/ subplot_mosaic

Solution 6 - Python

There are three main options in matplotlib to make separate plots within a figure:

  1. subplot: access the axes array and add subplots
  2. gridspec: control the geometric properties of the underlying figure (demo)
  3. subplots: wraps the first two in a convenient api (demo)

The posts so far have addressed the first two options, but they have not mentioned the third, which is the more modern approach and is based on the first two options. See the specific docs Combining two subplots using subplots and GridSpec.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSvenView Question on Stackoverflow
Solution 1 - PythonEric O LebigotView Answer on Stackoverflow
Solution 2 - PythonHooshmand zandiView Answer on Stackoverflow
Solution 3 - PythonImportanceOfBeingErnestView Answer on Stackoverflow
Solution 4 - PythonA.WanView Answer on Stackoverflow
Solution 5 - PythonJody KlymakView Answer on Stackoverflow
Solution 6 - PythonpylangView Answer on Stackoverflow