快速更新图中的单个点
问题内容:
我有一个matplotlib图,其中有多个图。一个图像中包含很多点。第二个轴有一个轴,我想在其中以快速更新来更新点位置。
下面的代码片段经过精简,可以有效地显示我想要执行的操作。当我在ax_large
图上移动鼠标时,我希望它能很快更新。
我在SO和其他地方找到了许多示例,并尝试了一些不同的选择。但是似乎没有一个人完全正确(或至少如我希望/期望的那样,所以也许我的期望需要改变)。
编码:
class Test:
def __init__(self):
self.fig = plt.figure(1)
# Axis with large plot
self.ax_large = plt.subplot(121)
self.ax_large.imshow(np.random.random((5000,5000)))
# Follow the point
self.ax = plt.subplot(122)
self.ax.grid('on')
self.fig.canvas.callbacks.connect('motion_notify_event', self.callback)
self.point = self.ax.plot(0,0, 'go')
plt.show()
def callback(self, event):
if event.inaxes == self.ax:
print('Updating to {} {}'.format(event.xdata, event.ydata))
self.point[0].set_data(event.xdata, event.ydata)
# Option 1. Works, bu super slow if there are other large sub-plots
plt.draw()
# Option 2. Doesn't update
# self.fig.canvas.blit(self.ax.bbox)
# Option 3. Works but then grid goes away
# self.ax.redraw_in_frame()
# self.fig.canvas.blit(self.ax.bbox)
# Option 4. Doesn't update
# self.ax.draw_artist(self.point[0])
# Option 5. Draws new point but does not remove the "old" one
# self.ax.draw_artist(self.point[0])
# self.fig.canvas.blit(self.ax.bbox)
if __name__ == '__main__':
tt = Test()
当您四处走动时,ax_large
我希望它将是该点位置的快速更新。
关于如何执行此操作的任何想法都将有所帮助。
谢谢…
问题答案:
您实际上忽略了发条所需的大部分功能。见例如
和往常一样
- 画画布
fig.canvas.draw()
- 保存背景以备后用,
fig.canvas.copy_from_bbox()
- 更新要点,
point.set_data
- 恢复背景,
fig.canvas.restore_region
- 指出要点,
ax.draw_artist
- 咬住轴
fig.canvas.blit
因此
import matplotlib.pyplot as plt
import numpy as np
class Test:
def __init__(self):
self.fig = plt.figure(1)
# Axis with large plot
self.ax_large = plt.subplot(121)
self.ax_large.imshow(np.random.random((5000,5000)))
# Follow the point
self.ax = plt.subplot(122)
self.ax.grid(True)
# set some limits to the axes
self.ax.set_xlim(-5,5)
self.ax.set_ylim(-5,5)
# Draw the canvas once
self.fig.canvas.draw()
# Store the background for later
self.background = self.fig.canvas.copy_from_bbox(self.ax.bbox)
# Now create some point
self.point, = self.ax.plot(0,0, 'go')
# Create callback to mouse movement
self.cid = self.fig.canvas.callbacks.connect('motion_notify_event',
self.callback)
plt.show()
def callback(self, event):
if event.inaxes == self.ax:
# Update point's location
self.point.set_data(event.xdata, event.ydata)
# Restore the background
self.fig.canvas.restore_region(self.background)
# draw the point on the screen
self.ax.draw_artist(self.point)
# blit the axes
self.fig.canvas.blit(self.ax.bbox)
tt = Test()