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\n{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:\Users\Surpass\Documents\PycharmProjects\a.jpg",r"C:\Users\Surpass\Documents\PycharmProjects\b.jpg" ]
viewImg=ViewImg(imgPath)
viewImg.viewImage()
参考网址:
作者: Surpassme
来源: http://www.jianshu.com/u/28161b7c9995/
http://www.cnblogs.com/surpassme/
声明:本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接 ,否则保留追究法律责任的权利。如有问题,可发送邮件 联系。让我们尊重原创者版权,共同营造良好的IT朋友圈。
分类:
Python
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现