python - 可拖动的 Matplotlib 散点图,带有使用 blitting 的动画图
问题描述
我最近问了一个关于创建可拖动散点图的问题,在某人的帮助下,我想出了一个可行的例子。请参阅'PathCollection' not iterable - 创建可拖动的散点图。
我现在正在尝试使用我创建的 DraggableScatter 类和使用 blitting 的动画情节。
我尝试在多个地方附加 DraggableScatter 类,例如,在初始化散点图之后,在 init 函数和更新函数中。在第一种情况下,DraggableScatter 的 scatter 是空的,这是有道理的,但显然不起作用。在另外两个中,点击似乎没有被捕获。
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
class DraggableScatter():
epsilon = 5
def __init__(self, scatter):
self.scatter = scatter
self._ind = None
self.ax = scatter.axes
self.canvas = self.ax.figure.canvas
self.canvas.mpl_connect('button_press_event', self.button_press_callback)
self.canvas.mpl_connect('button_release_event', self.button_release_callback)
self.canvas.mpl_connect('motion_notify_event', self.motion_notify_callback)
def get_ind_under_point(self, event):
xy = np.asarray(self.scatter.get_offsets())
xyt = self.ax.transData.transform(xy)
xt, yt = xyt[:, 0], xyt[:, 1]
d = np.sqrt((xt - event.x)**2 + (yt - event.y)**2)
ind = d.argmin()
if d[ind] >= self.epsilon:
ind = None
return ind
def button_press_callback(self, event):
if event.inaxes is None:
return
if event.button != 1:
return
self._ind = self.get_ind_under_point(event)
def button_release_callback(self, event):
if event.button != 1:
return
self._ind = None
def motion_notify_callback(self, event):
if self._ind is None:
return
if event.inaxes is None:
return
if event.button != 1:
return
x, y = event.xdata, event.ydata
xy = np.asarray(self.scatter.get_offsets())
xy[self._ind] = np.array([x, y])
self.scatter.set_offsets(xy)
self.canvas.draw_idle()
fig, ax = plt.subplots(1, 1)
scatter = ax.scatter([],[])
def init():
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
return scatter,
def update(frame):
scatter = ax.scatter(np.random.rand(10), np.random.rand(10), marker ='o')
ds = DraggableScatter(scatter)
return scatter,
ani = FuncAnimation(fig=fig, func=update, init_func=init, blit=True, interval=5000)
plt.show()
这样做的正确方法是什么?
解决方案
这适用于 GTK3Cairo 后端。(它不适用于 TkAgg、Qt4Agg、Qt5Agg、GTK3Agg。)
创建DraggableScatter
一次,然后用于ds.scatter.set_offsets
更改update
函数内部的散点数据:
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
class DraggableScatter():
epsilon = 5
def __init__(self, scatter):
self.scatter = scatter
self._ind = None
self.ax = scatter.axes
self.canvas = self.ax.figure.canvas
self.canvas.mpl_connect('button_press_event', self.button_press_callback)
self.canvas.mpl_connect('button_release_event', self.button_release_callback)
self.canvas.mpl_connect('motion_notify_event', self.motion_notify_callback)
def get_ind_under_point(self, event):
xy = np.asarray(self.scatter.get_offsets())
xyt = self.ax.transData.transform(xy)
xt, yt = xyt[:, 0], xyt[:, 1]
d = np.sqrt((xt - event.x)**2 + (yt - event.y)**2)
ind = d.argmin()
if d[ind] >= self.epsilon:
ind = None
return ind
def button_press_callback(self, event):
if event.inaxes is None:
return
if event.button != 1:
return
self._ind = self.get_ind_under_point(event)
def button_release_callback(self, event):
if event.button != 1:
return
self._ind = None
def motion_notify_callback(self, event):
if self._ind is None:
return
if event.inaxes is None:
return
if event.button != 1:
return
x, y = event.xdata, event.ydata
xy = np.asarray(self.scatter.get_offsets())
xy[self._ind] = np.array([x, y])
self.scatter.set_offsets(xy)
self.canvas.draw_idle()
fig, ax = plt.subplots(1, 1)
scatter = ax.scatter(np.random.rand(10), np.random.rand(10), marker ='o')
ds = DraggableScatter(scatter)
def init():
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
return ds.scatter,
def update(frame, ds):
x, y = np.random.rand(10), np.random.rand(10)
ds.scatter.set_offsets(np.column_stack([x, y]))
return ds.scatter,
ani = FuncAnimation(fig=fig, func=update, init_func=init, fargs=[ds], blit=True,
interval=5000)
plt.show()
推荐阅读
- ios - ios 获取位置 react-native/Expo
- javascript - 如何在 React Native 中创建无组织的网格视图
- c# - 缺少 C# Properties.Settings
- sapui5 - 以“标题”作为超链接的 SAP UI5 对象列表项
- snowflake-cloud-data-platform - 使用事务内的临时表调用存储过程
- nearprotocol - 如何验证在 Rust 智能合约测试中创建了正确的 Promise?
- javascript - script src 302 如何找出哪个链接重定向?
- c++ - 返回模板化实体的函数的概念
- python - Pandas 打破行并阻止 Google Data Studio 正确读取文件
- eclipse - 为什么其他代码有 Log4j 输出到控制台,而不是我的代码?