कथा को कथानक से बाहर कैसे रखा जाए


986

मैं 20 भूखंडों (नहीं subplots) की एक श्रृंखला के लिए एक एकल आकृति में बनाया जाना है। मैं चाहता हूं कि किंवदंती बॉक्स के बाहर हो। उसी समय, मैं कुल्हाड़ियों को बदलना नहीं चाहता, क्योंकि आकृति का आकार कम हो जाता है। निम्नलिखित प्रश्नों के लिए कृपया मेरी मदद करें:

  1. मैं किंवदंती बॉक्स को प्लॉट क्षेत्र के बाहर रखना चाहता हूं। (मैं चाहता हूं कि किंवदंती भूखंड क्षेत्र के दाईं ओर बाहर हो)।
  2. वैसे भी क्या मैं किंवदंती बॉक्स के अंदर पाठ का फ़ॉन्ट आकार कम करता हूं, ताकि किंवदंती बॉक्स का आकार छोटा हो।

14
नए matplotlib संस्करणों के लिए, यह उत्तर दिखाता है कि कैसे matplotlib को स्वचालित रूप से यह निर्धारित करने के लिए कि प्लॉट के साथ हस्तक्षेप किए बिना किंवदंती को कहां रखा जाए
dotancohen

2
एक ही सवाल था और इस महान उदाहरण को पाया जो मेरे लिए "आउट ऑफ द बॉक्स" काम करता था: matplotlib.org/1.3.1/users/legend_guide.html
robodasha

1
इस उत्तर में अधिक गहराई है https://stackoverflow.com/a/43439132/52074। और कोड की दो पंक्तियों के साथ ऐसा करता है! +1200 उत्क्रमित उत्तर भी अच्छा है लेकिन मैंने पाया कि यह कम सामान्य है।
ट्रेवर बॉयड स्मिथ

2
@dotancohen "स्वचालित रूप से निर्धारित करता है कि भूखंडों में हस्तक्षेप किए बिना किंवदंती को कहां रखा जाए" कुछ मामलों में, जब भूखंड में बहुत अधिक वक्रता होती है, तो यह दुर्भाग्य से असंभव है। उन मामलों में उपयोगकर्ता मैन्युअल रूप से किंवदंती रखना चाहता है, और वास्तव में इसे प्लॉट क्षेत्र के बाहर रख सकता है। मुझे अभी इस तरह के प्लॉट को लेकर मुश्किलें हो रही हैं।
अली

btw, नियंत्रण रेखा के विकल्पों की सूची: सबसे अच्छा; उपर से दाहिना; ऊपरी बांया; निचला बायां; निचली दाईं ओर; सही; केंद्र छोड़ दिया; केंद्र सही; निचला केंद्र; ऊपरी केंद्र; केंद्र;
Z-Y00

जवाबों:


57

आप फ़ॉन्ट गुण बनाकर किंवदंती पाठ को छोटा बना सकते हैं:

from matplotlib.font_manager import FontProperties

fontP = FontProperties()
fontP.set_size('small')
legend([plot1], "title", prop=fontP) 
# or add prop=fontP to whatever legend() call you already have

50
plot1इस जवाब में क्या है ?
पॉल एच

41
legendइस जवाब में क्या है ?
रिचर्ड

28
यह प्रश्न के द्वितीयक भाग का उत्तर देता है, लेकिन प्राथमिक नहीं (जिसका शीर्षक है)।
मतीन उल्हाक

8
इसके अलावा, ऐसा करने का उचित तरीका हैplt.legend(fontsize='small')
मतीन उल्हाक

41
यह उत्तर भयानक है और बहुत कम संदर्भ प्रदान करता है!
Tekill

1793

आप क्या चाहते हैं, इसके कई तरीके हैं। @Inalis और @Navi ने जो पहले ही कहा था, उसे जोड़ने के लिए, आप bbox_to_anchorआंशिक रूप से कुल्हाड़ियों के बाहर किंवदंती को रखने और / या फ़ॉन्ट का आकार कम करने के लिए कीवर्ड तर्क का उपयोग कर सकते हैं ।

इससे पहले कि आप फ़ॉन्ट आकार को कम करने पर विचार करें (जो चीजों को पढ़ने के लिए भयानक रूप से कठिन बना सकता है), किंवदंती को विभिन्न स्थानों पर रखने के साथ खेलने का प्रयास करें:

तो, आइए एक सामान्य उदाहरण से शुरू करते हैं:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend()

plt.show()

वैकल्पिक शब्द

यदि हम ऐसा ही करते हैं, लेकिन bbox_to_anchorकीवर्ड तर्क का उपयोग करें तो हम किंवदंती को कुल्हाड़ियों की सीमाओं के बाहर स्थानांतरित कर सकते हैं:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend(bbox_to_anchor=(1.1, 1.05))

plt.show()

वैकल्पिक शब्द

इसी तरह, आप किंवदंती को अधिक क्षैतिज बना सकते हैं और / या इसे आकृति के शीर्ष पर रख सकते हैं (मैं गोल कोनों और एक सरल ड्रॉप छाया भी बदल रहा हूं):

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05),
          ncol=3, fancybox=True, shadow=True)
