Я пытаюсь использовать matplotlib для написания программы, которая после масштабирования изображения, отображаемого на объекте plt.figure, когда я выполняю движение "щелчок и перетаскивание мышью", отображающая часть будет двигаться в направлении моего перетаскивания, поэтому я могу увидеть другую часть изображения с помощью установки предела x / y.
Я знаю, что самый простой способ - использовать функцию canvas.draw () после сброса предела x / y, например
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", который вызывает проблему? Как это исправить или есть лучший способ сделать работу?