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