plt.show()

वैकल्पिक शब्द

वैकल्पिक रूप से, आप वर्तमान प्लॉट की चौड़ाई को सिकोड़ सकते हैं, और किंवदंती को पूरी तरह से आकृति के अक्ष के बाहर रख सकते हैं (ध्यान दें: यदि आप टाइट_लेआउट () का उपयोग करते हैं , तो बाहर निकलें ax.set_position ():

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis by 20%
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

# Put a legend to the right of the current axis
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

plt.show()

वैकल्पिक शब्द

और एक समान तरीके से, आप प्लॉट को लंबवत सिकोड़ सकते हैं, और नीचे एक क्षैतिज किंवदंती डाल सकते हैं:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis's height by 10% on the bottom
box = ax.get_position()
ax.set_position([box.x0, box.y0 + box.height * 0.1,
                 box.width, box.height * 0.9])

# Put a legend below current axis
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
          fancybox=True, shadow=True, ncol=5)

plt.show()

वैकल्पिक शब्द

मैटलोट्लिब किंवदंती गाइड पर एक नज़र डालें । आप भी देख सकते हैं plt.figlegend()


10
अगर किसी को इस के साथ समस्या है, ध्यान दें कि tight_layout () मुद्दों का कारण होगा!
मैथ्यू जी।

4
बहुत बढ़िया जवाब! दस्तावेज़ में सही लिंक है matplotlib.org/users/legend_guide.html#legend-location
meduz

4
पूर्णता के रूप में, आप कह सकते हैं कि सामान्य तौर पर (डॉक से अभिव्यक्त) " bbox_to_anchor4 फ्लोट्स (x, y, चौड़ाई, बॉक्स की ऊँचाई), या सामान्यीकृत कुल्हाड़ियों में 2 फ़्लोट्स (x, y) का एक टपल है। निर्देशांक। "
मज्जा

5
मुझे यह स्वीकार करना चाहिए कि शायद मेरा सबसे अधिक दौरा किया गया एसओ उत्तर है। मैं बस इसे फिर से आने में मदद नहीं कर सकता क्योंकि कोई रास्ता नहीं है एक उचित व्यक्ति इस तर्क को यहां देखे बिना याद रख सकता है।
केटी।

9
ध्यान दें कि यदि आप किसी फ़ाइल में आकृति को सहेजना चाहते हैं, तो आपको संभवतः लौटी हुई वस्तु को स्टोर करना चाहिए, legend = ax.legend()और बाद मेंfig.savefig(bbox_extra_artists=(legend,))
कोल्डफिक्स

786

किंवदंती रखने ( bbox_to_anchor)

एक किंवदंती locतर्क का उपयोग करके कुल्हाड़ियों के बाउंडिंग बॉक्स के अंदर स्थित है plt.legend
उदाहरण के लिए loc="upper right"सीमांकन बॉक्स के ऊपरी दाहिने कोने में कथा स्थानों जो डिफ़ॉल्ट विस्तार से से (0,0)करने के लिए (1,1)कुल्हाड़ियों निर्देशांक में (या बॉक्स अंकन बाउंडिंग में (x0,y0, width, height)=(0,0,1,1))।

किंवदंती को कुल्हाड़ियों से बांधने वाले बॉक्स के बाहर रखने के लिए, कथा (x0,y0)के निचले बाएं कोने में कुल्हाड़ियों के निर्देशांक का एक टपल निर्दिष्ट किया जा सकता है ।

plt.legend(loc=(1.04,0))

हालाँकि, bbox_to_anchorतर्क का उपयोग करते हुए एक अधिक बहुमुखी दृष्टिकोण बाउंडिंग बॉक्स को मैन्युअल रूप से निर्दिष्ट करना होगा जिसमें किंवदंती को रखा जाना चाहिए । एक खुद को केवल (x0,y0)बॉक्स के हिस्से की आपूर्ति करने के लिए प्रतिबंधित कर सकता है । यह एक शून्य स्पैन बॉक्स बनाता है, जिसमें से किंवदंती locतर्क द्वारा दी गई दिशा में विस्तार करेगी । उदाहरण के लिए

plt.legend (bbox_to_anchor = (1.04,1), loc = "ऊपरी बाएँ")

कुल्हाड़ियों के बाहर किंवदंती को जगह देता है, जैसे कि किंवदंतियों के ऊपरी बाएं कोने को (1.04,1)कुल्हाड़ियों के निर्देशांक में स्थिति में है।

इसके आगे के उदाहरण नीचे दिए गए हैं, जहां इसके अतिरिक्त विभिन्न तर्कों के बीच परस्पर संबंध जैसे modeऔर ncolsदिखाए गए हैं।

यहां छवि विवरण दर्ज करें

l1 = plt.legend(bbox_to_anchor=(1.04,1), borderaxespad=0)
l2 = plt.legend(bbox_to_anchor=(1.04,0), loc="lower left", borderaxespad=0)
l3 = plt.legend(bbox_to_anchor=(1.04,0.5), loc="center left", borderaxespad=0)
l4 = plt.legend(bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
                mode="expand", borderaxespad=0, ncol=3)
