pyplot तितर बितर साजिश मार्कर आकार


376

स्कैटर प्लॉट के लिए पाइलट दस्तावेज़ में:

matplotlib.pyplot.scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None,
                          vmin=None, vmax=None, alpha=None, linewidths=None,
                          faceted=True, verts=None, hold=None, **kwargs)

मार्कर का आकार

s: अंकों में आकार ^ 2। यह एक स्केलर या एक्स और वाई के समान लंबाई की एक सरणी है।

किस प्रकार की इकाई है points^2? इसका क्या मतलब है? करता है s=100मतलब है 10 pixel x 10 pixel?

मूल रूप से मैं अलग-अलग मार्कर आकारों के साथ तितर बितर भूखंड बनाने की कोशिश कर रहा हूं, और मैं यह पता लगाना चाहता हूं कि sसंख्या का क्या मतलब है।


बहुत यकीन है कि अंक वही इकाइयां हैं जो फोंट के लिए उपयोग की जाती हैं।
ताकसवेल

@ tcaswell, आपका मतलब s=20है कि मार्कर आकार एक fontsize=20अक्षर के बराबर है?
LWZ

नहीं, क्षेत्र 20 अंक ^ 2 होगा, एक fontsize=20पत्र 20 pts लंबा है (या कभी भी फ़ॉन्ट में संदर्भ चरित्र 20 pts लंबा है)।
ताकसवेल

23
matplotlib.pyplot.plot()है msपैरामीटर ( markersize) के लिए एक समान matplotlib.pyplot.scatter()पैरामीटर s( size)। बस एक अनुस्मारक ..
niekas

@neikas यह मुझे लगता है कि वे नहीं हैं, क्योंकि एक पिक्सेल (मार्कर) में है और अन्य इस अजीब वर्ग बिंदु इकाई (आकार) में है। यह हमेशा मेरे लिए भ्रमित करने वाला रहा है, लेकिन मेरा मानना ​​है कि इसे स्कैल्प्लॉट मार्कर के आकार के साथ करना है, जिसका उपयोग नेत्रहीन आनुपातिक तरीके से राशि को दर्शाने के लिए किया जाता है।
हेल्टनबीकर

जवाबों:


406

यह आकार को परिभाषित करने का कुछ भ्रमित तरीका हो सकता है लेकिन आप मूल रूप से मार्कर के क्षेत्र को निर्दिष्ट कर रहे हैं । इसका मतलब है, मार्कर की चौड़ाई (या ऊँचाई) को दोगुना करने के लिए आपको s4. के कारक से बढ़ाना होगा । [क्योंकि A = W H => (2W) (2H) = 4A]

हालाँकि, एक कारण यह है कि मार्करों के आकार को इस तरह से परिभाषित किया गया है। चौड़ाई के वर्ग के रूप में क्षेत्र के स्केलिंग के कारण, चौड़ाई को दोगुना करना वास्तव में एक कारक 2 से अधिक आकार में वृद्धि करता प्रतीत होता है (वास्तव में यह इसे 4 के कारक से बढ़ाता है)। इसे देखने के लिए निम्नलिखित दो उदाहरणों और उनके द्वारा उत्पादित आउटपुट पर विचार करें।

# doubling the width of markers
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [20*4**n for n in range(len(x))]
plt.scatter(x,y,s=s)
plt.show()

देता है

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

ध्यान दें कि आकार बहुत तेज़ी से कैसे बढ़ता है। अगर इसके बजाय हमारे पास है

# doubling the area of markers
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [20*2**n for n in range(len(x))]
plt.scatter(x,y,s=s)
plt.show()

देता है

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

अब मार्करों का स्पष्ट आकार सहज ज्ञान युक्त रूप से रैखिक रूप से बढ़ता है।

जैसा कि एक 'बिंदु' के सटीक अर्थ के लिए, यह प्लॉटिंग उद्देश्यों के लिए काफी हद तक मनमाना है, आप अपने सभी आकारों को एक निरंतरता तक माप सकते हैं जब तक कि वे उचित न दिखें।

उम्मीद है की यह मदद करेगा!

संपादित करें: (@Emma से टिप्पणी के जवाब में)

यह शायद मेरी ओर से भ्रमित करने वाला है। प्रत्येक सर्कल के लिए पहली तस्वीर में एक सर्कल की चौड़ाई को दोगुना करने के बारे में पूछा गया सवाल (जैसा कि हम बाएं से दाएं चलते हैं) यह चौड़ाई पिछले एक से दोगुना है, इसलिए यह क्षेत्र आधार के साथ एक घातांक है 4. इसी तरह दूसरा उदाहरण प्रत्येक सर्कल में क्षेत्र है पिछले एक दोगुना है जो बेस 2 के साथ एक घातांक देता है।

