How to fit arbitrary images into subplots without changing alignment in matplotlib?

45 Views Asked by At

I have a code

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec


def format_axes(fig):
    for i, ax in enumerate(fig.axes):
        ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")
        ax.tick_params(labelbottom=False, labelleft=False)


# gridspec inside gridspec
fig = plt.figure()

gs0 = gridspec.GridSpec(2, 2, figure=fig)

gs00 = gs0[0,0].subgridspec(2, 3, wspace=0)

ax1 = fig.add_subplot(gs00[:, :-1])
ax2 = fig.add_subplot(gs00[0, -1])


gs01 = gs0[0,1].subgridspec(2, 3, wspace=0)

ax3 = fig.add_subplot(gs01[:, :-1])
ax4 = fig.add_subplot(gs01[0, -1])

gs10 = gs0[1,0].subgridspec(1, 1)

ax5 = fig.add_subplot(gs10[0, 0])

gs11 = gs0[1,1].subgridspec(1, 1)

ax6 = fig.add_subplot(gs11[0, 0])

format_axes(fig)


for ax in fig.axes:
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)


plt.tight_layout()
plt.show()

that gives a draft of the figure.
And I need to fill these subplots with arbitrary shaped images, like this

img1 = np.random.rand(10, 20)
img2 = np.random.rand(15, 25)
img3 = np.random.rand(20, 30)
img4 = np.random.rand(25, 35)
img5 = np.random.rand(30, 40)
img6 = np.random.rand(35, 45)

ax1.imshow(img1)
ax2.imshow(img2)
ax3.imshow(img3)
ax4.imshow(img4)
ax5.imshow(img5)
ax6.imshow(img6)

but it changes positions of subplots and their aspect ratios (here). I also need to keep aspect ratio for images.
How can I plot it and keep the alignment and aspect ratios?

I tried to extend my images manually so they have the same aspect ratio as subplots in draft figure. In my view it could solve the problem with alignment. But I didn't succeed in extracting these aspect ratios.

1

There are 1 best solutions below

1
Suraj Shourie On

IIUC you need to specify the aspect argument in your call, by either using axis.set_aspect or by explicitly setting the aspect in your ax.imshow.

ax1.imshow(img1, aspect='auto')
ax2.imshow(img2, aspect='auto')
ax3.imshow(img3, aspect='auto')
ax4.imshow(img4, aspect='auto')
ax5.imshow(img5, aspect='auto')
ax6.imshow(img6, aspect='auto')
plt.show()

Output: enter image description here