l5 = plt.legend(bbox_to_anchor=(1,0), loc="lower right", 
                bbox_transform=fig.transFigure, ncol=3)
l6 = plt.legend(bbox_to_anchor=(0.4,0.8), loc="upper right")

4-टपल तर्क की व्याख्या कैसे करें bbox_to_anchor, जैसा l4कि इस प्रश्न में पाया जा सकता है । mode="expand"4-ट्यूपल द्वारा दिए गए बाउंडिंग बॉक्स के अंदर क्षैतिज रूप से किंवदंती का विस्तार। एक लंबवत विस्तारित कथा के लिए, यह प्रश्न देखें ।

कभी-कभी कुल्हाड़ियों के निर्देशांक के बजाय आंकड़ा निर्देशांक में बाउंडिंग बॉक्स को निर्दिष्ट करना उपयोगी हो सकता है। यह l5ऊपर से उदाहरण में दिखाया गया है , जहां bbox_transformआंकड़े के निचले बाएं कोने में किंवदंती को रखने के लिए तर्क का उपयोग किया जाता है।

प्रोसेसिंग के बाद

कुल्हाड़ियों के बाहर किंवदंती को रखने से अक्सर अवांछित स्थिति पैदा होती है कि यह आंकड़ा कैनवास के बाहर पूरी तरह या आंशिक रूप से होता है।

इस समस्या के समाधान हैं:

  • सबप्लॉट मापदंडों
    को समायोजित करें एक सबप्लॉट मापदंडों को समायोजित कर सकता है, जैसे कि कुल्हाड़ियों को आंकड़े के अंदर कम जगह लेते हैं (और इस तरह किंवदंती के लिए अधिक स्थान छोड़ देते हैं) plt.subplots_adjust। उदाहरण के लिए

    plt.subplots_adjust(right=0.7)

    आंकड़ा के दाईं ओर 30% स्थान छोड़ता है, जहां कोई भी किंवदंती रख सकता है।

  • तंग लेआउट
    का उपयोग करके plt.tight_layoutसबप्लॉट मापदंडों को स्वचालित रूप से समायोजित करने की अनुमति देता है जैसे कि आंकड़ा में तत्व आंकड़ा किनारों के खिलाफ तंग बैठते हैं। दुर्भाग्य से, इस ऑटोमैटिज़्म में किंवदंती को ध्यान में नहीं रखा गया है, लेकिन हम एक आयत बॉक्स की आपूर्ति कर सकते हैं जो पूरे सबप्लॉट क्षेत्र (लेबल सहित) में फिट होगा।

    plt.tight_layout(rect=[0,0,0.75,1])
  • आकृतिbbox_inches = "tight" को सहेजने के
    तर्क bbox_inches = "tight"का plt.savefigउपयोग इस आंकड़े को बचाने के लिए किया जा सकता है कि कैनवास पर सभी कलाकार (किंवदंती सहित) सहेजे गए क्षेत्र में फिट हैं। यदि आवश्यक हो, तो आंकड़ा आकार स्वचालित रूप से समायोजित किया जाता है।

    plt.savefig("output.png", bbox_inches="tight")
  • स्वचालित रूप से उपप्लॉट के समायोजन को समायोजित करने का
    एक तरीका स्वचालित रूप से उपप्लॉट स्थिति को समायोजित करने का तरीका है कि किंवदंती कैनवास के अंदर फिट होती है बिना आकृति के आकार को बदलने के इस उत्तर में पाया जा सकता है: सटीक आकार और कोई पैडिंग (और कुल्हाड़ियों के बाहर किंवदंती) के साथ आंकड़ा बनाना

ऊपर चर्चा किए गए मामलों के बीच तुलना:

यहां छवि विवरण दर्ज करें

वैकल्पिक

एक फिगर लैजेंड
वन एक्सिस के बजाय फिगर के लिए एक लेजेंड का उपयोग कर सकता है matplotlib.figure.Figure.legend। यह विशेष रूप से matplotlib संस्करण> = 2.1 के लिए उपयोगी हो गया है, जहाँ किसी विशेष तर्क की आवश्यकता नहीं है

fig.legend(loc=7) 

