Reputation: 33
I have encountered a strange issue with matplotlib artists.
Disclaimer: Unfortunately I only ever used matplotlib in jupyter notebooks and in a tkinter GUI (the latter is where I found this) so I do not know how to write simple code that will replicate the issue. However I do not think sample is code is absolutely needed in this case.
Now the issue:
In the interest of speeding up plotting in a GUI I do not plot everything anew whenever elements of the plot change but rather make use of methods like set_ydata
and canvas.draw
. Sometimes it is also necessary to remove lines altogether which can be accomplished with artist.remove
. Here is the problem: When I have one or several artist(s) stored in a list I can successfully remove them from the plot by iterating over the list and calling remove
. If however I store the reference directly (as an attribute of the class that is managing plots), calling remove
does not do anything.
As sketch of the code suppose we have
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot()
the first case is generated by something like
artist_list = list()
for x in range(5):
line = ax.axhline(x)
artist_list.append(line)
and can be removed by
for line in artist_list:
line.remove()
artist_list = list()
(the last is needed for this to work).
whereas the second would be
line = ax.axhline(1)
line.remove()
which does not remove the line from the plot (even if del line
or line = None
are added).
It seems that storing the artist in a list and then assigning that variable to a new empty list is somehow a more complete removal than reassigning the variable that stores the artist directly or even deleting it. Does somebody know what is going here? How could a line be removed if it is simply stored as line
rather than in a list?
Upvotes: 2
Views: 5046
Reputation: 339590
As can be seen from the below piece of code, removing a line is pretty easy. Indeed, you just call .remove()
on the object in question and redraw the canvas.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.set(title="Click to remove line", xlim=(0,2))
line=ax.axvline(1)
def remove_line(event):
line.remove()
fig.canvas.draw()
fig.canvas.mpl_connect("button_press_event", remove_line)
plt.show()
Upvotes: 4