2012-01-17 23 views
8

matplotlib में इस प्रकार मैं लॉग भूखंडों का उपयोग कर रहा है, इस प्रकार मोटे तौर पर।matplotlib समस्याओं लॉग इन डेटा की साजिश रचने और उसके x/y सीमा की स्थापना

plt.scatter(x, y) 

# use log scales 
plt.gca().set_xscale('log') 
plt.gca().set_yscale('log') 

# set x,y limits 
plt.xlim([-1, 3]) 
plt.ylim([-1, 3]) 

पहले समस्या यह है कि एक्स, वाई सीमा, matplotlib तराजू सेट के बिना इस तरह है कि डेटा के सबसे नहीं दिख रही है - किसी कारण से, यह न्यूनतम और अधिकतम मूल्य के साथ x और y का उपयोग नहीं करता आयाम हैं, इसलिए डिफ़ॉल्ट साजिश अत्यंत भ्रामक है।

जब मैं plt.xlim, plt.ylim का उपयोग करके मैन्युअल रूप से सीमा निर्धारित करता हूं, जिसे मैं लॉग 10 इकाइयों (यानी 1/10th से 3000) में -1 से 3 होने की व्याख्या करता हूं, मुझे एक संलग्नक की तरह एक साजिश मिलती है। enter image description here

धुरी लेबल यहां समझ में नहीं आता है: यह 10^1 से 10^3 तक जाता है। यहाँ क्या चल रहा है?

import matplotlib 
import matplotlib.pyplot as plt 
from numpy import * 

x = array([58, 0, 20, 2, 2, 0, 12, 17, 16, 6, 257, 0, 0, 0, 0, 1, 0, 13, 25, 9, 13, 94, 0, 0, 2, 42, 83, 0, 0, 157, 27, 1, 80, 0, 0, 0, 0, 2, 0, 41, 0, 4, 0, 10, 1, 4, 63, 6, 0, 31, 3, 5, 0, 61, 2, 0, 0, 0, 17, 52, 46, 15, 67, 20, 0, 0, 20, 39, 0, 31, 0, 0, 0, 0, 116, 0, 0, 0, 11, 39, 0, 17, 0, 59, 1, 0, 0, 2, 7, 0, 66, 14, 1, 19, 0, 101, 104, 228, 0, 31]) 

y = array([60, 0, 9, 1, 3, 0, 13, 9, 11, 7, 177, 0, 0, 0, 0, 1, 0, 12, 31, 10, 14, 80, 0, 0, 2, 30, 70, 0, 0, 202, 26, 1, 96, 0, 0, 0, 0, 1, 0, 43, 0, 6, 0, 9, 1, 3, 32, 6, 0, 20, 1, 2, 0, 52, 1, 0, 0, 0, 26, 37, 44, 13, 74, 15, 0, 0, 24, 36, 0, 22, 0, 0, 0, 0, 75, 0, 0, 0, 9, 40, 0, 14, 0, 51, 2, 0, 0, 1, 9, 0, 59, 9, 0, 23, 0, 80, 81, 158, 0, 27]) 

c = 0.01 

plt.figure(figsize=(5,3)) 
s = plt.subplot(1, 3, 1) 
plt.scatter(x + c, y + c) 
plt.title('Unlogged') 
s = plt.subplot(1, 3, 2) 
plt.scatter(x + c, y + c) 
plt.gca().set_xscale('log', basex=2) 
plt.gca().set_yscale('log', basey=2) 
plt.title('Logged') 
s = plt.subplot(1, 3, 3) 
plt.scatter(x + c, y + c) 
plt.gca().set_xscale('log', basex=2) 
plt.gca().set_yscale('log', basey=2) 
plt.xlim([-2, 20]) 
plt.ylim([-2, 20]) 
plt.title('Logged with wrong xlim/ylim') 
plt.savefig('test.png') 

यह नीचे दिए गए भूखंड का उत्पादन:

मुझे लगता है कि नीचे एक अधिक विस्तृत उदाहरण शामिल कर रहा हूँ डेटा के साथ इन सभी समस्याओं से पता चलता बाएं से

enter image description here

पहले subplot में, हम कच्चे अनलॉक डेटा है। दूसरे में, हमने मूल्य डिफ़ॉल्ट दृश्य लॉग किए हैं। तीसरे में हम मान x/y LIMS के साथ निर्दिष्ट लॉग इन किया है। मेरे प्रश्न हैं:

  1. क्यों बिखराव भूखंड गलत के लिए डिफ़ॉल्ट x/y सीमा कर रहे हैं? मैनुअल कहते हैं कि यह डेटा में न्यूनतम और अधिकतम मानों का उपयोग करने की अपेक्षा की है, लेकिन यह स्पष्ट रूप से मामला यहाँ नहीं है। इसने मूल्यों को चुना जो डेटा के विशाल बहुमत को छुपाते हैं।

  2. कारण है कि यह है कि जब मैं बाएं से अपने आप को सीमा, तीसरे बिखराव साजिश में निर्धारित करते हैं, यह लेबल के आदेश को उलट देता है? 2^5 से पहले 2^8 दिखा रहा है? यह बहुत भ्रमित है।

  3. अंत में, मैं इसे कैसे प्राप्त कर सकते हैं ताकि भूखंडों कि डिफ़ॉल्ट subplots का उपयोग करके की तरह squished नहीं कर रहे हैं? मैं चाहता था कि ये तितर बर्तन स्क्वायर हों।

संपादित करें: उत्तर के लिए जो और होन के लिए धन्यवाद। की तरह इस वर्ग होने के लिए अगर मैं subplots समायोजित करने का प्रयास:

enter image description here

मैं कैसे ताकि प्रत्येक भूखंड वर्ग और एक दूसरे के साथ गठबंधन किया है प्राप्त कर सकते हैं:

plt.figure(figsize=(5,3), dpi=10) 
s = plt.subplot(1, 2, 1, adjustable='box', aspect='equal') 
plt.scatter(x + c, y + c) 
plt.title('Unlogged') 
s = plt.subplot(1, 2, 2, adjustable='box', aspect='equal') 
plt.scatter(x + c, y + c) 
plt.gca().set_xscale('log', basex=2) 
plt.gca().set_yscale('log', basey=2) 
plt.title('Logged') 

मैं नीचे परिणाम प्राप्त? यह सिर्फ वर्ग का एक ग्रिड, सभी को समान आकार ...

संपादित 2 होना चाहिए:

कुछ वापस योगदान के लिए, यहाँ कैसे एक इन लॉग 2 भूखंडों लेने के लिए और कुल्हाड़ियों उनके गैर के साथ दिखाई होगा है एक्सपोनेंट नोटेशन:

import matplotlib 

from matplotlib.ticker import FuncFormatter 

def log_2_product(x, pos): 
    return "%.2f" %(x) 

c = 0.01 
plt.figure(figsize=(10,5), dpi=100) 
s1 = plt.subplot(1, 2, 1, adjustable='box', aspect='equal') 
plt.scatter(x + c, y + c) 
plt.title('Unlogged') 
plotting.axes_square(s1) 
s2 = plt.subplot(1, 2, 2, adjustable='box', aspect='equal') 
min_x, max_x = min(x + c), max(x + c) 
min_y, max_y = min(y + c), max(y + c) 
plotting.axes_square(s2) 
plt.xlim([min_x, max_x]) 
plt.ylim([min_y, max_y]) 
plt.gca().set_xscale('log', basex=2) 
plt.gca().set_yscale('log', basey=2) 
plt.scatter(x + c, y + c) 
formatter = FuncFormatter(log_2_product) 
s2.xaxis.set_major_formatter(formatter) 
s2.yaxis.set_major_formatter(formatter) 

plt.title('Logged') 
plt.savefig('test.png') 