आकृति के विभिन्न अक्षों में सभी कलाकारों के लिए एक किंवदंती बनाने के लिए। किंवदंती को locतर्क का उपयोग करके रखा गया है, यह एक कुल्हाड़ी के अंदर कैसे रखा जाता है के समान है, लेकिन पूरे आंकड़े के संदर्भ में - इसलिए यह कुल्हाड़ियों के बाहर कुछ हद तक स्वचालित रूप से होगा। जो कुछ रहता है वह उपपलों को समायोजित करता है जैसे कि किंवदंती और अक्षों के बीच कोई ओवरलैप नहीं है। यहां ऊपर से "सबप्लॉट मापदंडों को समायोजित करें" बिंदु सहायक होगा। एक उदाहरण:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,2*np.pi)
colors=["#7aa0c4","#ca82e1" ,"#8bcd50","#e18882"]
fig, axes = plt.subplots(ncols=2)
for i in range(4):
    axes[i//2].plot(x,np.sin(x+i), color=colors[i],label="y=sin(x+{})".format(i))

fig.legend(loc=7)
fig.tight_layout()
fig.subplots_adjust(right=0.75)   
plt.show()

यहां छवि विवरण दर्ज करें

समर्पित सबप्लॉट कुल्हाड़ियों के अंदर किंवदंती
का उपयोग bbox_to_anchorकिंवदंती को अपने समर्पित सबप्लॉट कुल्हाड़ियों ( lax) में जगह देने के लिए होगा । चूंकि किंवदंती उपप्लॉट भूखंड से छोटा होना चाहिए, इसलिए हम gridspec_kw={"width_ratios":[4,1]}कुल्हाड़ियों के निर्माण में उपयोग कर सकते हैं । हम कुल्हाड़ियों छिपा कर सकते हैं lax.axis("off"), लेकिन अभी भी में एक पौराणिक कथा डाल दिया। कथा के हैंडल और लेबल के माध्यम से वास्तविक साजिश से प्राप्त करने की आवश्यकता है h,l = ax.get_legend_handles_labels(), और उसके बाद में पौराणिक कथा के आपूर्ति की जा सकती lax, subplot lax.legend(h,l)। एक पूर्ण उदाहरण नीचे है।

import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 6,2

fig, (ax,lax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[4,1]})
ax.plot(x,y, label="y=sin(x)")
....

h,l = ax.get_legend_handles_labels()
lax.legend(h,l, borderaxespad=0)
lax.axis("off")

plt.tight_layout()
plt.show()

यह एक भूखंड का निर्माण करता है जो ऊपर से दिए गए भूखंड के समान होता है:

यहां छवि विवरण दर्ज करें

हम पौराणिक कथाओं का उपयोग करने के लिए पहली कुल्हाड़ियों का भी उपयोग कर सकते हैं, लेकिन bbox_transformकिंवदंती कुल्हाड़ियों का उपयोग करें ,

ax.legend(bbox_to_anchor=(0,0,1,1), bbox_transform=lax.transAxes)
lax.axis("off")

इस दृष्टिकोण में, हमें किंवदंती के हैंडल को बाहरी रूप से प्राप्त करने की आवश्यकता नहीं है, लेकिन हमें bbox_to_anchorतर्क को निर्दिष्ट करने की आवश्यकता है ।

आगे पढ़ने और नोट्स:

  • किंवदंतियों के साथ अन्य सामानों के कुछ उदाहरणों के साथ माटप्लोटिब किंवदंती गाइड पर विचार करें ।
  • पाई चार्ट के लिए किंवदंतियों को रखने के लिए कुछ उदाहरण कोड सीधे इस प्रश्न के उत्तर में मिल सकते हैं: पायथन - लीज पाई चार्ट के साथ ओवरलैप करता है
  • locतर्क तार के बजाय संख्या है, जो कॉल को कम करने के लिए ले जा सकते हैं, हालांकि, वे बहुत सहज एक दूसरे के लिए मैप नहीं कर रहे हैं। यहाँ संदर्भ के लिए मानचित्रण है:

यहां छवि विवरण दर्ज करें


किंवदंती को एक समर्पित उपपट अक्ष अक्ष में रखना बहुत अच्छी तरह से तालमेल करता है fig.tight_layout। यदि आप plt.subplotsकुल्हाड़ियों को बनाने के लिए उपयोग कर रहे हैं , तो बस इसे कुछ gridspec_kw={'height_ratios': [100, 1]}(या width_ratios) दें जैसे कि किंवदंती की कुल्हाड़ी छोटी है ... फिर fig.tight_layout()इसे फिट करने के लिए विस्तार करेगी। कम से कम matplotlib 3.0.3 के लिए।
Travc

160

इस तरह legend()कॉल के बाद बस कॉल करें plot():

# matplotlib
plt.plot(...)
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))

# Pandas
df.myCol.plot().legend(loc='center left', bbox_to_anchor=(1, 0.5))

परिणाम कुछ इस तरह दिखेंगे:

यहां छवि विवरण दर्ज करें


4
matplotlib.pyplot.legend के समान मापदंडों को पारित करने पर भी काम करता है
अपहरण

8
क्या यह किसी और के लिए किंवदंती में शब्दों को काट देता है?
user1717828

85

प्लॉट क्षेत्र के बाहर किंवदंती लगाने के लिए, का उपयोग करें locऔर bbox_to_anchorकीवर्ड legend()। उदाहरण के लिए, निम्न कोड किंवदंती को भूखंड क्षेत्र के दाईं ओर रखेगा:

legend(loc="upper left", bbox_to_anchor=(1,1))

अधिक जानकारी के लिए, लीजेंड गाइड देखें


10
ठीक है - मुझे कार्यान्वयन पसंद है, लेकिन जब मैं आंकड़ा बचाने के लिए जाता हूं (मैन्युअल रूप से इसे विंडो में आकार दिए बिना, जो मैं हर बार नहीं करना चाहता), किंवदंती कटा हुआ हो रहा है। इस बारे में कोई विचार कि मैं इसे कैसे ठीक कर सकता हूं?
खगोलविद

