यह एक बहुत लंबी व्याख्या है जो मैंने अपने एक सहकर्मी के लिए टाइप की थी। मुझे लगता है कि यह यहां भी मददगार होगा। हालांकि, धैर्य रखें। मैं असली मुद्दे पर आता हूं कि आप अंत की ओर हैं। एक टीज़र के रूप में, यह आपकी Line2Dवस्तुओं के चारों ओर अतिरिक्त संदर्भ होने का एक मुद्दा है ।
चेतावनी: इससे पहले कि हम गोता लगाते हैं एक अन्य नोट। यदि आप इसे बाहर परीक्षण करने के लिए आईपीथॉन का उपयोग कर रहे हैं, तो आईपीथॉन अपने स्वयं के संदर्भ रखता है और उनमें से सभी कमजोर नहीं हैं। तो, IPython में कचरा संग्रह का परीक्षण काम नहीं करता है। यह सिर्फ मामलों को भ्रमित करता है।
ठीक है, यहाँ हम चलते हैं। प्रत्येक matplotlibऑब्जेक्ट ( Figureऔर Axes, आदि) विभिन्न विशेषताओं के माध्यम से अपने बाल कलाकारों तक पहुंच प्रदान करता है। निम्नलिखित उदाहरण काफी लंबा हो रहा है, लेकिन रोशन होना चाहिए।
हम एक Figureऑब्जेक्ट बनाकर शुरू करते हैं , फिर Axesउस आकृति में एक ऑब्जेक्ट जोड़ते हैं । ध्यान दें कि axऔर fig.axes[0]समान वस्तु (समान 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)
यह भी एक कुल्हाड़ी वस्तु में लाइनों तक फैली हुई है:
>>>
>>> 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)
यदि आपको plt.show()ऊपर बताई गई कॉल का उपयोग करना है, तो आपको एक आकृति का एक अक्ष और एक रेखा दिखाई देगी:

अब, जबकि हमने देखा है कि सामग्री linesऔर ax.linesसमान है, यह ध्यान रखना बहुत महत्वपूर्ण है कि linesचर द्वारा संदर्भित वस्तु वैसी नहीं है, जैसा ax.linesकि निम्न द्वारा देखी जा रही वस्तु द्वारा देखी जा सकती है:
>>> id(lines), id(ax.lines)
(212754584, 211335288)
परिणामस्वरूप, एक तत्व को हटाने से linesवर्तमान भूखंड के लिए कुछ भी नहीं होता है, लेकिन एक तत्व को हटाने से ax.linesउस रेखा को वर्तमान भूखंड से हटा दिया जाता है। इसलिए:
>>>
>>> lines.pop(0)
>>>
>>> ax.lines.pop(0)
इसलिए, यदि आप कोड की दूसरी पंक्ति को चलाने के लिए थे, तो आप वर्तमान भूखंड से Line2Dनिहित वस्तु को हटा देंगे ax.lines[0]और यह चला जाएगा। ध्यान दें कि यह ax.lines.remove()अर्थ के माध्यम से भी किया जा सकता है कि आप Line2Dएक चर में एक उदाहरण को बचा सकते हैं , फिर इसे ax.lines.remove()उस पंक्ति को हटाने के लिए पास कर सकते हैं , जैसे:
>>>
>>> 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>]

उपरोक्त सभी काम करता है fig.axesऔर साथ ही इसके लिए काम करता हैax.lines
अब, असली समस्या यहाँ। यदि हम ax.lines[0]किसी weakref.refऑब्जेक्ट में निहित संदर्भ को संग्रहीत करते हैं , तो इसे हटाने का प्रयास करें, हम देखेंगे कि यह कचरा एकत्र नहीं करता है:
>>>
>>> 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>
संदर्भ अभी भी जीवित है! क्यों? इसका कारण यह है Line2Dकि वस्तु के संदर्भ में एक और संदर्भ अभी भी wrहै। याद रखें कि कैसे linesसमान ID नहीं थी, ax.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.
>>>
>>> lines = []
>>> print lines
[]
>>> print wr
<weakref at 0xb758af8; dead>
तो, कहानी का नैतिक है, अपने आप को साफ करना। यदि आप उम्मीद करते हैं कि कुछ कचरा एकत्र किया जाएगा, लेकिन ऐसा नहीं है, तो आप कहीं बाहर एक संदर्भ छोड़ रहे हैं।