es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Ejes compartidos de matplotlib para imágenes con tamaños diferentes (Aproximación y desplazamiento vinculados)

Tengo dos imágenes que muestro con la función imshow() de matplotlib. Las imágenes están relacionadas entre sí, por lo que deberían comportarse de la misma manera al hacer zoom o moverse. Esto funciona bien cuando tienen la misma resolución. Pero cuando su resolución difiere, compartir los ejes funciona de una manera (para mí) no intencionada.
Digamos que estas son mis dos imágenes, una gaussiana bidimensional, una vez con una resolución de 600×400 y otra vez con una resolución de 300×200.
[aquí inserte los enlaces e imágenes]
Cuando comparto los ejes, esto sucede:
[aquí inserte los enlaces e imágenes]

Sin embargo, quiero que la salida sea como en el primer caso, pero cuando haga zoom o me mueva, la segunda imagen debería manipularse de acuerdo. De esta manera, quiero poder obtener salidas como esta:
[aquí inserte los enlaces e imágenes]
Sé que estos ejes no están realmente compartidos, pero deberían aparecer como si lo estuvieran.

Intenté configurar ejes gemelos (con escala dividida por la mitad) pero esto no tuvo mucho éxito en cuanto a mi problema.

Código para reproducir las imágenes adjuntas y jugar con ellas:

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

w, h = 600, 400 # ancho y alto de la resolución original
x, y = np.meshgrid(np.arange(w), np.arange(h))

gaussiana = np.exp(-(np.sqrt((x – w/2) ** 2 + (y – h/2) ** 2) ** 2 / (2.0 * 100 ** 2))) # 600×400
muestreada = zoom(gaussiana, 0.5) # 300×200

ax_grande = plt.subplot2grid((1, 2), (0, 0))
ax_grande.imshow(gaussiana, cmap=’turbo’)

ax_pequeño = plt.subplot2grid((1, 2), (0, 1))

Quiero algo como esto:

ax_pequeño = plt.subplot2grid((1, 2), (0, 1), sharex=ax_grande, sharey=ax_grande)

ax_pequeño.imshow(muestreada, cmap=’turbo’)

plt.tight_layout()
plt.show()

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para lograr el resultado deseado, puedes crear una función de devolución de llamada personalizada para realizar el zoom y el desplazamiento que ajuste el alcance de ambas imágenes en función del nivel de zoom de la primera imagen. Puedes utilizar las propiedades xlim e ylim de la primera imagen para calcular el nuevo alcance de la segunda imagen.

    Aquí tienes un código de ejemplo que demuestra este enfoque:

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.ndimage import zoom
    
    
    def on_xlims_change(ax):
        # Ajustar el alcance de la segunda imagen en función del nivel de zoom de la primera imagen
        ax2.set_xlim(ax.get_xlim())
        ax2.set_ylim(ax.get_ylim())
    
    
    w, h = 600, 400  # anchura y altura de la resolución original
    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
    
    fig, ax1 = plt.subplots(1, 1)
    ax1.imshow(gaussian, cmap='turbo')
    
    ax2 = plt.axes([0.55, 0.17, 0.3, 0.3])  # Crear nuevos ejes para la segunda imagen
    ax2.imshow(downsampled, cmap='turbo')
    
    ax1.callbacks.connect('xlim_changed', on_xlims_change)  # Conectar la función de devolución de llamada a la primera imagen
    
    plt.tight_layout()
    plt.show()
    

    En este ejemplo, creamos nuevos ejes para la segunda imagen usando plt.axes(). Luego, conectamos la función on_xlims_change() al evento xlim_changed de la primera imagen usando ax1.callbacks.connect(). Esta función actualiza las propiedades xlim e ylim de la segunda imagen en función del nivel de zoom de la primera imagen. Por último, utilizamos plt.tight_layout() para ajustar el espaciado entre las dos imágenes.

    Con este enfoque, ambas imágenes parecen compartir los mismos ejes al hacer zoom o desplazarse en la primera imagen, mientras que la segunda imagen se muestra todavía a su resolución nativa.

Comments are closed.