हालांकि यह दूसरा उदाहरण है (जहां हम स्केलिंग एरिया हैं) कि दोहरीकरण क्षेत्र सर्कल को आंखों से दो गुना बड़ा बनाता है। इस प्रकार यदि हम चाहते हैं कि एक वृत्त nबड़े के एक कारक को प्रदर्शित करे तो हम क्षेत्र को एक कारक से बढ़ाएंगे nन कि त्रिज्या तो स्पष्ट रूप से इस क्षेत्र के साथ आकार।

@TomaszGandor द्वारा टिप्पणी की कल्पना करने के लिए संपादित करें :

यह मार्कर आकार के विभिन्न कार्यों के लिए कैसा दिखता है:

घातीय, वर्ग या रैखिक आकार

x = [0,2,4,6,8,10,12,14,16,18]
s_exp = [20*2**n for n in range(len(x))]
s_square = [20*n**2 for n in range(len(x))]
s_linear = [20*n for n in range(len(x))]
plt.scatter(x,[1]*len(x),s=s_exp, label='$s=2^n$', lw=1)
plt.scatter(x,[0]*len(x),s=s_square, label='$s=n^2$')
plt.scatter(x,[-1]*len(x),s=s_linear, label='$s=n$')
plt.ylim(-1.5,1.5)
plt.legend(loc='center left', bbox_to_anchor=(1.1, 0.5), labelspacing=3)
plt.show()

2
मैं शायद आपकी बात को गलत समझ रहा हूं, लेकिन आपके दूसरे उदाहरण में आप तेजी से वृद्धि कर रहे हैं (s = [20, 40, 80, 160, 320, 640]) और यह कहते हुए कि हमें एक अच्छा रेखीय-आकार का आकार बढ़ता है। आकार को रैखिक रूप से बढ़ाते हुए क्या यह अधिक समझ में नहीं आता (उदाहरण के लिए s = [20, 40, 60, 80, 100, 120]) ने हमें रेखीय दिखने वाला परिणाम दिया?
एम्मा

@ इम्मा तुम्हारा अंतर्ज्ञान सही है, यह मेरी ओर से खराब शब्द है (एक्स एक्सिस स्केलिंग का वैकल्पिक रूप से खराब विकल्प)। मैंने एक संपादन में कुछ और समझाया क्योंकि यह एक टिप्पणी के लिए बहुत लंबा था।
डैन

1
क्या sआकृति विंडो के आकार के अनुसार मूल्य बदलना संभव है ? मेरा मतलब है, अगर हम आंकड़ा खिड़कियों को अधिकतम करते हैं, तो मुझे बड़े आकार के निशान चाहिए।
सिगुर

2
महान उदाहरण (बस आवश्यक सामान!)। यह नहीं होना चाहिए 4 ** nऔर 2 ** nहै, लेकिन n ** 4और n ** 2। साथ 2 ** nदूसरी साजिश वृत्त व्यास के मामले में रैखिक पैमाने पर नहीं है। यह अभी भी बहुत तेजी से आगे बढ़ता है (सिर्फ इतना ही नहीं ऊपर से)।
टॉमस गंडोर

1
इसे छोटा करने के लिए - दूसरा प्लॉट घातांक का वर्गमूल दिखाता है - जो एक और घातीय है, बस थोड़ा कम खड़ी है।
टॉमस गैंडर

217

क्योंकि यहां अन्य उत्तर दावा करते हैं कि sमार्कर के क्षेत्र को दर्शाता है, मैं इस उत्तर को स्पष्ट करने के लिए जोड़ रहा हूं कि यह जरूरी नहीं है।

अंक में आकार ^ 2

इस तर्क sको plt.scatterनिरूपित करता है markersize**2। जैसा कि प्रलेखन कहता है

s: स्केलर या array_like, आकार (n), वैकल्पिक
आकार में अंक ^ 2। डिफ़ॉल्ट rcParams ['lines.markersize'] ** 2 है।

यह शाब्दिक रूप से लिया जा सकता है। एक मार्कर प्राप्त करने के लिए जो कि x बिंदु बड़ा है, आपको उस संख्या को वर्ग और sतर्क को देना होगा ।

