[Python] How to bind a pick event callback directly to an artisti in matplotlib

Discussão em 'Python' iniciado por Stack, Setembro 13, 2024.

  1. Stack

    Stack Membro Participativo

    I'm drawing 2 lines into a figure and I want to draw a vertical line when clicking the lines. What I want is the callback "on_pick_line1" being called when clicking on line "y1" and "on_pick_line2" when clicking on line y2.

    All examples in the documentation show how to bind a callback to the event "on_pick" of the canvas but it does not know which line has been clicked.

    I wrote the Pick_dispatcher class that routes the "on_pick" events to my callbacks. The solution works but, in my opinion is complicated.

    Is there any way to bind the callback "on_pick_line1" directly to line "y1" and so on?

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt


    class Pick_dispatcher():
    """Pick callbacks register themselfs into the dispatcher, then they'll get called"""

    def __init__(self):
    self.callbacks = {}

    def register_callback(self, artist, func):
    self.callbacks[artist] = func

    def unregister_callback(self, artist, func):
    del self.callbacks[artist]

    def __call__(self, event):
    artist = event.artist
    print("Dispatcher calling ", artist.get_label())
    self.callbacks[artist](event)



    def on_pick_line1(event):
    artist = event.artist
    i_sel = event.ind # list of indexes selected vertices
    i_med = i_sel[len(i_sel) // 2] # index of median vertex
    x = artist.get_xdata()[i_med] # median vertex
    ax = artist.axes
    ax.axvline(x, ls='--', lw=1, color='blue')
    artist.get_figure().canvas.draw_idle()



    def on_pick_line2(event):
    artist = event.artist
    i_sel = event.ind
    i_med = i_sel[len(i_sel) // 2]
    x = artist.get_xdata()[i_med]
    ax = artist.axes
    ax.axvline(x, ls='--', lw=1, color='red')
    artist.get_figure().canvas.draw_idle()




    if __name__ == "__main__":


    # Sample traces
    x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
    y1 = np.array([0, 0, 0, 1, 2, 3, 4, 5, 6, 6, 6, 6])
    y2 = np.array([0, 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5])

    # Prepare plot
    fig, ax = plt.subplots()

    pick_dispatcher = Pick_dispatcher()

    tolerance = 5 # points
    f, = ax.plot(x, y1, marker=".", ms=2, lw=1, label='y1', picker=True, pickradius=tolerance)
    pick_dispatcher.register_callback(f, on_pick_line1)

    g, = ax.plot(x, y2, marker=".", ms=2, lw=1, label='y2', picker=True, pickradius=tolerance)
    pick_dispatcher.register_callback(g, on_pick_line2)

    plt.legend()

    fig.canvas.callbacks.connect('pick_event', pick_dispatcher)
    plt.show()

    Continue reading...

Compartilhe esta Página