Issue
Could someone please shed some light on this?
This code is supposed to print out the event details on a mouse button press. If I connect the button_press_event
slot to on_button_press
(outside the class), the code works as expected. If I instead use the class method self.on_button_press
, nothing is printed out. Why is that?
import matplotlib.pyplot as plt
class Modifier:
def __init__(self, initial_line):
self.initial_line = initial_line
self.ax = initial_line.axes
canvas = self.ax.figure.canvas
cid = canvas.mpl_connect('button_press_event', self.on_button_press)
def on_button_press(self, event):
print(event)
def on_button_press(event):
print(event)
fig, ax = plt.subplots()
ax.set_aspect('equal')
initial = ax.plot([1,2,3], [4,5,6], color='b', lw=1, clip_on=False)
Modifier(initial[0])
plt.show()
Solution
Because you create the object but don't save it to a variable, Python automatically destroys it immediately after you create it. We can check this by adding a __del__
method with a print
call to show it is being deleted. I also added a short sleep to prove that the destruction is happening before the program terminates.
import matplotlib.pyplot as plt
import time
class Modifier:
def __init__(self, initial_line):
self.initial_line = initial_line
self.ax = initial_line.axes
canvas = self.ax.figure.canvas
cid = canvas.mpl_connect("button_press_event", self.on_button_press)
def on_button_press(self, event):
print(event)
def __del__(self):
print("Destroyed.")
fig, ax = plt.subplots()
ax.set_aspect("equal")
initial = ax.plot([1,2,3], [4,5,6], color='b', lw=1, clip_on=False)
Modifier(initial[0])
print("Starting to sleep...")
time.sleep(5)
print("Done sleeping.")
plt.show()
Output:
Destroyed.
Starting to sleep...
Done sleeping.
So, your class instance is destroyed before the plot is shown. In the case where you use the external button function, mpl_connect
still knows about the function and can use it. In the case of the class method, the class is destroyed and so mpl_connect
no longer has a function to call (and I'm not sure why this happens silently).
The simple fix is to save the object to a variable so it isn't immediately destroyed, i.e.
m = Modifier(initial[0])
Once you do this, the code will work with the class method.
As a side note, you should probably save cid
as a class attribute to ensure that remains as well.
Answered By - jared
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.