तो लाइन प्लॉट के मार्कर के बीच संबंध और तितर बितर आकार का तर्क वर्ग है। आदेश में 10 अंक के आकार के प्लॉट मार्कर के समान आकार के एक बिखरे हुए मार्कर का उत्पादन करने के लिए आप इसलिए कॉल करेंगे scatter( .., s=100)

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

import matplotlib.pyplot as plt

fig,ax = plt.subplots()

ax.plot([0],[0], marker="o",  markersize=10)
ax.plot([0.07,0.93],[0,0],    linewidth=10)
ax.scatter([1],[0],           s=100)

ax.plot([0],[1], marker="o",  markersize=22)
ax.plot([0.14,0.86],[1,1],    linewidth=22)
ax.scatter([1],[1],           s=22**2)

plt.show()

"क्षेत्र" के लिए कनेक्शन

तो जब sपैरामीटर की बात आती है तो अन्य जवाब और यहां तक ​​कि प्रलेखन "क्षेत्र" के बारे में क्यों बोलते हैं ?

बेशक अंक 2 की इकाइयाँ क्षेत्र इकाइयाँ हैं।

  • एक वर्ग मार्कर के विशेष मामले के लिए, मार्कर marker="s"का क्षेत्र वास्तव में सीधे मूल्य हैs पैरामीटर ।
  • एक सर्कल के लिए, सर्कल का क्षेत्र है area = pi/4*s
  • अन्य मार्करों के लिए मार्कर के क्षेत्र से कोई स्पष्ट संबंध भी नहीं हो सकता है।

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

हालांकि सभी मामलों में मार्कर का क्षेत्र sपैरामीटर के आनुपातिक है । यह "क्षेत्र" कहने की प्रेरणा है भले ही ज्यादातर मामलों में यह वास्तव में नहीं है।

तितर बितर मार्करों के आकार को कुछ मात्रा के संदर्भ में निर्दिष्ट करना जो मार्कर के क्षेत्र के लिए आनुपातिक है इस प्रकार दूर का अर्थ है क्योंकि यह मार्कर का क्षेत्र है जो कि इसकी लंबाई या व्यास के बजाय विभिन्न पैच की तुलना करते समय माना जाता है। यानी अंतर्निहित मात्रा को दोगुना करना मार्कर के क्षेत्र को दोगुना करना चाहिए।

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

अंक क्या हैं?

अब तक एक तितर बितर मार्कर के आकार का मतलब अंकों की इकाइयों में दिया गया है। अंक अक्सर टाइपोग्राफी में उपयोग किए जाते हैं, जहां अंक में फ़ॉन्ट निर्दिष्ट किए जाते हैं। इसके अलावा linewidths अक्सर बिंदुओं में निर्दिष्ट किया जाता है। Matplotlib में अंकों का मानक आकार 72 अंक प्रति इंच (ppi) है - 1 अंक इसलिए 1/72 इंच है।

यह अंकों के बजाय पिक्सेल में आकार निर्दिष्ट करने में सक्षम होने के लिए उपयोगी हो सकता है। यदि आंकड़ा डीपीआई 72 है, तो एक बिंदु एक पिक्सेल है। यदि आंकड़ा डीपीआई अलग है (matplotlib डिफ़ॉल्ट है fig.dpi=100),

1 point == fig.dpi/72. pixels

जबकि पॉइंटर्स में तितर बितर मार्कर का आकार इसलिए अलग-अलग आकृति डीपीआई के लिए अलग-अलग दिखाई देगा, एक 10 पिक्सेल 10 मिमी ^ 2 मार्कर का उत्पादन कर सकता है, जिसमें हमेशा समान संख्या में पिक्सेल शामिल होंगे:

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

import matplotlib.pyplot as plt

for dpi in [72,100,144]:

    fig,ax = plt.subplots(figsize=(1.5,2), dpi=dpi)
    ax.set_title("fig.dpi={}".format(dpi))

    ax.set_ylim(-3,3)
    ax.set_xlim(-2,2)

    ax.scatter([0],[1], s=10**2, 
               marker="s", linewidth=0, label="100 points^2")
    ax.scatter([1],[1], s=(10*72./fig.dpi)**2, 
               marker="s", linewidth=0, label="100 pixels^2")

    ax.legend(loc=8,framealpha=1, fontsize=8)

    fig.savefig("fig{}.png".format(dpi), bbox_inches="tight")

plt.show() 

यदि आप डेटा इकाइयों में एक बिखराव में रुचि रखते हैं, तो इस उत्तर की जांच करें


