簡體   English   中英

可拖動的Matplotlib散點圖使用blitting進行動畫繪制

[英]Draggable Matplotlib scatter with an animated plot using blitting

我最近問了一個有關創建可拖動散點圖的問題,在我能夠提出一個可行示例的幫助下。 請參閱“ PathCollection”不可迭代-創建可拖動的散點圖

我現在正嘗試使用通過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()

什么是正確的方法?

與GTK3Cairo后端一起使用。 (使用TkAgg,Qt4Agg,Qt5Agg,GTK3Agg無效。)

創建一次DraggableScatter ,然后使用ds.scatter.set_offsetsupdate函數中更改散點數據:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM