How to remove lines in a Matplotlib plot

matplotlib remove points from plot
matplotlib remove horizontal line
matplotlib remove single line
matplotlib remove axis lines
remove last plot matplotlib
matplotlib remove artist
matplotlib scatter plot
matplotlib update plot

How can I remove a line (or lines) of a matplotlib axes in such a way as it actually gets garbage collected and releases the memory back? The below code appears to delete the line, but never releases the memory (even with explicit calls to gc.collect())

from matplotlib import pyplot
import numpy
a = numpy.arange(int(1e7))
# large so you can easily see the memory footprint on the system monitor.
fig = pyplot.Figure()
ax  = pyplot.add_subplot(1, 1, 1)
lines = ax.plot(a) # this uses up an additional 230 Mb of memory.
# can I get the memory back?
l = lines[0]
l.remove()
del l
del lines
# not releasing memory
ax.cla() # this does release the memory, but also wipes out all other lines.

So is there a way to just delete one line from an axes and get the memory back? This potential solution also does not work.

I'm showing that a combination of lines.pop(0) l.remove() and del l does the trick.

from matplotlib import pyplot
import numpy, weakref
a = numpy.arange(int(1e3))
fig = pyplot.Figure()
ax  = fig.add_subplot(1, 1, 1)
lines = ax.plot(a)

l = lines.pop(0)
wl = weakref.ref(l)  # create a weak reference to see if references still exist
#                      to this object
print wl  # not dead
l.remove()
print wl  # not dead
del l
print wl  # dead  (remove either of the steps above and this is still live)

I checked your large dataset and the release of the memory is confirmed on the system monitor as well.

Of course the simpler way (when not trouble-shooting) would be to pop it from the list and call remove on the line object without creating a hard reference to it:

lines.pop(0).remove()

Matplotlib - How to remove a specific line or curve, Almost all of the plotting functions return a reference to the artist object created ex​: ln, = plot(x, y) # plot actually returns a list of artists, hence the  The below code appears to delete the line, but never releases the memory (even with explicit calls to gc.collect ()) from matplotlib import pyplot import numpy a = numpy.arange (int (1e7)) # large so you can easily see the memory footprint on the system monitor. fig = pyplot.Figure () ax = pyplot.add_subplot (1, 1, 1) lines = ax.plot (a) # this uses up an additional 230 Mb of memory. # can I get the memory back? l = lines [0] l.remove () del l del lines # not releasing memory ax.cla

This is a very long explanation that I typed up for a coworker of mine. I think it would be helpful here as well. Be patient, though. I get to the real issue that you are having toward the end. Just as a teaser, it's an issue of having extra references to your Line2D objects hanging around.

WARNING: One other note before we dive in. If you are using IPython to test this out, IPython keeps references of its own and not all of them are weakrefs. So, testing garbage collection in IPython does not work. It just confuses matters.

Okay, here we go. Each matplotlib object (Figure, Axes, etc) provides access to its child artists via various attributes. The following example is getting quite long, but should be illuminating.

We start out by creating a Figure object, then add an Axes object to that figure. Note that ax and fig.axes[0] are the same object (same id()).

>>> #Create a figure
>>> fig = plt.figure()
>>> fig.axes
[]

>>> #Add an axes object
>>> ax = fig.add_subplot(1,1,1)

>>> #The object in ax is the same as the object in fig.axes[0], which is 
>>> #   a list of axes objects attached to fig 
>>> print ax
Axes(0.125,0.1;0.775x0.8)
>>> print fig.axes[0]
Axes(0.125,0.1;0.775x0.8)  #Same as "print ax"
>>> id(ax), id(fig.axes[0])
(212603664, 212603664) #Same ids => same objects

This also extends to lines in an axes object:

>>> #Add a line to ax
>>> lines = ax.plot(np.arange(1000))