आपकी सहायता के लिए धन्यवाद।

+1

सबसे अजीब! मैं खुद को जानना उत्सुक हूं। –

उत्तर

12

@honk पहले से ही अपने मुख्य सवाल का जवाब दे दिया है, लेकिन दूसरों को (और अपने मूल प्रश्न) के लिए के रूप में, कृपया कुछ ट्यूटोरियल पढ़ने के लिए या उदाहरण के कुछ पर एक नजर है। :)

तुम बहुत उलझन में हो रही है क्योंकि आप कार्यों का उपयोग कर रहे के लिए दस्तावेज़ को देखा नहीं किया है।

स्कैटर प्लॉट के लिए डिफ़ॉल्ट x/y सीमाएं गलत क्यों हैं? मैनुअल का कहना है कि यह डेटा में न्यूनतम और अधिकतम मानों का उपयोग करना है, लेकिन यह स्पष्ट रूप से यहां मामला नहीं है। इसने मूल्यों को चुना जो विशाल डेटा के बहुमत को छुपाते हैं।

यह सबसे निश्चित रूप से कहना नहीं है कि दस्तावेज में।

डिफ़ॉल्ट रूप से, matplotlib साजिश सीमा के लिए सबसे पास "भी" संख्या के लिए "दौर" होगा। लॉग प्लॉट के मामले में, यह आधार की निकटतम शक्ति है।

आप इसे सख्ती से मिनट और डेटा की अधिकतम स्नैप करना चाहते हैं, तो निर्दिष्ट करें:

ax.axis('tight') 

या समतुल्य रूप

plt.axis('tight') 

क्यों है जब मैं सीमा अपने आप सेट कि , बाईं ओर तीसरे स्कैटर प्लॉट में, यह लेबल के क्रम को उलट देता है? 2^5 से पहले 2^8 दिखा रहा है? यह बहुत भ्रमित है।

यह नहीं है। यह 2^5 से पहले 2^-8 दिखा रहा है। आपके पास बस बहुत सारे लेबल हैं। एक्सपोनेंट में शून्य संकेत छिपाने वाले टेक्स्ट से छुपाए जा रहे हैं। भूखंड का आकार बदलने या plt.tight_layout() कॉल करके देखें अंत में (या फ़ॉन्ट आकार या डीपीआई बदल जाते हैं। डीपीआई बदलने फोंट की सभी सहेजे छवि पर बड़ा या छोटा करने का एक त्वरित तरीका है।)

, मैं कैसे कर सकते हैं इसे प्राप्त करें ताकि प्लॉट्स को की तरह स्प्लिड नहीं किया जा सके, सबप्लॉट्स का उपयोग करके डिफ़ॉल्ट रूप से? मैं चाहता था कि ये तितर बर्तन स्क्वायर हों।

"वर्ग" के अर्थ के आधार पर ऐसा करने के कई तरीके हैं। मेरा अनुमान है कि यह है कि आप दोनों, जिस स्थिति में आप plt.subplot को adjustable='box' और aspect='equal' में दे देते हैं मतलब (अर्थात आप साजिश के पहलू अनुपात या सीमा अलग-अलग करना चाहते हैं?)

।(आप भी इसे अलग तरीके का एक संख्या में बाद में सेट कर सकते हैं, (plt.axis('equal') आदि))

ऊपर के सभी का एक उदाहरण के रूप में:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.array([58, 0, 20, 2, 2, 0, 12, 17, 16, 6, 257, 0, 0, 0, 0, 1, 0, 13, 25, 
       9, 13, 94, 0, 0, 2, 42, 83, 0, 0, 157, 27, 1, 80, 0, 0, 0, 0, 2, 
       0, 41, 0, 4, 0, 10, 1, 4, 63, 6, 0, 31, 3, 5, 0, 61, 2, 0, 0, 0, 
       17, 52, 46, 15, 67, 20, 0, 0, 20, 39, 0, 31, 0, 0, 0, 0, 116, 0, 
       0, 0, 11, 39, 0, 17, 0, 59, 1, 0, 0, 2, 7, 0, 66, 14, 1, 19, 0, 
       101, 104, 228, 0, 31]) 

