Saya memiliki serangkaian 20 plot (bukan subplot) untuk dibuat dalam satu gambar. Saya ingin legenda berada di luar kotak. Pada saat yang sama, saya tidak ingin mengganti sumbu, karena ukuran gambar menjadi berkurang. Mohon bantu saya untuk pertanyaan berikut:
- Saya ingin menyimpan kotak legenda di luar area plot. (Saya ingin legenda berada di luar di sisi kanan area plot).
- Apakah ada yang mengurangi ukuran font teks di dalam kotak legenda, sehingga ukuran kotak legenda akan kecil.
python
matplotlib
legend
pottigopi
sumber
sumber
https://stackoverflow.com/a/43439132/52074
. dan melakukannya dengan dua baris kode! jawaban tervotifikasi +1200 juga bagus tetapi saya merasa kurang generik.Jawaban:
Anda dapat membuat teks legenda lebih kecil dengan membuat properti font:
sumber
plot1
di jawaban ini?legend
di jawaban ini?plt.legend(fontsize='small')
Ada sejumlah cara untuk melakukan apa yang Anda inginkan. Untuk menambah apa yang sudah dikatakan @inalis dan @Navi, Anda bisa menggunakan
bbox_to_anchor
argumen kata kunci untuk menempatkan legenda sebagian di luar sumbu dan / atau mengurangi ukuran font.Sebelum Anda mempertimbangkan untuk mengurangi ukuran font (yang dapat membuat hal-hal sangat sulit dibaca), cobalah bermain-main dengan menempatkan legenda di tempat yang berbeda:
Jadi, mari kita mulai dengan contoh umum:
Jika kami melakukan hal yang sama, tetapi menggunakan
bbox_to_anchor
argumen kata kunci, kami dapat menggeser legenda sedikit di luar batas sumbu:Demikian pula, Anda dapat membuat legenda lebih horizontal dan / atau meletakkannya di bagian atas gambar (saya juga menyalakan sudut bulat dan drop shadow sederhana):
Sebagai alternatif, Anda dapat mengecilkan lebar plot saat ini, dan meletakkan legenda sepenuhnya di luar sumbu gambar (catatan: jika Anda menggunakan tight_layout () , lalu tinggalkan ax.set_position ():
Dan dengan cara yang sama, Anda dapat mengecilkan plot secara vertikal, dan meletakkan legenda horizontal di bagian bawah:
Lihatlah panduan legenda matplotlib . Anda mungkin juga melihatnya
plt.figlegend()
.sumber
bbox_to_anchor
adalah tuple dari 4 float (x, y, lebar, tinggi bbox), atau tuple dari 2 float (x, y) dalam sumbu dinormalisasi koordinat. "legend = ax.legend()
dan kemudianfig.savefig(bbox_extra_artists=(legend,))
Menempatkan legenda (
bbox_to_anchor
)Legenda diposisikan di dalam kotak pembatas dari sumbu menggunakan
loc
argumen untukplt.legend
.Misalnya
loc="upper right"
menempatkan legenda di sudut kanan atas kotak pembatas, yang secara default meluas dari(0,0)
ke(1,1)
dalam koordinat sumbu (atau dalam notasi pembatas kotak(x0,y0, width, height)=(0,0,1,1)
).Untuk menempatkan legenda di luar kotak pembatas sumbu, seseorang dapat menentukan tupel
(x0,y0)
koordinat sumbu dari sudut kiri bawah legenda.Namun, pendekatan yang lebih fleksibel adalah dengan menentukan secara manual kotak pembatas di mana legenda harus ditempatkan, menggunakan
bbox_to_anchor
argumen. Seseorang dapat membatasi diri hanya untuk memasok(x0,y0)
bagian dari bbox. Ini menciptakan kotak rentang nol, di mana legenda akan berkembang ke arah yang diberikan olehloc
argumen. Misalnyamenempatkan legenda di luar sumbu, sehingga sudut kiri atas legenda berada pada posisi
(1.04,1)
dalam koordinat sumbu.Contoh lebih lanjut diberikan di bawah ini, di mana tambahan interaksi antara argumen yang berbeda seperti
mode
danncols
ditampilkan.Rincian tentang bagaimana menafsirkan argumen 4-tuple
bbox_to_anchor
, seperti padal4
, dapat ditemukan dalam pertanyaan ini . Themode="expand"
memperluas legenda horizontal dalam kotak berlari diberikan oleh 4-tupel. Untuk legenda yang diperluas secara vertikal, lihat pertanyaan ini .Kadang-kadang mungkin berguna untuk menentukan kotak pembatas dalam koordinat angka, bukan koordinat sumbu. Ini ditunjukkan dalam contoh
l5
dari atas, di manabbox_transform
argumen digunakan untuk meletakkan legenda di sudut kiri bawah gambar.Pengolahan pasca
Setelah menempatkan legenda di luar sumbu sering mengarah pada situasi yang tidak diinginkan bahwa itu sepenuhnya atau sebagian di luar kanvas gambar.
Solusi untuk masalah ini adalah:
Menyesuaikan parameter subplot
Seseorang dapat menyesuaikan parameter subplot sedemikian rupa, sehingga sumbu mengambil lebih sedikit ruang di dalam gambar (dan dengan demikian meninggalkan lebih banyak ruang untuk legenda) dengan menggunakan
plt.subplots_adjust
. Misalnyamenyisakan 30% ruang di sisi kanan gambar, di mana orang bisa menempatkan legenda.
Tata letak yang ketat
Menggunakan
plt.tight_layout
Memungkinkan untuk secara otomatis menyesuaikan parameter subplot sedemikian rupa sehingga elemen-elemen pada gambar berada pada tepi gambar. Sayangnya, legenda tersebut tidak diperhitungkan dalam otomatisme ini, tetapi kami dapat menyediakan kotak persegi panjang yang dapat digunakan oleh seluruh area subplot (termasuk label).Menyimpan gambar dengan
bbox_inches = "tight"
Argumen
bbox_inches = "tight"
untukplt.savefig
dapat digunakan untuk menyimpan gambar sedemikian rupa sehingga semua artis di kanvas (termasuk legenda) masuk ke dalam area yang disimpan. Jika perlu, ukuran gambar disesuaikan secara otomatis.Cara untuk menyesuaikan posisi subplot secara otomatis sehingga legenda pas di dalam kanvas tanpa mengubah ukuran gambar dapat ditemukan dalam jawaban ini: Membuat gambar dengan ukuran tepat dan tanpa bantalan (dan legenda di luar sumbu)
Perbandingan antara kasus-kasus yang dibahas di atas:
Alternatif
Legenda figur
Seseorang dapat menggunakan legenda untuk figur alih-alih sumbu
matplotlib.figure.Figure.legend
,. Ini menjadi sangat berguna untuk versi matplotlib> = 2.1, di mana tidak ada argumen khusus yang diperlukanuntuk menciptakan legenda bagi semua seniman di sumbu yang berbeda dari gambar. Legenda ditempatkan menggunakan
loc
argumen, mirip dengan bagaimana ia ditempatkan di dalam sumbu, tetapi mengacu pada keseluruhan gambar - maka itu akan berada di luar sumbu agak otomatis. Yang tersisa adalah menyesuaikan subplot sehingga tidak ada tumpang tindih antara legenda dan sumbu. Di sini titik "Sesuaikan parameter subplot" dari atas akan sangat membantu. Sebuah contoh:Legenda di dalam kapak subplot khusus
Alternatif untuk menggunakan
bbox_to_anchor
adalah menempatkan legenda dalam kapak subplot khusus (lax
). Karena subplot legenda harus lebih kecil dari plot, kita dapat menggunakangridspec_kw={"width_ratios":[4,1]}
pada pembuatan sumbu. Kita dapat menyembunyikan sumbulax.axis("off")
tetapi masih memasukkan legenda. Legenda menangani dan label perlu diperoleh dari plot nyata melaluih,l = ax.get_legend_handles_labels()
, dan kemudian dapat dipasok ke legenda dilax
subplotlax.legend(h,l)
,. Contoh lengkapnya ada di bawah ini.Ini menghasilkan plot yang secara visual sangat mirip dengan plot dari atas:
Kita juga bisa menggunakan kapak pertama untuk menempatkan legenda, tetapi gunakan
bbox_transform
kapak legenda,Dalam pendekatan ini, kita tidak perlu mendapatkan gagang legenda secara eksternal, tetapi kita perlu menentukan
bbox_to_anchor
argumennya.Bacaan dan catatan lebih lanjut:
loc
Argumen dapat mengambil angka bukan string, yang membuat panggilan pendek, namun, mereka tidak sangat intuitif dipetakan ke satu sama lain. Berikut adalah pemetaan untuk referensi:sumber
fig.tight_layout
. Jika Anda menggunakanplt.subplots
untuk membuat sumbu, cukup berikan sesuatu sepertigridspec_kw={'height_ratios': [100, 1]}
(atau width_ratios) sehingga sumbu legenda itu kecil ... Kemudianfig.tight_layout()
akan diperluas agar sesuai. Setidaknya untuk matplotlib 3.0.3.Panggil saja panggilan
legend()
setelahplot()
panggilan seperti ini:Hasilnya akan terlihat seperti ini:
sumber
Untuk menempatkan legenda di luar area plot, gunakan
loc
danbbox_to_anchor
kata kunci darilegend()
. Misalnya, kode berikut akan menempatkan legenda di sebelah kanan area plot:Untuk info lebih lanjut, lihat panduan legenda
sumber
plt.tight_layout()
?Jawaban singkat: Anda dapat menggunakan
bbox_to_anchor
+bbox_extra_artists
+bbox_inches='tight'
.Jawaban yang lebih panjang: Anda dapat menggunakan
bbox_to_anchor
untuk secara manual menentukan lokasi kotak legenda, seperti yang ditunjukkan beberapa orang lainnya dalam jawaban.Namun, masalah yang biasa terjadi adalah kotak legenda dipangkas, misalnya:
Untuk mencegah kotak legenda dipotong, ketika Anda menyimpan gambar, Anda dapat menggunakan parameter
bbox_extra_artists
danbbox_inches
memintasavefig
untuk memasukkan elemen yang dipotong dalam gambar yang disimpan:fig.savefig('image_output.png', bbox_extra_artists=(lgd,), bbox_inches='tight')
Contoh (Saya hanya mengubah baris terakhir untuk menambahkan 2 parameter
fig.savefig()
):Saya berharap matplotlib akan mengizinkan lokasi di luar untuk kotak legenda seperti yang dilakukan Matlab :
sumber
bbox_inches='tight'
berfungsi dengan baik untuk saya bahkan tanpa bbox_extra_artistSelain semua jawaban yang sangat baik di sini, versi yang lebih baru
matplotlib
dan secara otomatispylab
dapat menentukan di mana menempatkan legenda tanpa mengganggu plot , jika memungkinkan.Ini akan secara otomatis membuat legenda menjauh dari data jika memungkinkan!
Namun, jika tidak ada tempat untuk meletakkan legenda tanpa tumpang tindih data, maka Anda akan ingin mencoba salah satu jawaban lainnya; menggunakan
loc="best"
tidak akan pernah menempatkan legenda di luar plot.sumber
Jawaban Singkat : Aktifkan draggable pada legenda dan pindahkan secara interaktif ke mana pun Anda inginkan:
Jawaban Panjang : Jika Anda lebih suka menempatkan legenda secara interaktif / manual daripada secara terprogram, Anda dapat mengaktifkan mode legenda yang dapat diseret sehingga Anda dapat menyeretnya ke mana pun Anda inginkan. Lihat contoh di bawah ini:
sumber
Tidak persis apa yang Anda minta, tetapi saya menemukan itu alternatif untuk masalah yang sama. Jadikan legenda semi transparan, seperti:
Lakukan ini dengan:
sumber
Seperti yang disebutkan, Anda juga bisa menempatkan legenda di plot, atau sedikit melenceng ke tepi juga. Berikut adalah contoh menggunakan Plotly Python API , dibuat dengan IPython Notebook . Saya di tim.
Untuk memulai, Anda ingin menginstal paket yang diperlukan:
Kemudian, instal Plotly:
Ini membuat grafik Anda, dan memberi Anda kesempatan untuk menyimpan legenda di dalam plot itu sendiri. Default untuk legenda jika tidak disetel adalah menempatkannya dalam plot, seperti yang ditunjukkan di sini.
Untuk penempatan alternatif, Anda dapat menyelaraskan tepi grafik dan tepi legenda dengan dekat, dan menghapus garis batas untuk kesesuaian yang lebih dekat.
Anda dapat memindahkan dan menata ulang legenda dan grafik dengan kode, atau dengan GUI. Untuk menggeser legenda, Anda memiliki opsi berikut untuk memposisikan legenda di dalam grafik dengan menetapkan nilai x dan y dari <= 1. Misalnya:
{"x" : 0,"y" : 0}
-- Kiri bawah{"x" : 1, "y" : 0}
-- Kanan bawah{"x" : 1, "y" : 1}
-- Kanan atas{"x" : 0, "y" : 1}
- Kiri Atas{"x" :.5, "y" : 0}
-- Tengah bawah{"x": .5, "y" : 1}
- Pusat AtasDalam hal ini, kami memilih kanan atas
legendstyle = {"x" : 1, "y" : 1}
,, juga dijelaskan dalam dokumentasi :sumber
Sesuatu di sepanjang garis ini bekerja untuk saya. Dimulai dengan sedikit kode yang diambil dari Joe, metode ini memodifikasi lebar jendela untuk secara otomatis sesuai dengan legenda di sebelah kanan gambar.
sumber
mgr.window.wm_geometry(...)
denganmgr.window.setFixedWidth(winWidthNew)
.fig.set_size_inches(...)
mengurus ukuran yang Anda butuhkan.Sebaiknya segarkan pertanyaan ini, karena versi Matplotlib yang lebih baru telah membuatnya lebih mudah untuk memposisikan legenda di luar plot. Saya menghasilkan contoh ini dengan versi Matplotlib
3.1.1
.Pengguna dapat memberikan koordinat 2-tupel ke
loc
parameter untuk memposisikan legenda di mana saja di kotak pembatas. Satu-satunya gotcha adalah Anda harus menjalankanplt.tight_layout()
untuk mendapatkan matplotlib untuk menghitung ulang dimensi plot sehingga legenda terlihat:Ini mengarah ke plot berikut:
Referensi:
sumber
Anda juga bisa mencoba
figlegend
. Dimungkinkan untuk membuat legenda yang independen dari objek Axes apa pun. Namun, Anda mungkin perlu membuat beberapa Path "dummy" untuk memastikan pemformatan objek diteruskan dengan benar.sumber
Berikut adalah contoh dari tutorial matplotlib yang ditemukan di sini . Ini adalah salah satu contoh yang lebih sederhana tetapi saya menambahkan transparansi ke legenda dan menambahkan plt.show () sehingga Anda dapat menempelkan ini ke shell interaktif dan mendapatkan hasilnya:
sumber
Solusi yang bekerja untuk saya ketika saya memiliki legenda besar adalah menggunakan tata letak gambar ekstra kosong. Dalam contoh berikut ini saya membuat 4 baris dan di bagian bawah saya memplot gambar dengan offset untuk legenda (bbox_to_anchor) di bagian atas tidak memotong.
sumber
Inilah solusi lain, mirip dengan menambahkan
bbox_extra_artists
danbbox_inches
, di mana Anda tidak harus memiliki artis tambahan dalam lingkup Andasavefig
panggilan . Saya datang dengan ini karena saya menghasilkan sebagian besar fungsi plot saya.Alih-alih menambahkan semua tambahan Anda ke kotak pembatas ketika Anda ingin menuliskannya, Anda dapat menambahkannya sebelumnya ke
Figure
artis. Menggunakan sesuatu yang mirip dengan jawaban Franck Dernoncourt di atas :Inilah plot yang dihasilkan.
sumber
tidak tahu apakah Anda sudah menyelesaikan masalah Anda ... mungkin ya, tapi ... Saya hanya menggunakan string 'luar' untuk lokasi, seperti di matlab. Saya mengimpor pylab dari matplotlib. lihat kode sebagai berikut:
Klik untuk melihat alurnya
sumber