Reputation: 1005
I'm using quite often matplotlibs subplots and i want something like this:
import mumpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(3, 2, figsize=(8, 10), sharey='row',
gridspec_kw={'height_ratios': [1, 2, 2]})
ax[0, :].plot(np.random.randn(128))
ax[1, 0].plot(np.arange(128))
ax[1, 1].plot(1 / (np.arange(128) + 1))
ax[2, 0].plot(np.arange(128) ** (2))
ax[2, 1].plot(np.abs(np.arange(-64, 64)))
I want to create a figure that have for 2 positions a single plot like done for ax1
in this (modified) gridspec example:
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
fig = plt.figure()
gs = GridSpec(3, 3)
ax1 = plt.subplot(gs[0, :])
# identical to ax1 = plt.subplot(gs.new_subplotspec((0, 0), colspan=3))
ax2 = plt.subplot(gs[1, :-1])
ax3 = plt.subplot(gs[1:, -1])
ax4 = plt.subplot(gs[-1, 0])
ax5 = plt.subplot(gs[-1, -2])
fig.suptitle("GridSpec")
plt.show()
see for full example: https://matplotlib.org/gallery/userdemo/demo_gridspec02.html#sphx-glr-gallery-userdemo-demo-gridspec02-py
Since i'm using the subplots environment quite a lot i would know if this is possible too. Also because subplots can handle GridSpec arguments. The pity is that it is not really explained what the exceptions are.
Upvotes: 0
Views: 3442
Reputation: 339765
plt.subplots
provides a convenient way to create a fully populated gridspec.
For example, instead of
fig = plt.figure()
n = 3; m=3
gs = GridSpec(n, m)
axes = []
for i in range(n):
row = []
for j in range(m):
ax = fig.add_subplot(gs[i,j])
row.append(ax)
axes.append(row)
axes = np.array(axes)
you can just write a single line
n = 3; m=3
fig, axes = plt.subplots(ncols=m, nrows=n)
However, if you want the freedom to select which positions on the grid to fill or even to have subplots spanning several rows or columns, plt.subplots
will not help much, because it does not have any options to specify which gridspec locations to occupy.
In that sense the documentation is pretty clear: Since it does not document any arguments that could be used to achieve a non rectilinear grid, there simply is no such option.
Whether to choose to use plt.subplots
or gridspec
is then a question of the desired plot. There might be cases where a combination of the two is still somehow useful, e.g.
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
n=3;m=3
gridspec_kw = dict(height_ratios=[3,2,1])
fig, axes = plt.subplots(ncols=m, nrows=n, gridspec_kw=gridspec_kw)
for ax in axes[1:,2]:
ax.remove()
gs = GridSpec(3, 3, **gridspec_kw)
fig.add_subplot(gs[1:,2])
plt.show()
where a usual grid is defined first and only at the positions where we need a row spanning plot, we remove the axes and create a new one using the gridspec.
Upvotes: 3