matplotlib implements the display of two pictures on the same page, and zooms and drags the pictures separately

The requirements are as follows:

  • 1. Show two pictures in one page
  • 2. You can use the mouse to drag their own pictures into the page without affecting each other
  • 3. After entering the page, you can use the mouse wheel to enlarge or reduce the pictures, which are not affected by each other. That is to say, when you move the mouse over picture A, you can enlarge or reduce picture A, picture B is not affected, and vice versa
  • 4. Drag demand is the same as 3

Implementation code:

import matplotlib.pyplot as plt
from PIL import Image
import numpy as np

class Scale:
    def __init__(self,fig,base_scale=1.5):
        self.fig=fig
        self.base_scale=base_scale
        self.x0 = None
        self.y0 = None
        self.x1 = None
        self.y1 = None
        self.xpress = None
        self.ypress = None
        self.cur_xlim = None
        self.cur_ylim = None
        self.press = None
        self.fig.canvas.mpl_connect('scroll_event', self.enter_axes)
        self.fig.canvas.mpl_connect("button_press_event", self.enter_axes)
        self.fig.canvas.mpl_connect('button_press_event',self.onPress)
        self.fig.canvas.mpl_connect('button_release_event',self.onRelease)
        self.fig.canvas.mpl_connect('motion_notify_event',self.onMotion)

    def enter_axes(self,event):
        # print(f"enter axes {event.inaxes}")
        axtemp = event.inaxes
        self.cur_xlim=axtemp.get_xlim()
        self.cur_ylim=axtemp.get_ylim()
        # print(f"x {self.cur_xlim} y {self.cur_ylim}")
        xdata=event.xdata
        ydata=event.ydata

        if event.button == "up":
           scale_factor=1/self.base_scale
        elif event.button == "down":
           scale_factor=self.base_scale
        else:
            scale_factor=1

        new_width = (self.cur_xlim[1] - self.cur_xlim[0]) * scale_factor
        new_height = (self.cur_ylim[1] - self.cur_ylim[0]) * scale_factor

        relx = (self.cur_xlim[1] - xdata) / (self.cur_xlim[1] - self.cur_xlim[0])
        rely = (self.cur_ylim[1] - ydata) / (self.cur_ylim[1] - self.cur_ylim[0])

        axtemp.set_xlim([xdata - new_width * (1 - relx), xdata + new_width * (relx)])
        axtemp.set_ylim([ydata - new_height * (1 - rely), ydata + new_height * (rely)])

        self.fig.canvas.draw_idle()

    def onPress(self,event):
        axtemp = event.inaxes
        if event.inaxes != axtemp:
            return
        self.cur_xlim = axtemp.get_xlim()
        self.cur_ylim = axtemp.get_ylim()
        self.press = self.x0, self.y0, event.xdata, event.ydata
        self.x0, self.y0, self.xpress, self.ypress = self.press

    def onMotion(self,event):
        if self.press is None:
            return
        if event.inaxes != event.inaxes:
            return
        dx = event.xdata - self.xpress
        dy = event.ydata - self.ypress
        self.cur_xlim -= dx
        self.cur_ylim -= dy
        event.inaxes.set_xlim(self.cur_xlim)
        event.inaxes.set_ylim(self.cur_ylim)

    def onRelease(self,event):
        self.press = None
        event.inaxes.figure.canvas.draw_idle()

class ViewImg:

    def __init__(self,imgPath):
        self.imgPath=imgPath

    def viewImage(self):
        try:
            img1=Image.open(self.imgPath[0])
            img2=Image.open(self.imgPath[1])
            imgList=[]

            for item in [img1,img2]:
                if item == img1:
                    scale=2000/item.size[0]
                    print(f"img1:{item},{scale}")
                elif item == img2:
                    scale=3000/item.size[0]
                    print(f"img2:{item},{scale}")
                width=int(item.size[0]*scale)
                height=int(item.size[1]*scale)
                print(f"(width,height):{(width,height)}")
                item=item.resize((width,height),Image.ANTIALIAS)
                item=np.array(item)
                imgList.append(item)

            if len(imgList)==2:
                img1,img2=imgList
            else:
                print(f"Error reading number of pictures,{len(imgList)}")
                return
        except Exception as ex:
            print(f"view image error\n{ex}")
            return
        else:
            # Set parameters before window maximization
            plt.switch_backend("QT5Agg")
            fig=plt.figure("Chromosome and cell diagram")
            # Add 1 row, 2 columns and the first child
            ax1=fig.add_subplot(1,2,1)
            # Show only axes, but not tick marks
            plt.xticks([])
            plt.yticks([])
            # display picture
            plt.imshow(img1, aspect="auto")
            plt.axis('on')
            # Add 1 row, 2 columns and the second child
            ax2=fig.add_subplot(1, 2, 2)
            # Add auto layout
            plt.tight_layout()
            plt.xticks([])
            plt.yticks([])
            plt.imshow(img2, aspect="auto")
            plt.axis('on')
            # Adjust the spacing between the four sides and the subgraph
            plt.subplots_adjust(left=0.005,right=0.995,bottom=0.005,top=0.995,wspace=0.010,hspace=0.1)
            # Set maximization
            plt.get_current_fig_manager().window.showMaximized()
            ax1.set_title("dna")
            ax2.set_title("cell")
            scale=Scale(fig)
            plt.show()

if __name__ == '__main__':
    imgPath=[r"C:\Users\Surpass\Documents\PycharmProjects\a.jpg",r"C:\Users\Surpass\Documents\PycharmProjects\b.jpg" ]
    viewImg=ViewImg(imgPath)
    viewImg.viewImage()

Reference website:

Tags: Python

Posted on Sun, 03 May 2020 21:57:01 -0700 by RazorICE