Dalam naskah tempat saya membuat banyak angka fix, ax = plt.subplots(...)
, saya mendapatkan peringatan RuntimeWarning: Lebih dari 20 angka telah dibuka. Angka yang dibuat melalui antarmuka pyplot ( matplotlib.pyplot.figure
) dipertahankan hingga ditutup secara eksplisit dan dapat menggunakan terlalu banyak memori.
Namun, saya tidak mengerti mengapa saya mendapatkan peringatan ini, karena setelah menyimpan angka dengan fig.savefig(...)
, saya menghapusnya dengan fig.clear(); del fig
. Tidak ada titik dalam kode saya, saya memiliki lebih dari satu angka terbuka pada suatu waktu. Namun, saya mendapat peringatan tentang terlalu banyak angka terbuka. Apa artinya itu / bagaimana saya bisa menghindari mendapat peringatan?
python
python-3.x
matplotlib
andreas-h
sumber
sumber
plt
semuanya. Misalnya stackoverflow.com/a/16337909/325565 (Bukan untuk menyambungkan salah satu jawaban saya sendiri, tetapi itu adalah jawaban yang paling cepat saya temukan ...)Jawaban:
Gunakan
.clf
atau.cla
pada objek gambar Anda alih-alih membuat gambar baru . Dari @DavidZwickerDengan asumsi Anda telah mengimpor
pyplot
sebagaiplt.cla()
membersihkan sumbu , yaitu sumbu yang saat ini aktif dalam gambar saat ini. Itu membuat sumbu lainnya tidak tersentuh.plt.clf()
membersihkan seluruh gambar saat ini dengan semua sumbunya, tetapi membiarkan jendela terbuka, sehingga dapat digunakan kembali untuk plot lainnya.plt.close()
menutup jendela , yang akan menjadi jendela saat ini, jika tidak ditentukan sebaliknya.plt.close('all')
akan menutup semua angka terbuka.Alasan yang
del fig
tidak berhasil adalah bahwapyplot
mesin-negara menyimpan referensi ke gambar di sekitar (sebagaimana mestinya jika itu akan tahu apa 'angka saat ini'). Ini berarti bahwa bahkan jika Anda menghapus referensi Anda ke angka tersebut, setidaknya ada satu referensi langsung, maka itu tidak akan pernah menjadi sampah yang dikumpulkan.Karena saya memilih pendapat kolektif di sini untuk jawaban ini, @JoeKington menyebutkan dalam komentar yang
plt.close(fig)
akan menghapus contoh figur spesifik dari mesin status pylab ( plt._pylab_helpers.Gcf ) dan mengizinkannya untuk dikumpulkan menjadi sampah.sumber
clf
untukfigure
kelas, tetapi tidakclose
. Mengapadel fig
sebenarnya tidak menutup dan menghapus gambar?close
tidak akan berfungsi pada objek gambar, panggil sajaplt.close()
, bukanfig.clf()
.del fig
tidak berhasil adalah bahwa memberikan__del__
metode (yang pada dasarnya akan memanggilplt.close(fig)
) akan berakhir menyebabkan referensi melingkar dalam kasus khusus ini, danfig
memiliki__del__
metode akan menyebabkan hal-hal lain tidak terkumpul menjadi sampah. . (Atau itu ingatan samar-samar saya, bagaimanapun.) Bagaimanapun, itu memang agak menjengkelkan, tetapi Anda harus meneleponplt.close(fig)
bukandel fig
. Sebagai tambahan, matplotlib benar-benar dapat menggunakan manajer konteks untuk ini ...plt.close(fig)
akan menghapus contoh angka spesifik dari mesin status pylab (plt._pylab_helpers.Gcf
) dan memungkinkannya menjadi sampah yang dikumpulkan.plt
agak berantakan dan ada pemikiran tentang bagaimana melakukan kembali banyak hal. Manajer konteks menarik .... Lihat github.com/matplotlib/matplotlib/pull/2736 , github.com/matplotlib/matplotlib/pull/2624Ini sedikit lebih detail untuk diperluas pada jawaban Hooked . Ketika saya pertama kali membaca jawaban itu, saya melewatkan instruksi untuk menelepon
clf()
alih-alih membuat angka baru .clf()
sendiri tidak membantu jika Anda kemudian pergi dan membuat gambar lain.Berikut ini contoh sepele yang menyebabkan peringatan:
Untuk menghindari peringatan itu, saya harus menarik panggilan ke
subplots()
luar loop. Agar terus melihat persegi panjang, saya harus beralihclf()
kecla()
. Itu membersihkan sumbu tanpa melepas sumbu itu sendiri.Jika Anda membuat plot dalam batch, Anda mungkin harus menggunakan keduanya
cla()
danclose()
. Saya mengalami masalah di mana satu batch dapat memiliki lebih dari 20 plot tanpa mengeluh, tetapi akan mengeluh setelah 20 batch. Saya memperbaikinya dengan menggunakancla()
setelah setiap plot, danclose()
setelah setiap batch.Saya mengukur kinerja untuk melihat apakah layak menggunakan kembali angka dalam satu batch, dan program sampel kecil ini melambat dari 41 menjadi 49 (20% lebih lambat) ketika saya baru saja menelepon
close()
setelah setiap plot.sumber
Jika Anda bermaksud menyimpan banyak plot secara sengaja, tetapi tidak ingin diperingatkan, Anda dapat memperbarui opsi sebelum menghasilkan angka.
Ini akan mencegah peringatan agar tidak dipancarkan tanpa mengubah apa pun tentang cara memori dikelola.
sumber
Cuplikan berikut memecahkan masalah bagi saya:
Ketika
_wrapped_figure
keluar dari ruang lingkup runtime memanggil__del__()
metode kami denganplt.close()
di dalamnya. Ini terjadi bahkan jika pengecualian menyala setelah_wrapped_figure
konstruktor.sumber
Ini juga berguna jika Anda hanya ingin untuk sementara menekan peringatan:
sumber