@astromax मुझे यकीन नहीं है, लेकिन शायद कॉल करने का प्रयास करें plt.tight_layout()?
ईसाई एलिस

81

संक्षिप्त उत्तर: आप bbox_to_anchor+ bbox_extra_artists+ का उपयोग कर सकते हैं bbox_inches='tight'


लंबे उत्तर: आप bbox_to_anchorकिंवदंती बॉक्स के स्थान को मैन्युअल रूप से निर्दिष्ट करने के लिए उपयोग कर सकते हैं , जैसा कि कुछ अन्य लोगों ने उत्तर में दिया है।

हालाँकि, सामान्य समस्या यह है कि लीजेंड बॉक्स क्रॉप है, जैसे:

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# Plot
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(all_x, all_y)

# Add legend, title and axis labels
lgd = ax.legend( [ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
ax.set_title('Title')
ax.set_xlabel('x label')
ax.set_ylabel('y label')

fig.savefig('image_output.png', dpi=300, format='png')

यहां छवि विवरण दर्ज करें

किंवदंती बॉक्स को क्रॉप होने से रोकने के लिए, जब आप उस आकृति को बचाते हैं जो आप मापदंडों का उपयोग कर सकते हैं bbox_extra_artistsऔर सहेजे गए चित्र में क्रॉप किए गए तत्वों को शामिल करने के bbox_inchesलिए पूछ savefigसकते हैं:

fig.savefig('image_output.png', bbox_extra_artists=(lgd,), bbox_inches='tight')

उदाहरण (मैंने केवल 2 मापदंडों को जोड़ने के लिए अंतिम पंक्ति को बदल दिया है fig.savefig()):

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# Plot
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(all_x, all_y)

# Add legend, title and axis labels
lgd = ax.legend( [ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
ax.set_title('Title')
ax.set_xlabel('x label')
ax.set_ylabel('y label')    

fig.savefig('image_output.png', dpi=300, format='png', bbox_extra_artists=(lgd,), bbox_inches='tight')

यहां छवि विवरण दर्ज करें

मैं चाहता हूं कि मैटलोट्लिब मूल रूप से किंवदंती बॉक्स के लिए बाहरी स्थान की अनुमति दे, जैसा कि मतलाब करता है :

figure
x = 0:.2:12;
plot(x,besselj(1,x),x,besselj(2,x),x,besselj(3,x));
hleg = legend('First','Second','Third',...
              'Location','NorthEastOutside')
% Make the text of the legend italic and color it brown
set(hleg,'FontAngle','italic','TextColor',[.3,.2,.1])

यहां छवि विवरण दर्ज करें


6
आपको बहुत - बहुत धन्यवाद! "Bbox_to_anchor", "bbox_extra_artist" और "" bbox_inches = 'tight "पैरामीटर बिल्कुल वही थे जो मुझे इसे सही ढंग से काम करने के लिए आवश्यक थे। बहुत बढ़िया!
14

6
धन्यवाद, लेकिन वास्तव में bbox_inches='tight'bbox_extra_artist के बिना भी मेरे लिए पूरी तरह से काम करता है
Avtomaton

1
@avtomaton धन्यवाद, यह जानकर अच्छा लगा कि आप matplotlib के किस संस्करण का उपयोग करते हैं?
फ्रेंक डर्नोनकोर्ट

1
@FranckDernoncourt python3, matplotlib संस्करण 1.5.3
avtomaton

68

सभी उत्कृष्ट यहाँ जवाब, के नए संस्करण के अलावा matplotlibऔर pylabकर सकते हैं स्वचालित रूप से जहां भूखंडों में हस्तक्षेप किए बिना कथा डाल करने के लिए निर्धारित यदि संभव हो तो।

pylab.legend(loc='best')

यदि संभव हो तो यह किंवदंती को डेटा से दूर रख देगा! लोक = 'सर्वोत्तम' के उपयोग की तुलना करें

हालांकि, यदि डेटा को ओवरलैप किए बिना किंवदंती लगाने के लिए कोई जगह नहीं है, तो आप अन्य उत्तरों में से एक का प्रयास करना चाहेंगे; उपयोग loc="best"करने से कथानक के बाहर की कहानी कभी नहीं होगी ।


2
इस बारे में बताने के लिए शुक्रिया! मैंने कुछ साल पहले इसकी तलाश की और इसे नहीं पाया, और यह कुछ ऐसा है जो वास्तव में मेरे जीवन को आसान बनाता है।
एडगर एच

4
यह विकल्प मददगार है, लेकिन इस सवाल का जवाब नहीं देता है इसलिए मैंने इसे अस्वीकृत कर दिया। जहाँ तक मैं बता सकता हूँ, सबसे अच्छा कभी भी कहानी को प्लॉट के बाहर नहीं रखता
टॉमी

3
@ टॉमी: ओपी की टिप्पणियों में (जो अब प्रतीत होता है) यह स्पष्ट रूप से स्पष्ट किया गया था कि ओपी चाहता था कि किंवदंती ग्राफ डेटा को कवर न करें, और उन्होंने सोचा कि प्लॉट के बाहर केवल ऐसा करने का तरीका था। आप इसे मेफ़थी, मेटो सांचेज़, बस्तियान और रेडटेक के जवाबों में देख सकते हैं। ओपी ने एक्स के लिए कहा, लेकिन वह वाई चाहता था
डॉटचेनन

1
असल में नहीं। उसने विशेष रूप से कथानक के बाहर रहने के लिए कहा। यह सवाल के नाम पर है;) "कथानक से बाहर कैसे रखा जाए"।
३६

4
यह गारंटी नहीं देता है कि किंवदंती डेटा को अस्पष्ट नहीं करती है। बस एक बहुत घने साजिश करें - किंवदंती लगाने के लिए कोई जगह नहीं है। उदाहरण के लिए, इसे आज़माएं ... numpy आयात arange, sin, pi आयात matplotlib.pyplot के रूप में plt t = arange (0.0, 100.0, 0.01) fig = plt.figure (1) ax1 = figad_subplot (211) ax1। तितर बितर (टी, पाप (2 * पी * टी), लेबल = 'परीक्षण') ax1.grid (सच) # ax1.set_ylim ((- 2, 2)) ax1.set_ylabel ('1 हर्ट्ज') ax1.set_title ( Ax1.get_xticklabels (): label.set_color ('r') plt.legend (loc = 'best') plt.show ()
adam.r

56

संक्षिप्त उत्तर : किंवदंती पर ड्रैग करने योग्य को शामिल करें और जहां चाहें, अंतःक्रियात्मक रूप से इसे स्थानांतरित करें:

ax.legend().draggable()

दीर्घ उत्तर : यदि आप प्रोग्राम के बजाय पौराणिक रूप से / मैन्युअल रूप से लीजेंड को रखना पसंद करते हैं, तो आप लीजेंड के ड्रैग करने योग्य मोड को टॉगल कर सकते हैं ताकि आप इसे जहां चाहें वहां खींच सकें। नीचे दिए गए उदाहरण की जाँच करें:

import matplotlib.pylab as plt
import numpy as np
#define the figure and get an axes instance
fig = plt.figure()
ax = fig.add_subplot(111)
#plot the data
x = np.arange(-5, 6)
ax.plot(x, x*x, label='y = x^2')
ax.plot(x, x*x*x, label='y = x^3')
ax.legend().draggable()
plt.show()

यकीन नहीं होता कि मैं इसे पूरी तरह से समझता हूं। इसके साथ मैं जहां भी चाहता हूं, मैं किंवदंती को "कैसे" खींचूं? मैं 20th पर Python 3.6 और Jupyter नोटबुक
sb2020

14

जैसा आपने पूछा, वैसा बिल्कुल नहीं, लेकिन मैंने पाया कि यह उसी समस्या का एक विकल्प है। किंवदंती को अर्ध-पारदर्शी बनाएं, जैसे: अर्ध पारदर्शी किंवदंती और अर्ध-पाठ पाठ बॉक्स के साथ matplotlib प्लॉट

इसके साथ करें:

fig = pylab.figure()
ax = fig.add_subplot(111)
ax.plot(x,y,label=label,color=color)
# Make the legend transparent:
ax.legend(loc=2,fontsize=10,fancybox=True).get_frame().set_alpha(0.5)
# Make a transparent text box
ax.text(0.02,0.02,yourstring, verticalalignment='bottom',
                     horizontalalignment='left',
                     fontsize=10,
                     bbox={'facecolor':'white', 'alpha':0.6, 'pad':10},
                     transform=self.ax.transAxes)

8

जैसा कि कहा गया है, आप किंवदंती को कथानक में रख सकते हैं, या किनारे से थोड़ा दूर भी कर सकते हैं। यहाँ एक उदाहरण प्लॉटली पायथन एपीआई का उपयोग करके बनाया गया है, जो एक आईपाइथन नोटबुक के साथ बनाया गया है । मैं टीम में हूं।

शुरू करने के लिए, आप आवश्यक पैकेज स्थापित करना चाहेंगे:

import plotly
import math
import random
import numpy as np

फिर, प्लॉटली स्थापित करें:

un='IPython.Demo'
k='1fw3zw2o13'
py = plotly.plotly(username=un, key=k)


def sin(x,n):
sine = 0
for i in range(n):
    sign = (-1)**i
    sine = sine + ((x**(2.0*i+1))/math.factorial(2*i+1))*sign
return sine

x = np.arange(-12,12,0.1)

anno = {
'text': '$\\sum_{k=0}^{\\infty} \\frac {(-1)^k x^{1+2k}}{(1 + 2k)!}$',
'x': 0.3, 'y': 0.6,'xref': "paper", 'yref': "paper",'showarrow': False,
'font':{'size':24}
}

l = {
'annotations': [anno], 
'title': 'Taylor series of sine',
'xaxis':{'ticks':'','linecolor':'white','showgrid':False,'zeroline':False},
'yaxis':{'ticks':'','linecolor':'white','showgrid':False,'zeroline':False},
'legend':{'font':{'size':16},'bordercolor':'white','bgcolor':'#fcfcfc'}
}

py.iplot([{'x':x, 'y':sin(x,1), 'line':{'color':'#e377c2'}, 'name':'$x\\\\$'},\
      {'x':x, 'y':sin(x,2), 'line':{'color':'#7f7f7f'},'name':'$ x-\\frac{x^3}{6}$'},\
      {'x':x, 'y':sin(x,3), 'line':{'color':'#bcbd22'},'name':'$ x-\\frac{x^3}{6}+\\frac{x^5}{120}$'},\
      {'x':x, 'y':sin(x,4), 'line':{'color':'#17becf'},'name':'$ x-\\frac{x^5}{120}$'}], layout=l)

यह आपका ग्राफ बनाता है, और आपको कथानक के भीतर किंवदंती रखने का मौका देता है। किंवदंती के लिए डिफ़ॉल्ट यदि यह सेट नहीं है, तो इसे प्लॉट में रखना है, जैसा कि यहां दिखाया गया है।

यहां छवि विवरण दर्ज करें

एक वैकल्पिक स्थान के लिए, आप किंवदंती के ग्राफ और सीमा के किनारे को बारीकी से संरेखित कर सकते हैं, और एक करीब फिट के लिए सीमा रेखाओं को हटा सकते हैं।

यहां छवि विवरण दर्ज करें

आप किंवदंती और ग्राफ़ को कोड के साथ, या GUI के साथ स्थानांतरित कर सकते हैं। किंवदंती को स्थानांतरित करने के लिए, आपके पास <= 1. उदाहरण: x और y मान निर्दिष्ट करके ग्राफ़ के अंदर किंवदंती को रखने के लिए निम्नलिखित विकल्प हैं:

  • {"x" : 0,"y" : 0} -- नीचे बाएँ
  • {"x" : 1, "y" : 0} -- नीचे दाएं
  • {"x" : 1, "y" : 1} -- दायां शीर्ष
  • {"x" : 0, "y" : 1} -- बाएं से बाएं
  • {"x" :.5, "y" : 0} -- निचला मध्यम
  • {"x": .5, "y" : 1} -- शीर्ष केंद्र

इस मामले में, हम ऊपरी दाईं ओर चुनते हैं legendstyle = {"x" : 1, "y" : 1}, दस्तावेज में भी वर्णित है :

यहां छवि विवरण दर्ज करें


3

इन पंक्तियों के साथ कुछ मेरे लिए काम किया। जो से लिया गया कोड का एक सा के साथ शुरू, यह विधि स्वचालित रूप से आंकड़ा के दाईं ओर एक किंवदंती फिट करने के लिए खिड़की की चौड़ाई को संशोधित करता है।

import matplotlib.pyplot as plt
import numpy as np

plt.ion()

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$'%i)

# Put a legend to the right of the current axis
leg = ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

plt.draw()

# Get the ax dimensions.
box = ax.get_position()
xlocs = (box.x0,box.x1)
ylocs = (box.y0,box.y1)

# Get the figure size in inches and the dpi.
w, h = fig.get_size_inches()
dpi = fig.get_dpi()

# Get the legend size, calculate new window width and change the figure size.
legWidth = leg.get_window_extent().width
winWidthNew = w*dpi+legWidth
fig.set_size_inches(winWidthNew/dpi,h)

# Adjust the window size to fit the figure.
mgr = plt.get_current_fig_manager()
mgr.window.wm_geometry("%ix%i"%(winWidthNew,mgr.window.winfo_height()))

# Rescale the ax to keep its original size.
factor = w*dpi/winWidthNew
x0 = xlocs[0]*factor
x1 = xlocs[1]*factor
width = box.width*factor
ax.set_position([x0,ylocs[0],x1-x0,ylocs[1]-ylocs[0]])

plt.draw()

मुझे यह काफी उपयोगी लगा और इसने मेरे लिए काम किया। ध्यान दें कि यदि आप wx बैकएंड में हैं (जैसे कि विंडोज़ का उपयोग कर रहे हैं), तो mgr.window.wm_geometry ("% ix% i"% (winWidthNew, mgr.window.winfo_height ())) को mgr.window.SetClientSizeWH (winWidthNewN) से बदलें , winHeightNew) या जैसे
ईजेकील क्रूगलिक

यदि आप Qt4Agg बैकएंड का उपयोग कर रहे हैं (जो कि मेरी लिनक्स इंस्टॉलेशन matplotlib पर डिफ़ॉल्ट है), तो इसके mgr.window.wm_geometry(...)साथ लाइन को बदलें mgr.window.setFixedWidth(winWidthNew)
फिलिप एस।

और, जैसा कि मैंने अभी-अभी खोजा है, यदि आप एक बैकएंड का उपयोग कर रहे हैं, जो किसी भी विंडो को नहीं दिखाता है, जो सीधे एक फाइल (एसवीजी और एजीजी बैकेंड की तरह) को बचाने के लिए हैं, बस विंडो को पूरी तरह से छोड़ दें। fig.set_size_inches(...)आप की जरूरत के आकार का ख्याल रखता है।
फिलिप एस।

3

यह इस सवाल को ताज़ा करने के लायक है, क्योंकि माटप्लोटलिब के नए संस्करणों ने कथानक के बाहर किंवदंती को स्थापित करना बहुत आसान बना दिया है। मैंने इस उदाहरण का उत्पादन Matplotlib संस्करण के साथ किया 3.1.1

उपयोगकर्ता locपैरामीटर को बाउंडिंग बॉक्स में कहीं भी रखने के लिए निर्देशांक के 2-टपल को पास कर सकते हैं । एकमात्र गोटा है जिसे आपको plt.tight_layout()प्लॉट आयामों को पुनः प्राप्त करने के लिए matplotlib प्राप्त करने के लिए चलाने की आवश्यकता है ताकि किंवदंती दिखाई दे:

import matplotlib.pyplot as plt

plt.plot([0, 1], [0, 1], label="Label 1")
plt.plot([0, 1], [0, 2], label='Label 2')

plt.legend(loc=(1.05, 0.5))
plt.tight_layout()

यह निम्नलिखित साजिश की ओर जाता है:

बाहर किंवदंती के साथ साजिश

संदर्भ:


2

आप भी आजमा सकते हैं figlegend। किसी भी अक्ष वस्तु से स्वतंत्र एक किंवदंती बनाना संभव है। हालाँकि, आपको कुछ "डमी" पथ बनाने की आवश्यकता हो सकती है ताकि यह सुनिश्चित हो सके कि ऑब्जेक्ट के लिए फ़ॉर्मेटिंग सही तरीके से पास हो।


1

यहां दिए गए matplotlib ट्यूटोरियल से एक उदाहरण दिया गया है । यह अधिक सरल उदाहरणों में से एक है, लेकिन मैंने किंवदंती में पारदर्शिता जोड़ी और plt.show () को जोड़ा ताकि आप इसे इंटरैक्टिव शेल में पेस्ट कर सकें और एक परिणाम प्राप्त कर सकें:

import matplotlib.pyplot as plt
p1, = plt.plot([1, 2, 3])
p2, = plt.plot([3, 2, 1])
p3, = plt.plot([2, 3, 1])
plt.legend([p2, p1, p3], ["line 1", "line 2", "line 3"]).get_frame().set_alpha(0.5)
plt.show()

1

जब मेरे पास विशाल किंवदंती थी, तो मेरे लिए काम करने वाला समाधान अतिरिक्त खाली छवि लेआउट का उपयोग करना था। निम्नलिखित उदाहरण में मैंने 4 पंक्तियाँ बनाईं और सबसे नीचे मैंने लीजेंड (bbox_to_anchor) के लिए ऑफ़सेट के साथ छवि तैयार की जो शीर्ष पर नहीं है।

f = plt.figure()
ax = f.add_subplot(414)
lgd = ax.legend(loc='upper left', bbox_to_anchor=(0, 4), mode="expand", borderaxespad=0.3)
ax.autoscale_view()
plt.savefig(fig_name, format='svg', dpi=1200, bbox_extra_artists=(lgd,), bbox_inches='tight')

1

यहां एक और समाधान है, जो जोड़ने के समान है bbox_extra_artistsऔर bbox_inchesजहां आपको अपने अतिरिक्त कलाकारों को अपने savefigकॉल के दायरे में नहीं रखना है । जब से मैं अपने अधिकांश प्लॉट को फंक्शन्स के अंदर जेनरेट करता हूं, मैं इसके साथ आ गया।

बाउंडिंग बॉक्स में अपने सभी अतिरिक्त जोड़ने के बजाय जब आप इसे लिखना चाहते हैं, तो आप उन्हें समय से पहले जोड़ सकते हैं Figureऊपर फ्रेंक डर्नोनकोर्ट के उत्तर के समान कुछ का उपयोग करना :

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# plotting function
def gen_plot(x, y):
    fig = plt.figure(1)
    ax = fig.add_subplot(111)
    ax.plot(all_x, all_y)
    lgd = ax.legend( [ "Lag " + str(lag) for lag in all_x], loc="center right", bbox_to_anchor=(1.3, 0.5))
    fig.artists.append(lgd) # Here's the change
    ax.set_title("Title")
    ax.set_xlabel("x label")
    ax.set_ylabel("y label")
    return fig

# plotting
fig = gen_plot(all_x, all_y)

# No need for `bbox_extra_artists`
fig.savefig("image_output.png", dpi=300, format="png", bbox_inches="tight")

यहाँ उत्पन्न प्लॉट है।


-1

नहीं जानता कि क्या आपने पहले ही अपना मुद्दा सुलझा लिया है ... शायद हाँ, लेकिन ... मैंने बस स्थान के लिए 'बाहर' स्ट्रिंग का इस्तेमाल किया, जैसे कि मटमैब में। मैंने matplotlib से पाइलब का आयात किया। कोड निम्नानुसार देखें:

from matplotlib as plt
from matplotlib.font_manager import FontProperties
...
...
t = A[:,0]
sensors = A[:,index_lst]

for i in range(sensors.shape[1]):
    plt.plot(t,sensors[:,i])

plt.xlabel('s')
plt.ylabel('°C')
lgd = plt.legend(b,loc='center left', bbox_to_anchor=(1, 0.5),fancybox = True, shadow = True)

प्लॉट देखने के लिए क्लिक करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.