When using gridspecs, I find it difficult to align different nested gridspecs. I often use gridspecs for figures where most or all subplots have a fixed aspect ratio (e.g., to display images).
A minimal example would be the following plot, where two square images are displayed next to 4 smaller images in a nested subplot:
import matplotlib.pyplot as plt
import numpy as np
n_cols = 3
fig = plt.figure(1, figsize=(6, 6 / n_cols * 1.5))
gs = fig.add_gridspec(1, n_cols)
test_img = np.ones((64, 64, 3)) * np.linspace(0.3, 1, 64)[:, None] # simple, square test image
for col in range(n_cols - 1):
ax = fig.add_subplot(gs[col])
ax.imshow(test_img)
gs_sub = gs[-1].subgridspec(2, 2, wspace=0.02, hspace=0.02)
for i in range(4):
ax = fig.add_subplot(gs_sub[i])
ax.imshow(test_img)
# use tight layout to remove excess white space
gs.tight_layout(fig, rect=[0, 0, 1, 1], pad=0.001)
gs.update(wspace=0.025, hspace=0.0)
This results in the following plot:
As you can see, the smaller images vertically use more space than the larger ones. I guess the nested gridspec tries to use all the available space, and is in no way restricted to match the two larger images on the left. On the other hand, it all aligns fine for plots with a flexible aspect ratio (e.g., line plots), as then the aspect ratio of the subplots stretches automatically:
(don't mind the overlapping axis ticks, it's easy to add more space if needed).
I can also oftentimes get things to work out okay by scaling the height of the plot or even playing with height/width ratios. In the above plot, the result can be improved by removing the arbitrary scale factor "1.5" that is applied to the plot height. However, this isn't a good solution as it often requires a lot of manual experimentation and is rarely perfect (especially for more complex layouts).
Are there better ways of doing this? Is there a way to inform the nested gridspec of the desired alignment? Ideally, I would want to control the nested gridspec to match the height of the other subplots, rather than using up all the available space.