Reputation:
I'm hoping to adjust the space between subplots horizontally. Specifically between every second row. I can adjust every row using fig.subplots_adjust(hspace=n)
. But is it possible to apply this to every 2nd row?
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize = (10,10))
plt.style.use('ggplot')
ax.grid(False)
ax1 = plt.subplot2grid((5,2), (0, 0))
ax2 = plt.subplot2grid((5,2), (0, 1))
ax3 = plt.subplot2grid((5,2), (1, 0))
ax4 = plt.subplot2grid((5,2), (1, 1))
ax5 = plt.subplot2grid((5,2), (2, 0))
ax6 = plt.subplot2grid((5,2), (2, 1))
ax7 = plt.subplot2grid((5,2), (3, 0))
ax8 = plt.subplot2grid((5,2), (3, 1))
fig.subplots_adjust(hspace=0.9)
Using the subplots below I'm hoping to add a space between rows 2 and 3 and keep the rest as is.
Upvotes: 9
Views: 7759
Reputation: 61
Here's a solution with getting into tedious low-level hacks:
import matplotlib.pyplot as plt
def tight_pairs(n_cols, fig=None):
"""
Stitch vertical pairs together.
Input:
- n_cols: number of columns in the figure
- fig: figure to be modified. If None, the current figure is used.
Assumptions:
- fig.axes should be ordered top to bottom (ascending row number).
So make sure the subplots have been added in this order.
- The upper-half's first subplot (column 0) should always be present
Effect:
- The spacing between vertical pairs is reduced to zero by moving all lower-half subplots up.
Returns:
- Modified fig
"""
if fig is None:
fig = plt.gcf()
for ax in fig.axes:
if hasattr(ax, 'get_subplotspec'):
ss = ax.get_subplotspec()
row, col = ss.num1 // n_cols, ss.num1 % n_cols
if (row % 2 == 0) and (col == 0): # upper-half row (first subplot)
y0_upper = ss.get_position(fig).y0
elif (row % 2 == 1): # lower-half row (all subplots)
x0_low, _ , width_low, height_low = ss.get_position(fig).bounds
ax.set_position(pos=[x0_low, y0_upper - height_low, width_low, height_low])
return fig
Here's a test for above function:
def test_tight_pairs():
def make_template(title):
fig = plt.figure(figsize=(8, 6))
for i in range(12):
plt.subplot(6, 2, i+1)
plt.plot([0,1], [0,1][::-1 if i%2==1 else 1])
fig.suptitle(title)
return fig
make_template("The vertical spacing should have increased (disappeared) between (within) pairs.")
tight_pairs(2)
make_template("Default spacing.")
plt.show()
test_tight_pairs()
y0_upper - height_low - padding
, ory0_upper - height_low - p * height_low
Upvotes: 1
Reputation: 2656
Without going to tedious low-level hacks like adjusting the position of the axes manually, I would suggest using a grid but just leaving some of the rows blank.
I tried this:
import matplotlib.pyplot as plt
plt.figure(figsize=(10., 10.))
num_rows = 6
num_cols = 2
row_height = 3
space_height = 2
num_sep_rows = lambda x: int((x-1)/2)
grid = (row_height*num_rows + space_height*num_sep_rows(num_rows), num_cols)
ax_list = []
for ind_row in range(num_rows):
for ind_col in range(num_cols):
grid_row = row_height*ind_row + space_height*num_sep_rows(ind_row+1)
grid_col = ind_col
ax_list += [plt.subplot2grid(grid, (grid_row, grid_col), rowspan=row_height)]
plt.subplots_adjust(bottom=.05, top=.95, hspace=.1)
# plot stuff
ax_list[0].plot([0, 1])
ax_list[1].plot([1, 0])
# ...
ax_list[11].plot([0, 1, 4], c='C2')
which gives this result:
Note that you can change the number of rows; also, you can adjust the size of the blank space compared to the subplots by tweaking the row_height
/space_height
ratio (both must be integers).
Upvotes: 5
Reputation: 339340
You may interlace two grids such that there is a larger spacing between every second subplot.
To illustrate the concept:
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
n = 3 # number of double-rows
m = 2 # number of columns
t = 0.9 # 1-t == top space
b = 0.1 # bottom space (both in figure coordinates)
msp = 0.1 # minor spacing
sp = 0.5 # major spacing
offs=(1+msp)*(t-b)/(2*n+n*msp+(n-1)*sp) # grid offset
hspace = sp+msp+1 #height space per grid
gso = GridSpec(n,m, bottom=b+offs, top=t, hspace=hspace)
gse = GridSpec(n,m, bottom=b, top=t-offs, hspace=hspace)
fig = plt.figure()
axes = []
for i in range(n*m):
axes.append(fig.add_subplot(gso[i]))
axes.append(fig.add_subplot(gse[i]))
plt.show()
Upvotes: 9