Scale image in matplotlib without changing axis

I have a graphical interface that displays a graph. I want to fit this plot to an existing image. I displayed the image under the plot using:

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

I can already play with the opacity of the image using

 myaxeimage.set_alpha() 

Now I would like to be able to zoom in and out of the image and move around the image using the graphical interface, without touching the existing graph and axes, in order to align it with my plot. In other words, I want to scale to the given coefficients sx and sy , and also put the beginning of the image at the given point (x,y) , cutting off parts of the image that go beyond the axes. How can i do this?

+6
source share
2 answers

Finally, I followed the tcaswell suggestion and used two different axes. Thus, I just need to play with set_xlim() and set_ylim() my image axes to change the initial and / or scale factor of my image. I order to get the image below my plot, without hiding it with the plot frame, I removed the plot frame and instead used the frame of the image axes. I also hid ticks from the image axes.

 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 
0
source

There is an example of a watermark distributed with matplotlib, which is similar. Starting with this code, we can change as follows:

Use ax.imshow to build the image first. I do this because the extent parameter affects the final degree of ax . Since we want the final degree to be determined using plt.plot(...) , we will return it last.

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

Instead of extent=myaxe.axis() use extent to control the position and size of the image. extent=(1,15,0.3,0.7) places the image in a rectangle with (1, 0.3) as the lower left corner and (15, 0.7) in the upper right corner.

With origin='upper' index [0,0] the im array is placed in the upper left corner. Using origin='lower' it was placed in the lower left corner.


 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() 

enter image description here


If you want to expand the image and copy it within the area, you may also need to use ax.set_xlim and ax.set_ylim :

 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) 

enter image description here


Or, for more control, you can copy the image to an arbitrary path using 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() 

enter image description here

+6
source

Source: https://habr.com/ru/post/945800/