mpl_connect inside a loop in matplotlib

753 Views Asked by At

It's not literally inside a loop, but I use fig.canvas.mpl_connect inside a method of my class PPlot().

In the main program I just create the plot first (with simple_plot()) and then call the update() method to re-draw the points:

plot = PPlot()
plot.simple_plot(x_values, y_values)
...
plot.update(x_values, y_values)
...
plot.update(x_values, y_values)

This is what my code looks like so far (__onpick just print the coordinates of the point picked):

def update(self, x_values, y_values) -> None:
    self.sc.set_data(x_values, y_values)
    event_handler = self.fig.canvas.mpl_connect('pick_event', self.__onpick)

    self.axis.relim()
    self.axis.autoscale_view(True, True, True)

    self.fig.canvas.draw()
    plt.pause(1*10e-10)

    self.fig.canvas.mpl_disconnect(event_handler)

The output is:

Point = (1,2)

On the other hand, if I don't put the last self.fig.canvas.mpl_disconnect(event_handler), when I use update() multiple times the output will be:

Point = (1,2)
Point = (1,2)
Point = (1,2)
...

Is there a better way of doing this? Am I doing something wrong? This approach doesn't seems good to me.

Thank you.

EDIT: Just to clarify, __onpick doesn't just print the points, It also do some other things. In fact, the real code is:

def update(self, x_values, y_values, biglist) -> None:
    ...
    event_handler = self.fig.canvas.mpl_connect('pick_event', 
                          lambda event: self.__onpick(event, biglist))
    ...

If I initialize fig.canvas.mpl_connect in the constructor or elsewhere outside update(), I can't use the list of the 3rd parameter.

1

There are 1 best solutions below

0
ImportanceOfBeingErnest On

I would imagine to make biglist a class variable and simply use it inside the onpick method, instead of supplying it to the onpick method.

import matplotlib.pyplot as plt

class PPlot():
    def __init__():
        self.biglist = None
        self.fig, self.ax = plt.subplots()
        self.cid = self.fig.canvas.mpl_connect('pick_event', self.onpick)

    def update(self, x_values, y_values, biglist):
        self.biglist = biglist
        self.sc.set_data(x_values, y_values)

        self.axis.relim()
        self.axis.autoscale_view(True, True, True)

        self.fig.canvas.draw()
        plt.pause(1*10e-10)


    def onpick(event=None):
        print (self.biglist)
        # do something with biglist



plot = PPlot()
plot.simple_plot(x_values, y_values)
#...
plot.update(x_values1, y_values1, biglist1)
#...
plot.update(x_values2, y_values2, biglist2)