python - साजिश से पौराणिक कथाओं को कैसे रखा जाए




matplotlib legend (11)

पौराणिक कथा ( bbox_to_anchor )

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

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

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

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

plt.legend(bbox_to_anchor=(1.04,1), loc="upper left")

अक्षों के बाहर पौराणिक कथाओं को (1.04,1) करता है, जैसे कि किंवदंती के ऊपरी बाएं कोने अक्ष निर्देशांक में स्थिति (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")

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

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

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

अक्षों के बाहर पौराणिक कथाओं को रखने से अक्सर अवांछित स्थिति होती है कि यह आकृति कैनवास के बाहर पूरी तरह से या आंशिक रूप से है।

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

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

    plt.subplots_adjust(right=0.7)
    

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

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

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

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

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

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

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

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

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


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

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()

जब मेरे पास बड़ी किंवदंती थी तो मेरे लिए काम किया गया समाधान अतिरिक्त खाली छवि लेआउट का उपयोग करना था। निम्नलिखित उदाहरण में मैंने 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')

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

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)

साजिश देखने के लिए क्लिक करें


फ़ॉन्ट गुण बनाएँ

from matplotlib.font_manager import FontProperties

fontP = FontProperties()
fontP.set_size('small')
legend([plot1], "title", prop=fontP)

यदि आप पांडस plot() रैपर फ़ंक्शन का उपयोग कर रहे हैं और बाहर किंवदंती रखना चाहते हैं तो यहां बहुत आसान तरीका है:

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

plot() बाद हम सिर्फ श्रृंखला legend() कॉल करते हैं।

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


यहां एक और समाधान है, जो 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")

यहां जेनरेट की गई साजिश है।


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

pylab.legend(loc='best')

यह साजिश के बाहर पौराणिक कथाओं को स्वचालित रूप से रखेगा!


संक्षिप्त उत्तर: आप 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')

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

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

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

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')

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

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])


संक्षिप्त उत्तर : किंवदंती पर ड्रैगगेबल को आमंत्रित करें और जहां चाहें इसे इंटरैक्टिव रूप से ले जाएं:

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()




legend