点选择器event_handler绘制线并在matplotlib中显示坐标

时间:2017-03-18 15:29:36

标签: python matplotlib event-handling

我有以下类通过y轴绘制一条垂直线,因此当我点击它时,会在该位置绘制一条水平线。 我的目标是让y坐标实际打印在y轴上,水平线被绘制。为了进行测试,我正在尝试使用y-ccordinate打印标题,但它没有按预期工作。

我想要真正实现的是使条形图上的y轴可点击,以便用户可以在y轴上选择一个点,然后发生一堆“东西”(包括绘图一条水平线)。除了在y轴上画一条可绘制的垂直线以使其可以选择之外,我真的看不到其它方法可以实现这一点。这似乎相当笨拙,但我没有任何其他方法取得任何成功。

import matplotlib.pyplot as plt

class PointPicker(object):
    def __init__(self):

        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111)
        self.lines2d, = self.ax.plot((0, 0), (-6000, 10000), 'k-', linestyle='-',picker=5)

        self.fig.canvas.mpl_connect('pick_event', self.onpick)
        self.fig.canvas.mpl_connect('key_press_event', self.onpress)
        fig.canvas.mpl_connect('button_press_event', self.onclick)

    def onpress(self, event):
        """define some key press events"""
        if event.key.lower() == 'q':
            sys.exit()

    def onpick(self,event):
        x = event.mouseevent.xdata
        y = event.mouseevent.ydata
        L =  self.ax.axhline(y=y)
        print(y)
        ax.axvspan(0, 0, facecolor='y', alpha=0.5, picker=10)
        self.fig.canvas.draw()

    def onclick(event):
        self.fig.canvas.set_title('Selected item came from {}'.format(event.ydata))
        print(event.xdata, event.ydata)

if __name__ == '__main__':

    plt.ion()
    p = PointPicker()
    plt.show()

假设没有办法实现我的最终结果,这种方法一切都很好,除了我不能在我的生活中获得打印的标题(使用self.fig.canvas.set_title('Selected item came from {}'.format(event.ydata))。

1 个答案:

答案 0 :(得分:3)

您可以使用'button_press_event'连接到某个方法,该方法会验证点击是否发生在离yaxis脊柱足够近的位置,然后使用点击的坐标绘制水平线。

import matplotlib.pyplot as plt

class PointPicker(object):
    def __init__(self, ax, clicklim=0.05):
        self.fig=ax.figure
        self.ax = ax
        self.clicklim = clicklim
        self.horizontal_line = ax.axhline(y=.5, color='y', alpha=0.5)
        self.text = ax.text(0,0.5, "")
        print self.horizontal_line
        self.fig.canvas.mpl_connect('button_press_event', self.onclick)


    def onclick(self, event):
        if event.inaxes == self.ax:
            x = event.xdata
            y = event.ydata
            xlim0, xlim1 = ax.get_xlim()
            if x <= xlim0+(xlim1-xlim0)*self.clicklim:
                self.horizontal_line.set_ydata(y)
                self.text.set_text(str(y))
                self.text.set_position((xlim0, y))
                self.fig.canvas.draw()


if __name__ == '__main__':

    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.bar([0,2,3,5],[4,5,1,3], color="#dddddd")
    p = PointPicker(ax)
    plt.show()

enter image description here