Escala la imagen en matplotlib sin cambiar el eje

Tengo una interfaz gráfica de usuario que muestra un gráfico. Quiero ajustar esa ttwig a una imagen existente. Mostré la imagen debajo de la ttwig usando:

myaxe.plot(...) myaxeimage = myaxe.imshow(myimage, axpect='auto', extent=myaxe.axis(), zorder=-1) 

Ya puedo jugar con la opacidad de la imagen, usando

 myaxeimage.set_alpha() 

Ahora me gustaría poder acercar y alejar y desplazarme por la imagen, utilizando la GUI, sin tocar la ttwig y los ejes existentes, para alinearla con mi ttwig. En otras palabras, quiero escalar a factores sx y sy dados, y poner el origen de la imagen en un punto (x,y) dado, recortando partes de la imagen que van fuera de los ejes. ¿Cómo puedo hacer eso?

Hay un ejemplo de marca de agua distribuido con matplotlib que es similar. A partir de ese código, podemos modificarlo de la siguiente manera:

Use ax.imshow para trazar la imagen primero. Hago esto porque el parámetro de extent afecta la extensión final de ax . Puesto que queremos que la extensión final se rija por plt.plot(...) , plt.plot(...) en último lugar.

 myaximage = ax.imshow(im, aspect='auto', extent=(1,15,0.3,0.7), alpha=0.5, origin='upper', zorder=-1) 

En lugar de la extent=myaxe.axis() , use la extent para controlar la posición y el tamaño de la imagen. extent=(1,15,0.3,0.7) coloca la imagen en el rectángulo con (1, 0.3) como la esquina inferior izquierda y (15, 0.7) como la esquina superior derecha.

Con origin='upper' , el índice [0,0] de la matriz im se coloca en la esquina superior izquierda de la extensión. Con origin='lower' se habría colocado en la esquina inferior izquierda.


 import numpy as np import matplotlib.pyplot as plt import matplotlib.cbook as cbook import matplotlib.image as image np.random.seed(1) datafile = cbook.get_sample_data('logo2.png', asfileobj=False) im = image.imread(datafile) fig, ax= plt.subplots() myaximage = ax.imshow(im, aspect='auto', extent=(1,15,0.3,0.7), alpha=0.5, zorder=-1) ax.plot(np.random.rand(20), '-o', ms=20, lw=2, alpha=1.0, mfc='orange') ax.grid() plt.show() 

introduzca la descripción de la imagen aquí


Si desea expandir la imagen y recortarla en la medida del trazado, es posible que necesite usar ax.set_xlim y ax.set_ylim también:

 myaximage = ax.imshow(im, aspect='auto', extent=(-1,25,0.3,0.7), alpha=0.5, zorder=-1, origin='upper') ax.plot(np.random.rand(20), '-o', ms=20, lw=2, alpha=1.0, mfc='orange') ax.set_xlim(0,20) ax.set_ylim(0,1) 

introduzca la descripción de la imagen aquí


O, para tener más control, puede recortar la imagen a una ruta arbitraria utilizando myaximage.set_clip_path :

 import numpy as np import matplotlib.pyplot as plt import matplotlib.cbook as cbook import matplotlib.image as image import matplotlib.patches as patches np.random.seed(1) datafile = cbook.get_sample_data('logo2.png', asfileobj=False) im = image.imread(datafile) fig, ax= plt.subplots() myaximage = ax.imshow(im, aspect='auto', extent=(-5,25,0.3,0.7), alpha=0.5, origin='upper', zorder=-2) # patch = patches.Circle((300,300), radius=100) patch = patches.Polygon([[5, 0.4], [15, 0.4], [15, 0.6], [5, 0.6]], closed=True, transform=ax.transData) myaximage.set_clip_path(patch) ax.plot(np.random.rand(20), '-o', ms=20, lw=2, alpha=1.0, mfc='orange', zorder=-1) ax.set_xlim(0, 20) ax.set_ylim(0, 1) plt.show() 

introduzca la descripción de la imagen aquí

Finalmente, seguí la sugerencia de tcaswell y usé 2 ejes diferentes. De esta manera, simplemente tengo que jugar con set_xlim() y set_ylim() de los ejes de mi imagen para cambiar el origen y / o el factor de zoom de mi imagen. Ordeno obtener la imagen debajo de mi ttwig, sin ocultarla con el marco de la ttwig, quité el marco de la ttwig y usé el marco de los ejes de la imagen. También escondí las garrapatas de los ejes de la imagen.

 from matplotlib import pyplot f = pyplot.figure() a = f.add_subplot(111, frameon=False) # Remove frame a.plot(...) myimg = pyplot.imread(...) imgaxes = f.add_axes(a.get_position(), # new axes with same position label='image', # label to ensure imgaxes is different from a zorder=-1, # put image below the plot xticks=[], yticks=[]) # remove the ticks img = imgaxes.imshow(myimg, aspect='auto') # ensure image takes all the place # now, to modify things img.set_alpha(...) imgaxes.set_xlim((x1, x2)) # x1 and x2 must be calculated from # image size, origin, and zoom factor