এটি একটি দীর্ঘ দীর্ঘ ব্যাখ্যা যা আমি আমার সহকর্মীর জন্য টাইপ করেছি। আমি মনে করি এটি এখানেও সহায়ক হবে। ধৈর্য ধরুন, যদিও। আপনি শেষের দিকে আসছেন এমন আসল সমস্যাটি আমি পেয়েছি। একটি টিজার হিসাবে, এটি আপনার Line2Dবস্তুর চারদিকে ঝুলন্ত অতিরিক্ত রেফারেন্স থাকার বিষয় ।
সতর্কতা: আমরা ডুব দেওয়ার আগে অন্য একটি নোট you আপনি যদি এটি পরীক্ষা করার জন্য আইপিথন ব্যবহার করে থাকেন তবে আইপিথন তার নিজস্ব রেফারেন্স রাখে এবং সেগুলি সমস্ত দুর্বল নয়। সুতরাং, আইপিথনে আবর্জনা সংগ্রহের পরীক্ষা করা কার্যকর হয় না। এটি কেবল বিষয়গুলিকে বিভ্রান্ত করে।
ঠিক আছে, আমরা এখানে যাই। প্রতিটি 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একই আইডি ছিল না 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>
সুতরাং, গল্পটির নৈতিকতা হল, নিজের পরে পরিষ্কার করুন। আপনি যদি কোনও জিনিস আবর্জনা সংগ্রহের প্রত্যাশা করেন তবে তা না হয় তবে আপনি সম্ভবত কোনও রেফারেন্স কোথাও রেখে যাচ্ছেন।