>>> #Lines and ax.lines contain the same line2D instances 
>>> print lines
[<matplotlib.lines.Line2D object at 0xce84bd0>]
>>> print ax.lines
[<matplotlib.lines.Line2D object at 0xce84bd0>]

>>> print lines[0]
Line2D(_line0)
>>> print ax.lines[0]
Line2D(_line0)

>>> #Same ID => same object
>>> id(lines[0]), id(ax.lines[0])
(216550352, 216550352)

If you were to call plt.show() using what was done above, you would see a figure containing a set of axes and a single line:

Now, while we have seen that the contents of lines and ax.lines is the same, it is very important to note that the object referenced by the lines variable is not the same as the object reverenced by ax.lines as can be seen by the following:

>>> id(lines), id(ax.lines)
(212754584, 211335288)

As a consequence, removing an element from lines does nothing to the current plot, but removing an element from ax.lines removes that line from the current plot. So:

>>> #THIS DOES NOTHING:
>>> lines.pop(0)

>>> #THIS REMOVES THE FIRST LINE:
>>> ax.lines.pop(0)

So, if you were to run the second line of code, you would remove the Line2D object contained in ax.lines[0] from the current plot and it would be gone. Note that this can also be done via ax.lines.remove() meaning that you can save a Line2D instance in a variable, then pass it to ax.lines.remove() to delete that line, like so:

>>> #Create a new line
>>> lines.append(ax.plot(np.arange(1000)/2.0))
>>> ax.lines
[<matplotlib.lines.Line2D object at 0xce84bd0>,  <matplotlib.lines.Line2D object at 0xce84dx3>]

>>> #Remove that new line
>>> ax.lines.remove(lines[0])
>>> ax.lines
[<matplotlib.lines.Line2D object at 0xce84dx3>]

All of the above works for fig.axes just as well as it works for ax.lines

Now, the real problem here. If we store the reference contained in ax.lines[0] into a weakref.ref object, then attempt to delete it, we will notice that it doesn't get garbage collected:

>>> #Create weak reference to Line2D object
>>> from weakref import ref
>>> wr = ref(ax.lines[0])
>>> print wr
<weakref at 0xb758af8; to 'Line2D' at 0xb757fd0>
>>> print wr()
<matplotlib.lines.Line2D at 0xb757fd0>

>>> #Delete the line from the axes
>>> ax.lines.remove(wr())
>>> ax.lines
[]

>>> #Test weakref again
>>> print wr
<weakref at 0xb758af8; to 'Line2D' at 0xb757fd0>
>>> print wr()
<matplotlib.lines.Line2D at 0xb757fd0>

The reference is still live! Why? This is because there is still another reference to the Line2D object that the reference in wr points to. Remember how lines didn't have the same ID as ax.lines but contained the same elements? Well, that's the problem.

>>> #Print out lines
>>> print lines
[<matplotlib.lines.Line2D object at 0xce84bd0>,  <matplotlib.lines.Line2D object at 0xce84dx3>]

To fix this problem, we simply need to delete `lines`, empty it, or let it go out of scope.

>>> #Reinitialize lines to empty list
>>> lines = []
>>> print lines
[]
>>> print wr
<weakref at 0xb758af8; dead>

So, the moral of the story is, clean up after yourself. If you expect something to be garbage collected but it isn't, you are likely leaving a reference hanging out somewhere.

matplotlib / Re: [Matplotlib-users] Deleting lines from a plot, If you know which line you want to delete, you can call ax.lines.remove(line) where line is a line instance. In [1]: line1, = plot(rand(10), 'ro') In [2]: line2,  How to remove frame from matplotlib (pyplot.figure vs matplotlib.figure ) (frameon=False Problematic in matplotlib) (11 answers) Closed 2 years ago . I would like to be able to hide the axes and gridlines on a 3D matplotlib graph.

I've tried lots of different answers in different forums. I guess it depends on the machine your developing. But I haved used the statement

ax.lines = []

