我试图使用matplotlib编写一个程序,在缩放plt.figure对象上显示的图像后,当我进行鼠标“单击并拖动”移动时,显示部分将向我的拖动方向移动,以便通过设置x/y限制可以看到缩放图像的不同部分
我知道最简单的方法是在重置x/y限制后使用canvas.draw()函数,如下所示
ax.set_xlim([x1,x2])
ax.set_ylim([y1,y2])
ax.figure.canvas.draw()
但在我的正式程序中,图形上不仅会有图像,还会有很多其他对象,如文本或线条,如果我使用canvas.draw(),它会重新绘制所有对象,包括那些完全不变的对象,并会严重损害程序的性能。为了使用最少的资源来执行拖动功能,我决定使用“blit”函数,下面是我的玩具示例
import matplotlib.pyplot as plt
class toy(object):
def dragstart(self, event):
# 'button_press_event'
if not event.inaxes:
return
if event.button == 1:
self.dragstate = 'move'
x, y = event.xdata, event.ydata
self.mouseloc = [x, y]
def dragstop(self, event):
# 'button_release_event'
if event.button == 1:
self.dragstate = 'stop'
def drag(self, event):
#Prevent multiple event happening
if self.dragprocessing:
return
self.dragprocessing = True
if not event.inaxes or self.dragstate != 'move':
self.dragprocessing = False
return
#Calculate the displacement
xloc, yloc = event.xdata, event.ydata
xdelta = -(xloc - self.mouseloc[0])
ydelta = -(yloc - self.mouseloc[1])
self.mouseloc = [xloc, yloc]
newxleft = self.last[0] + xdelta
newxright = self.last[1] + xdelta
newyup = self.last[2] + ydelta
newydown = self.last[3] + ydelta
#Border check
if newxright > self.limit[0] - 0.5:
over = newxright - (self.limit[0] - 0.5)
newxright = self.limit[0] - 0.5
newxleft -= over
if newxleft < -0.5:
over = -0.5 - newxleft
newxleft = -0.5
newxright += over
if newydown > self.limit[1] - 0.5:
over = newydown - (self.limit[1] - 0.5)
newydown = self.limit[1] - 0.5
newyup -= over
if newyup < -0.5:
over = -0.5 - newyup
newyup = -0.5
newydown += over
newposition = [newxleft, newxright, newyup, newydown]
#Set new limit
self.ax.set_xlim([newxleft, newxright])
self. ax.set_ylim([newydown, newyup])
#Only draw the changing part
#The formal project contents lots of other objects such as text or line, redraw everything will be slow
self.ax.draw_artist(self.ax.images[0])
self.ax.draw_artist(self.ax.yaxis)
self.ax.draw_artist(self.ax.xaxis)
self.ax.figure.canvas.blit()
self.last = newposition
self.mouseloc = [xloc + xdelta, yloc + ydelta]
self.dragprocessing = False
def __call__(self, images):
fig, ax = plt.subplots()
ax.imshow(images)
h = images.shape[0]
w = images.shape[1]
self.limit = [w, h]
ax.set_ylim([400, 200])#just an example
ax.set_xlim([200, 400])#just an example
self.dragprocessing = False
self.last = [200, 400, 200, 400]#present x/y limit
self.dragstate = 'stop'
self.ax=ax
self.fig=fig
fig.canvas.mpl_connect('button_press_event', self.dragstart)
fig.canvas.mpl_connect('button_release_event', self.dragstop)
fig.canvas.mpl_connect('motion_notify_event', self.drag)
plt.show()
imagenow = plt.imread("path/to/my/image")
test=toy()
test(imagenow)
请注意,我使用“self.ax.figure.canvas.blit()”而不是“self.ax.figure.canvas.blit(self.ax.bbox)”,因为后者不会更新轴上的任何内容。
问题是,每次更新x/y限制时,x/y轴的杆都会覆盖,如下所示
在我的玩具“blit”示例中是否存在导致问题的任何误用?如何修复它,或者有没有更好的方法来完成这项工作
目前没有回答
相关问题 更多 >
编程相关推荐