आश्चर्य होता है कि कोई ऐसा पैरामीटर कैसे गणना करेगा जो एक सर्कल को पाने के लिए तितर बितर करने के लिए देता है जो व्यास को कवर करता है, आइए कहते हैं, भूखंड के वास्तविक निर्देशांक में 0.1 (ताकि के बीच के अंतर को भरने के लिए 0.4 और 0.5 से एक भूखंड पर कहें) , 0) से (1,1)?
अनातोली अलेक्सेव

@AnatolyAlekseev इस सवाल का जवाब दिया जाना चाहिए ।
महत्व

21

आप प्लॉट विधि में सर्कल के आकार को निर्दिष्ट करने के लिए मार्कर का उपयोग कर सकते हैं

import numpy as np
import matplotlib.pyplot as plt

x1 = np.random.randn(20)
x2 = np.random.randn(20)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(x1, 'bo', markersize=20)  # blue circle with size 10 
plt.plot(x2, 'ro', ms=10,)  # ms is just an alias for markersize
plt.show()

से यहाँ

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


सवाल scatterplot के बारे में था, और matplotlib में दो की साजिश रचने कार्य (विभिन्न मापदंडों है markersize के लिए साजिश , और रों लिए बिखराव )। तो यह उत्तर लागू नहीं होता है।
डोम

3
@Dom I upvott, क्योंकि यह प्रश्न Google में पहले परिणाम के रूप में पॉप करता है, जब मैं "pyplot साजिश मार्कर आकार" खोजता हूं, तो यह उत्तर मदद करता है।
प्रेज़ेमेक डी।

मैं जानता हूँ कि साजिश विधि और बिखराव विधि plt में अलग हैं, लेकिन वे दोनों 'बिखराव साजिश' का एहसास है और markersize समायोजित कर सकते हैं, तो यह जवाब है सिर्फ एक और आसपास काम कर रहे है, तो आप साजिश विधि @Dom का उपयोग
Zhaoqing

18

यह मार्कर का क्षेत्र है। मेरा मतलब है कि अगर आपके पास है s1 = 1000और फिर s2 = 4000, प्रत्येक सर्कल के त्रिज्या के बीच संबंध है r_s2 = 2 * r_s1:। निम्नलिखित कथानक देखें:

plt.scatter(2, 1, s=4000, c='r')
plt.scatter(2, 1, s=1000 ,c='b')
plt.scatter(2, 1, s=10, c='g')

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

जब मैंने पोस्ट देखा तो मुझे वही संदेह था, इसलिए मैंने यह उदाहरण दिया तब मैंने रेडी को मापने के लिए स्क्रीन पर एक शासक का उपयोग किया।


यह सबसे साफ और सबसे वसा मुक्त जवाब है। धन्यवाद
अयान मित्रा

6

मैंने इस उद्देश्य के लिए शुरू में 'बिखराव' का उपयोग करने का भी प्रयास किया। काफी समय बर्बाद होने के बाद - मैं निम्नलिखित समाधान पर आ गया।

import matplotlib.pyplot as plt
input_list = [{'x':100,'y':200,'radius':50, 'color':(0.1,0.2,0.3)}]    
output_list = []   
for point in input_list:
    output_list.append(plt.Circle((point['x'], point['y']), point['radius'], color=point['color'], fill=False))
ax = plt.gca(aspect='equal')
ax.cla()
ax.set_xlim((0, 1000))
ax.set_ylim((0, 1000))
for circle in output_list:    
   ax.add_artist(circle)

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

यह इस प्रश्न के उत्तर पर आधारित है


काफी सहायक। लेकिन दो छोरों का उपयोग क्यों करें?
१32 को ११:३२ पर हड़बड़ी

1
@ कोई कारण नहीं, बस इसमें बहुत ज्यादा नहीं सोचा था।
आइक

2

यदि मंडलियों का आकार पैरामीटर के वर्ग से मेल खाता है s=parameter, तो आप अपने आकार सरणी में संलग्न प्रत्येक तत्व के लिए एक वर्गमूल असाइन करें, जैसे: s=[1, 1.414, 1.73, 2.0, 2.24]इस तरह कि जब यह इन मूल्यों को लेता है और उन्हें लौटाता है, तो उनके सापेक्ष आकार में वृद्धि होगी चौकोर प्रगति का वर्गमूल, जो एक रैखिक प्रगति लौटाता है।

अगर मैं हर एक को वर्ग के रूप में यह भूखंड के लिए उत्पादन हो जाता है output=[1, 2, 3, 4, 5]:। सूची व्याख्या का प्रयास करें:s=[numpy.sqrt(i) for i in s]


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