y = np.array([60, 0, 9, 1, 3, 0, 13, 9, 11, 7, 177, 0, 0, 0, 0, 1, 0, 12, 31, 
       10, 14, 80, 0, 0, 2, 30, 70, 0, 0, 202, 26, 1, 96, 0, 0, 0, 0, 1, 
       0, 43, 0, 6, 0, 9, 1, 3, 32, 6, 0, 20, 1, 2, 0, 52, 1, 0, 0, 0, 
       26, 37, 44, 13, 74, 15, 0, 0, 24, 36, 0, 22, 0, 0, 0, 0, 75, 0, 
       0, 0, 9, 40, 0, 14, 0, 51, 2, 0, 0, 1, 9, 0, 59, 9, 0, 23, 0, 80, 
       81, 158, 0, 27]) 
c = 0.01 

# Let's make the figure a bit bigger so the text doesn't run into itself... 
# (5x3 is rather small at 100dpi. Adjust the dpi if you really want a 5x3 plot) 
fig, axes = plt.subplots(ncols=3, figsize=(10, 6), 
         subplot_kw=dict(aspect=1, adjustable='box')) 

# Don't use scatter for this. Use plot. Scatter is if you want to vary things 
# like color or size by a third or fourth variable. 
for ax in axes: 
    ax.plot(x + c, y + c, 'bo') 

for ax in axes[1:]: 
    ax.set_xscale('log', basex=2) 
    ax.set_yscale('log', basey=2) 

axes[0].set_title('Unlogged') 
axes[1].set_title('Logged') 

axes[2].axis([2**-2, 2**20, 2**-2, 2**20]) 
axes[2].set_title('Logged with wrong xlim/ylim') 

plt.tight_layout() 
plt.show() 

enter image description here

आप अपने भूखंड की रूपरेखा चाहते हैं बिल्कुल वही आकार और आकार होने के लिए, सबसे आसान तरीका आकृति आकार को उचित अनुपात में बदलना है और फिर adjustable='datalim' का उपयोग करना है।

यदि आप पूरी तरह से सामान्यीकृत होना चाहते हैं, तो मैन्युअल रूप से सबप्लॉट का उपयोग करने के बजाय उप-अक्ष जोड़ें।

हालांकि, यदि आप आकृति आकार को समायोजित करने और subplots_adjust का उपयोग करने पर ध्यान नहीं देते हैं, तो यह करना आसान है और अभी भी उप-स्थान का उपयोग करना आसान है।

मूल रूप से, आप की तरह

