Images share both x- and y-axes

WBOY
Release: 2024-02-09 22:45:04
forward
819 people have browsed it

Images share both x- and y-axes

Question content

I have an image displayed using imshow. Then I add all rows and display the maximum value. I do the same thing with the columns. In the display graph, I want the x-axis and y-axis of the image to coincide with the x-axis of the added columns and the y-axis of the added rows. However, despite setting sharex and sharey respectively, it doesn't seem to work. I wish I could only do one at a time:

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import argrelextrema
import matplotlib.animation as animation

fig=        plt.figure()
gs=         fig.add_gridspec(2,2, height_ratios=[1, 0.1], width_ratios=[1, 0.1], hspace=0, wspace=0)
ax1=        fig.add_subplot(gs[0,0])
ax2=        fig.add_subplot(gs[1,0], sharex=ax1)
ax3=        fig.add_subplot(gs[0,1], sharey=ax1)
frameNumber= 10
imgs=   []

for i in range(frameNumber):
    np.random.seed(i)
    randomImage= np.random.random((5,5))
    sumX=   np.sum(randomImage, axis=0)
    sumY=   np.sum(randomImage, axis=1)
    dataRange=  np.arange(len(sumX))
    randomDataSet=  np.random.random((10))
    randomMaximalX= argrelextrema(sumX, np.greater)
    randomMaximalY= argrelextrema(sumY, np.greater)

    img1=   ax1.imshow(randomImage, animated=True)
    img2=   ax2.plot(dataRange, sumX,animated=True)[0]
    img3=   ax3.plot(sumY,dataRange,animated=True)[0]
    img4=   ax2.vlines(x=randomMaximalX, ymin=0, ymax=5, animated=True, linestyles="dashed")
    img5=   ax3.hlines(y=randomMaximalY, xmin=0, xmax=5, animated=True, linestyles="dashed")
    imgs.append([img1, img2, img3, img4, img5])
ani=    animation.ArtistAnimation(fig, imgs, interval=1000, blit=False)
plt.show()
Copy after login

The current result is this:

Actually I want something like this:

The h values ​​of the two graphs are the same. Thank you so much!


Correct answer


There are two ways to solve this problem:

  1. Use axes.pcolormesh instead of axes.imshow
  2. Or update the aspect ratio of adjacent images.

① axis.pcolormesh

axes.pcolormesh does not force the resulting image to be square (1:1 aspect ratio), so your cells will be rectangular, but they will fill the space provided appropriately.

from numpy.random import default_rng
import matplotlib.pyplot as plt

rng = default_rng(0)
image = rng.uniform(1, 10, size=(5, 5))

mosaic = [
    ['main',   'right'],
    ['bottom', '.'    ],
]

fig, axd = plt.subplot_mosaic(
    mosaic,
    gridspec_kw={
        'height_ratios': [1, .1], 'width_ratios': [1, .1],
        'wspace': .05, 'hspace': .05,
    },
    sharex=true,
    sharey=true,
)

axd['main'].pcolormesh(image)

plt.show()
Copy after login

② Update

If you want to stick with axes.imshow then you need to adjust Manually adjust the aspect ratio of each plot. To get the correct ratio you need Calculated based on height_ratio and width_ratio provided to gridspec

from numpy.random import default_rng
import matplotlib.pyplot as plt

rng = default_rng(0)
image = rng.uniform(1, 10, size=(5, 5))

mosaic = [
    ['main',   'right'],
    ['bottom', '.'    ],
]

fig, axd = plt.subplot_mosaic(
    mosaic,
    sharex=True,
    sharey=True,
    gridspec_kw={
        'height_ratios': [1, .1], 'width_ratios': [1, .1],

        # change values to move adjacent plots closer to the main
        'wspace': .05, 'hspace': .05,
    },
)

axd['main'].imshow(image)
axd['main'].set_anchor('SE') # move main plot to bottom-right of bounding-box

# calculate the width and height scales
gs = axd['main'].get_gridspec() # you can also save these values from your `gridspec_kw`
width_scale = gs.get_width_ratios()[0]    / gs.get_width_ratios()[1]
height_scale = gs.get_height_ratios()[0]  / gs.get_height_ratios()[1]

# update the aspect ratios of the adjacent plots
#   set their anchors so they correctly align with the main plot
axd['right'].set_aspect(width_scale, anchor='SW')
axd['bottom'].set_aspect(1/height_scale, anchor='NE')

plt.show()
Copy after login

The above is the detailed content of Images share both x- and y-axes. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!