Dies ist eine sehr lange Erklärung, die ich für einen meiner Kollegen geschrieben habe. Ich denke, das wäre auch hier hilfreich. Sei aber geduldig. Ich komme zu dem eigentlichen Problem, das Sie gegen Ende haben. Nur als Teaser geht es darum, zusätzliche Verweise auf Ihre zu habenLine2D Objekte zu haben.
WARNUNG: Noch ein Hinweis, bevor wir eintauchen. Wenn Sie IPython zum Testen verwenden, behält IPython eigene Referenzen bei und nicht alle sind Schwachstellen. Das Testen der Garbage Collection in IPython funktioniert also nicht. Es verwirrt nur die Dinge.
Okay, los geht's. Jedes matplotlibObjekt ( Figure, Axesusw.) bietet Zugang zu seinem Kind Künstler über verschiedene Attribute. Das folgende Beispiel wird ziemlich lang, sollte aber leuchten.
Wir beginnen mit der Erstellung eines FigureObjekts und fügen Axesdieser Figur dann ein Objekt hinzu. Beachten Sie, dass axund fig.axes[0]dasselbe Objekt sind (dasselbe id()).
>>>
>>> fig = plt.figure()
>>> fig.axes
[]
>>>
>>> ax = fig.add_subplot(1,1,1)
>>>
>>>
>>> print ax
Axes(0.125,0.1;0.775x0.8)
>>> print fig.axes[0]
Axes(0.125,0.1;0.775x0.8)
>>> id(ax), id(fig.axes[0])
(212603664, 212603664)
Dies erstreckt sich auch auf Linien in einem Achsenobjekt:
>>>
>>> lines = ax.plot(np.arange(1000))
>>>
>>> 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)
>>>
>>> id(lines[0]), id(ax.lines[0])
(216550352, 216550352)
Wenn Sie mit den oben beschriebenen Schritten anrufen plt.show()würden, würden Sie eine Abbildung sehen, die einen Satz Achsen und eine einzelne Zeile enthält:

Obwohl wir gesehen haben, dass der Inhalt von linesund ax.linesderselbe ist, ist es sehr wichtig zu beachten, dass das Objekt, auf das die linesVariable verweist, nicht dasselbe ist wie das Objekt , auf das verwiesen wird ax.lines, wie aus dem Folgenden ersichtlich ist:
>>> id(lines), id(ax.lines)
(212754584, 211335288)
Infolgedessen hat das Entfernen eines Elements aus linesnichts mit dem aktuellen Plot zu tun, aber das Entfernen eines Elements aus ax.linesentfernt diese Linie aus dem aktuellen Plot. Damit:
>>>
>>> lines.pop(0)
>>>
>>> ax.lines.pop(0)
Wenn Sie also die zweite Codezeile ausführen würden, würden Sie das darin Line2Denthaltene Objekt ax.lines[0]aus dem aktuellen Plot entfernen und es wäre verschwunden. Beachten Sie, dass dies auch über die ax.lines.remove()Bedeutung erfolgen kann, dass Sie eine Line2DInstanz in einer Variablen speichern und dann an übergeben können ax.lines.remove(), um diese Zeile wie folgt zu löschen:
>>>
>>> lines.append(ax.plot(np.arange(1000)/2.0))
>>> ax.lines
[<matplotlib.lines.Line2D object at 0xce84bd0>, <matplotlib.lines.Line2D object at 0xce84dx3>]

>>>
>>> ax.lines.remove(lines[0])
>>> ax.lines
[<matplotlib.lines.Line2D object at 0xce84dx3>]

Alle oben genannten Funktionen funktionieren fig.axesgenauso gut wie fürax.lines
Nun das eigentliche Problem hier. Wenn wir die darin enthaltene Referenz ax.lines[0]in einem weakref.refObjekt speichern und dann versuchen, sie zu löschen, werden wir feststellen, dass kein Müll gesammelt wird:
>>>
>>> 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>
>>>
>>> ax.lines.remove(wr())
>>> ax.lines
[]
>>>
>>> print wr
<weakref at 0xb758af8; to 'Line2D' at 0xb757fd0>
>>> print wr()
<matplotlib.lines.Line2D at 0xb757fd0>
Die Referenz ist noch live! Warum? Dies liegt daran, dass es noch einen weiteren Verweis auf das Line2DObjekt gibt, auf den der Verweis in wrverweist. Erinnern Sie sich, wie Sie linesnicht dieselbe ID hatten, ax.linesaber dieselben Elemente enthielten? Nun, das ist das Problem.
>>>
>>> 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.
>>>
>>> lines = []
>>> print lines
[]
>>> print wr
<weakref at 0xb758af8; dead>
Die Moral der Geschichte lautet also: Räumen Sie nach sich selbst auf. Wenn Sie erwarten, dass etwas Müll gesammelt wird, dies aber nicht ist, lassen Sie wahrscheinlich irgendwo eine Referenz hängen.