• matplotlib实现同一页面显示两张图片且单独缩放和拖动各自的图片


    需求如下:

    • 1、在一个页面中显示两张图片
    • 2、进入页面可以使用鼠标拖动各自的图片,相互不受影响
    • 3、进入页面后可以使用鼠标滚轮放大或缩小图片,相互不受影响,即鼠标移动到图片A上,可对图片A进行放大或缩小,图片B不受影响,反之亦然
    • 4、拖动需求同3

    实现代码:

    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"读取图片数量出错,{len(imgList)}")
                    return
            except Exception as ex:
                print(f"view image error
    {ex}")
                return
            else:
                # 设置窗口最大化前参数
                plt.switch_backend("QT5Agg")
                fig=plt.figure("染色体图和细胞图")
                # 添加1行2列格子并添加第一个子格
                ax1=fig.add_subplot(1,2,1)
                # 仅显示坐标轴,但不显示刻度线
                plt.xticks([])
                plt.yticks([])
                # 显示图片
                plt.imshow(img1, aspect="auto")
                plt.axis('on')
                # 添加1行2列格子并添加第二个子格
                ax2=fig.add_subplot(1, 2, 2)
                # 添加自动布局
                plt.tight_layout()
                plt.xticks([])
                plt.yticks([])
                plt.imshow(img2, aspect="auto")
                plt.axis('on')
                # 调整四周和子图之间的间距
                plt.subplots_adjust(left=0.005,right=0.995,bottom=0.005,top=0.995,wspace=0.010,hspace=0.1)
                # 设置最大化
                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:UsersSurpassDocumentsPycharmProjectsa.jpg",r"C:UsersSurpassDocumentsPycharmProjects.jpg" ]
        viewImg=ViewImg(imgPath)
        viewImg.viewImage()
    

    参考网址:

  • 相关阅读:
    echo e 在SHELL脚本和命令行中表现不同一例问题排查
    Linux 中修改网卡名称【ubuntu + Centos7】
    ESXI上实施ORACLE 10G RAC+LINUX+ASM
    Linux crontab下关于使用date命令的坑
    SkiaSharp跨平台绘图研究1WPF桌面应用
    编译原理 实验一 词法分析
    计算机组成原理(上)_第一章测试题
    计算机组成原理(上)_第三章测试题
    SQL Server 2017 下载及安装详细教程
    计算机组成原理(上)_第四章测试题(上)
  • 原文地址:https://www.cnblogs.com/surpassme/p/12823286.html
Copyright © 2020-2023  润新知