标记/声明特定拣选事件的艺术家

时间:2015-04-02 21:07:32

标签: python matplotlib event-handling mouseevent

我有一个简单的正弦波图和一个程序(有几种模式)来选取正弦波线的峰值。我有另一种模式来删除我选择/绘制的峰值,以防出现错误。但是我在分离哪个艺术家时遇到了一些麻烦。

我希望能够标记正弦波线和拾取点,以便稍后我可以移除我拾取/绘制的峰值点,并将正弦波保持在图上。我在下面制作了这段代码。对不起,它可能看起来很复杂,我只是想保持我的程序的布局/功能。

#! /usr/bin/python

import sys
import matplotlib.pyplot as plt
import numpy as np


class MyClick(object):
    def __init__(self):
        # initialize mode
        self._mode = 1 

        self.peak = []

    def press(self, event):
        """record last key pressed"""
        sys.stdout.flush()
        if event.key == '1':   
            self._mode = 1 
            print('Peak Mode')

        elif event.key == '4':
            self._mode = 4
            print('Delete Mode')

    def pick(self,event):
        mouseevent = event.mouseevent
        artist = event.artist
        x, y = np.array(artist.get_xdata()), np.array(artist.get_ydata())#used numpy array for argsort feature
        ind = event.ind

        #remove = [artist for artist in self.peak if artist.get_xy ]

        if self._mode == 1:
            # peak
            peakind = y[ind].argsort()[-1:] #argsort to find peak
            self.peak.append(zip(x[ind[peakind]], y[ind[peakind]])) #save peak
            ax.plot(x[ind[peakind]],y[ind[peakind]],'ro',picker=5)
            print('peak: ', zip(x[ind[peakind]], y[ind[peakind]]))
            pass

        elif self._mode == 4:
            # delete
            #for artist in remove:
            artist.remove()

        fig.canvas.draw()

if __name__ == "__main__":
    fig = plt.figure()
    ax = plt.axes()

    ax.set_xlim(0, 1.5)
    ax.set_ylim(-1.5, 1.5)

    #pickable_artists = []

    x=np.arange(0,2,0.01)
    y=np.sin(2*np.pi*x)
    plt.plot(x, y, picker=5)

    browser = MyClick()
    cid = fig.canvas.mpl_connect('pick_event', browser.pick)
    cid = fig.canvas.mpl_connect('key_press_event', browser.press)

    plt.show()

我一直试图关注这篇文章matplotlib: clearing the scatter data before redrawing中的内容,但我似乎做错了什么。任何帮助将不胜感激!提前谢谢!

1 个答案:

答案 0 :(得分:1)

经过几个小时的玩弄和搜索,我想出了一个解决方案。基本上我存储了所选的每个峰值并将其绘制成一个列表。然后将列表与当前艺术家进行比较。如果这是一个可怕的解释,我很抱歉,但我已经在下面添加了新代码。感谢matplotlib: clearing the scatter data before redrawingMatplotlib - How to remove a specific line or curve的灵感和帮助。

#! /usr/bin/python
import sys
import matplotlib.pyplot as plt
import numpy as np


class MyClick(object):
    def __init__(self):
        # initialize mode
        self._mode = 1 

        self.peak = []
        self.pk = [] # new - list where to store artists/pts already picked

    def press(self, event):
        """record last key pressed"""
        sys.stdout.flush()
        if event.key == '1':   
            self._mode = 1 
            print('Peak Mode')

        elif event.key == '4':
            self._mode = 4
            print('Delete Mode')

    def pick(self,event):
        mouseevent = event.mouseevent
        artist = event.artist
        x, y = np.array(artist.get_xdata()), np.array(artist.get_ydata()) #used numpy array for argsort feature
        ind = event.ind

        #remove = [artist for artist in self.peak if artist.contains()]


        if self._mode == 1:
            # peak
            peakind = y[ind].argsort()[-1:] #argsort to find peak
            self.peak.append(zip(x[ind[peakind]], y[ind[peakind]])) #save peak
            pt, = ax.plot(x[ind[peakind]],y[ind[peakind]],'ro',picker=5) #new
            self.pk.append(pt)  #new - store into a list
            print('peak: ', zip(x[ind[peakind]], y[ind[peakind]]))
            pass

        elif self._mode == 4:
            # delete
            for i in self.pk:   # this loop can probably be done in 1 line
                for j in ind:
                    if i == artist: #see if point in list matches current point
                        i.remove()  #remove the point

        fig.canvas.draw()

if __name__ == "__main__":
    fig = plt.figure()
    ax = plt.axes()

    ax.set_xlim(0, 1.5)
    ax.set_ylim(-1.5, 1.5)

    #pickable_artists = []

    x=np.arange(0,2,0.01)
    y=np.sin(2*np.pi*x)
    plt.plot(x, y, picker=5)

    browser = MyClick()
    cid = fig.canvas.mpl_connect('pick_event', browser.pick)
    cid = fig.canvas.mpl_connect('key_press_event', browser.press)

    plt.show()

希望这有助于将来的任何人!