# For 3 columns and one row, we'd want a 3 to 1 ratio... 
fig, axes = plt.subplots(ncols=3, figsize=(9,3), 
         subplot_kw=dict(adjustable='datalim', aspect='equal') 

# By default, the width available to make subplots in is 5% smaller than the 
# height to make them in. This is easily changable... 
# ("right" is a percentage of the total width. It will be 0.95 regardless.) 
plt.subplots_adjust(right=0.95) 

कुछ करना चाहते हैं और फिर पहले की तरह जारी है।

पूर्ण उदाहरण के लिए:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.array([58, 0, 20, 2, 2, 0, 12, 17, 16, 6, 257, 0, 0, 0, 0, 1, 0, 13, 25, 
       9, 13, 94, 0, 0, 2, 42, 83, 0, 0, 157, 27, 1, 80, 0, 0, 0, 0, 2, 
       0, 41, 0, 4, 0, 10, 1, 4, 63, 6, 0, 31, 3, 5, 0, 61, 2, 0, 0, 0, 
       17, 52, 46, 15, 67, 20, 0, 0, 20, 39, 0, 31, 0, 0, 0, 0, 116, 0, 
       0, 0, 11, 39, 0, 17, 0, 59, 1, 0, 0, 2, 7, 0, 66, 14, 1, 19, 0, 
       101, 104, 228, 0, 31]) 

y = np.array([60, 0, 9, 1, 3, 0, 13, 9, 11, 7, 177, 0, 0, 0, 0, 1, 0, 12, 31, 
       10, 14, 80, 0, 0, 2, 30, 70, 0, 0, 202, 26, 1, 96, 0, 0, 0, 0, 1, 
       0, 43, 0, 6, 0, 9, 1, 3, 32, 6, 0, 20, 1, 2, 0, 52, 1, 0, 0, 0, 
       26, 37, 44, 13, 74, 15, 0, 0, 24, 36, 0, 22, 0, 0, 0, 0, 75, 0, 
       0, 0, 9, 40, 0, 14, 0, 51, 2, 0, 0, 1, 9, 0, 59, 9, 0, 23, 0, 80, 
       81, 158, 0, 27]) 
c = 0.01 

fig, axes = plt.subplots(ncols=3, figsize=(9, 3), 
         subplot_kw=dict(adjustable='datalim', aspect='equal')) 
plt.subplots_adjust(right=0.95) 

for ax in axes: 
    ax.plot(x + c, y + c, 'bo') 

for ax in axes[1:]: 
    ax.set_xscale('log', basex=2) 
    ax.set_yscale('log', basey=2) 

axes[0].set_title('Unlogged') 
axes[1].set_title('Logged') 

axes[2].axis([2**-2, 2**20, 2**-2, 2**20]) 
axes[2].set_title('Logged with wrong xlim/ylim') 

plt.tight_layout() 
plt.show() 

enter image description here

+0

उत्तरों के लिए धन्यवाद, मैं इसकी सराहना करता हूं। बस एक और अनुवर्ती: यदि मैं समायोज्य = 'बॉक्स' और पहलू = 'बराबर' का उपयोग करता हूं, तो यह अभी भी व्यक्तिगत उप-वर्ग वर्ग को उसी तरह से नहीं बनाता है। संपादित उत्तर देखें। – user248237dfsf

+0

यदि आप प्लॉट्स के लिए बिल्कुल समान, स्क्वायर रूपरेखा चाहते हैं (ध्यान दें कि इस मामले में प्लॉट स्वयं _cannot_ वर्ग नहीं हैं (यानी पहलू = 1 और x और y में समान सीमाएं) !!) तो इसे करने के कुछ अलग तरीके हैं । मुझे थोड़ा सा दें और मैं एक और उदाहरण जोड़ूंगा। –

+0

हां, स्पष्टीकरण के लिए, मैं नहीं चाहता हूं कि वे एक ही अक्ष मानों को प्राप्त करें - केवल एक ही आयाम में एक्स एक्स इकाइयों में "वर्ग" दोनों एक दूसरे में एक्स इकाइयों के बराबर होते हैं, प्रत्येक प्लॉट के लिए, और वास्तविक वर्ग है सभी में एक ही आकार ... धन्यवाद – user248237dfsf

4

आप भ्रमित हैं कि xlim और ylim पर कौन सी इकाइयां देना है।वे को xlim(log10(min), log10(max)) नहीं कहा जाना चाहिए, लेकिन केवल xlim(min, max)। वे आपके अक्षों पर सबसे कम और उच्चतम मानों से निपटते हैं जो x और y की इकाइयों में हैं।

अजीब प्रदर्शन आप (सभी x के लिए log(x)>0) एक लघुगणकीय पैमाने जो यह नहीं दिखा सकते हैं पर एक नकारात्मक न्यूनतम का अनुरोध के बाद से कुछ बग आप को गति प्रदान होने के लिए मुझे लगता है।

+0

मैं स्वीकार करता हूं कि xlim/ylim के लिए, हालांकि यह भ्रमित है। क्या आपको अन्य दो प्रश्नों के बारे में कोई जानकारी है? – user248237dfsf

संबंधित मुद्दे