and works perfectly. I don't use cla() cause it deletes all the definitions I've made to the plot

Ex.

pylab.setp(_self.ax.get_yticklabels(), fontsize=8)

but I've tried deleting the lines many times. Also using the weakref library to check the reference to that line while I was deleting but nothing worked for me.

Hope this works for someone else =D

matplotlib.axes.Axes.remove, matplotlib.axes.Axes.remove¶. Axes. remove (self)¶. Remove the artist from the figure if possible. The effect will not be visible until the figure is  To simply remove the lines once the data has been plotted: handles, labels = ax.get_legend_handles_labels() for h in handles: h.set_linestyle("") ax.legend(handles, labels)

(using the same example as the guy above)

from matplotlib import pyplot
import numpy
a = numpy.arange(int(1e3))
fig = pyplot.Figure()
ax  = fig.add_subplot(1, 1, 1)
lines = ax.plot(a)

for i, line in enumerate(ax.lines):
    ax.lines.pop(i)
    line.remove()

Artist tutorial, If you make subsequent calls to ax.plot (and the hold state is "on" which is the default) then additional lines will be added to the list. You can remove lines later​  Each axes instance contains a lines attribute, which is a list of the data series in the plot, added in chronological order. To delete a particular data series, one must simply delete the appropriate element of the lines list and redraw if necessary. The is illustrated in the following example from an interactive session:

Plotting masked and NaN values, Sometimes you need to plot data with missing values. One possibility is to simply remove undesired data points. The line plotted through the remaining data will  Hi, When i try to plot the following data x,y, and z using plot 3 function, i'm getting the plot, where the points have connection lines between them. How can i remove those connecting lines between points ? This is my code:

Matplotlib: deleting an existing data series, Each axes instance contains a lines attribute, which is a list of the data series in the plot, added in chronological order. To delete a particular  So, if you were to run the second line of code, you would remove the Line2D object contained in ax.lines from the current plot and it would be gone. Note that this can also be done via ax.lines.remove () meaning that you can save a Line2D instance in a variable, then pass it to ax.lines.remove () to delete that line, like so:

Remove vlines from a matplotlib plot? : learnpython, lines, and so while I can delete them from my dict, I can't actually remove them from the graph. No amount of googling is clueing me in to where this object is held,  How do you remove the frame, ticks, or axes from a matplotlib plot? matplotlib plot without a y axis. Some books you may find useful when working with matplotlib: The full example is available on github. First, we construct a figure and an axes object: fig1 = plt.figure(facecolor='white') ax1 = plt.axes(frameon=False) The Axes object is a

Comments
  • I ran your code and I got: [8:37pm]@flattop:~/Desktop/sandbox>python delete_lines.py <weakref at 0x8dd348c; to 'Line2D' at 0x8dd43ec> <weakref at 0x8dd348c; to 'Line2D' at 0x8dd43ec> <weakref at 0x8dd348c; to 'Line2D' at 0x8dd43ec> I'm using matplotlib version 0.99.1.1 in ubuntu 10.04
  • @David Morton I just downgraded to 0.99.1 and now I reproduce your problem. I guess I can only recommend upgrading to 1.0.1. There were a lot of bugfixes since 0.99.x
  • The issue here is likely an issue of references hanging around when they shouldn't be. I would bet that the OP was using IPython to test things out. See my answer.
  • Exactly what I needed. I'm plotting thousands of maps, each with a scatter plot over top of a world map projection. They were taking 3 seconds each! By reusing the figure with the map already drawn and popping the resulting collection from ax.collections I got it down to 1/3 of a second. Thanks!
  • I think this is no longer necessary in current versions of mpl. The artist have a remove() function which will clean them out of the mpl side of things, and then you only need to keep track of your references.
  • Huh, any idea what version of matplotlib this change same out in?
  • The issue here is likely an issue of references hanging around when they shouldn't be. I would bet that the OP was using IPython to test things out. See my answer.