可拖曳的Matplotlib散点图,使用动画效果进行散布

时间:2018-10-25 19:00:22

标签: python python-3.x matplotlib

我最近问了一个有关创建可拖动散点图的问题,在我能够提供一个可行示例的人的帮助下。参见'PathCollection' not iterable - creating a draggable scatter plot

我现在正尝试使用通过blitting制作动画情节创建的DraggableScatter类。

我尝试在多个位置附加DraggableScatter类,例如,在初始化散点之后,在init函数和update函数中。在第一种情况下,DraggableScatter的散点为空,这是有道理的,但显然不起作用。在另外两个中,点击似乎没有被捕获。

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()

正确的方法是什么?

1 个答案:

答案 0 :(得分:0)

这与GTK3Cairo后端一起使用。 (使用TkAgg,Qt4Agg,Qt5Agg,GTK3Agg无效。)

创建一次 id date happy type 1 1912 2018-10-08 11:32:55 0 blue 2 1912 2018-10-05 11:32:55 0 red 3 1912 2018-10-08 09:09:56 0 red 4 1912 2018-10-08 11:32:55 0 c1 7 2191 2018-10-15 08:17:47 0 red 8 2191 2018-09-29 10:16:34 0 green 9 2191 2018-07-09 18:28:25 0 blue 10 2191 2018-07-09 18:28:25 0 green 11 2191 2018-10-15 08:17:47 1 c1 15 2192 2018-07-09 18:20:32 0 purple 16 2192 2018-08-30 13:06:45 0 blue 17 2192 2018-07-09 18:20:32 0 c1 19 14129 2018-06-15 00:15:42 0 blue 20 14129 2018-10-08 12:44:44 0 blue 21 14129 2018-07-09 18:14:58 0 green 22 14129 2018-06-15 00:15:42 1 c1 25 29102 2018-06-15 00:15:40 0 red 26 29102 2018-06-15 00:19:42 0 red 27 29102 2018-06-15 00:15:40 0 c1 ,然后使用DraggableScatter更改ds.scatter.set_offsets函数内部的散点数据:

update