Gnnr
Gnnr

Reputation: 148

Shared matplotlib axes for images with different sizes (Linked zooming and panning)

I have two images that I display with matplotlib's imshow(). The images are related to each other, so they should behave in the same way when zooming or panning. This works fine when they have the same resolution. But when their resolution differs, sharing the axes works in a (for me) unintended way. Let's say these are my two images, a two-dimensional Gaussian, once in a 600x400 and once in a 300x200 resolution. My two images When I share the axes, this happens: With shared axes

However, I want the output to be like in the first case, but when zooming or panning, the second image should be manipulated accordingly. Like this, I want to be able to get outputs like this: Exemplary desired output I know that these axes are not really shared, but they should appear like it.

I tried setting up twin axes (with halved scale) but this was not very successful in regards to my problem.

Code to reproduce the images I attached and play around:

import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import zoom

w, h = 600, 400  # original resolution width & height
x, y = np.meshgrid(np.arange(w), np.arange(h))

gaussian = np.exp(-(np.sqrt((x - w/2) ** 2 + (y - h/2) ** 2) ** 2 / (2.0 * 100 ** 2)))  # 600x400
downsampled = zoom(gaussian, 0.5)  # 300x200

ax_big = plt.subplot2grid((1, 2), (0, 0))
ax_big.imshow(gaussian, cmap='turbo')

ax_small = plt.subplot2grid((1, 2), (0, 1))
# I want something like this:
# ax_small = plt.subplot2grid((1, 2), (0, 1), sharex=ax_big, sharey=ax_big)
ax_small.imshow(downsampled, cmap='turbo')

plt.tight_layout()
plt.show()

Upvotes: 0

Views: 253

Answers (1)

hexahedronest
hexahedronest

Reputation: 198

If you don't necessarily need the axes of the subsampled image to display the subsampled width/height, but just the region that matches your zoom/translation (which I'm not completely sure of from your question), you could use the extent parameter in the ax_small.imshow() call. This specifies the effective rectangle in axes space where the image will displayed. By default, this is simply the size in pixels of the image, but you can set the size to be equal to the size of the fully sampled image.

Have a look at the documentation for imshow for more information.

...

# I want something like this:
ax_small = plt.subplot2grid((1, 2), (0, 1), sharex=ax_big, sharey=ax_big)
ax_small.imshow(downsampled, cmap='turbo', extent=[0, w, 0, h])

...

I've included a picture of the result below. As you can see, the subsampled image is essentially stretched over a larger region.

enter image description here

Upvotes: 1

Related Questions