2010-03-29 11 views
21

के साथ एसिमप्टेट/डिस्टॉन्टीन्यूटी को कैसे संभालना है, जब एक डिस्कटिन्यूइटी/एसिमपोट/एकवचन/जो भी हो, के साथ ग्राफ की साजिश करते समय, क्या मैटलप्लिब को 'ब्रेक' में 'डॉट्स में शामिल होने' से रोकने के लिए कोई स्वचालित तरीका है? (कृपया नीचे कोड/छवि देखें)।
मैंने पढ़ा है कि ऋषि की एक [detect_poles] सुविधा है जो अच्छी लगती है, लेकिन मैं वास्तव में इसे Matplotlib के साथ काम करना चाहता हूं।Matplotlib

import matplotlib.pyplot as plt 
import numpy as np 
from sympy import sympify, lambdify 
from sympy.abc import x 

fig = plt.figure(1) 
ax = fig.add_subplot(111) 

# set up axis 
ax.spines['left'].set_position('zero') 
ax.spines['right'].set_color('none') 
ax.spines['bottom'].set_position('zero') 
ax.spines['top'].set_color('none') 
ax.xaxis.set_ticks_position('bottom') 
ax.yaxis.set_ticks_position('left') 

# setup x and y ranges and precision 
xx = np.arange(-0.5,5.5,0.01) 

# draw my curve 
myfunction=sympify(1/(x-2)) 
mylambdifiedfunction=lambdify(x,myfunction,'numpy') 
ax.plot(xx, mylambdifiedfunction(xx),zorder=100,linewidth=3,color='red') 

#set bounds 
ax.set_xbound(-1,6) 
ax.set_ybound(-4,4) 

plt.show() 

Discontinuity

+1

इस के लिए धन्यवाद सवाल; यद्यपि आपने इसे 'पायथन' टैग किया है, इस बात से अवगत रहें कि यह आमतौर पर 'matplotlib' सवाल है; मैंने खुद को पाइथन की बजाय जूलिया के उत्तरों में से एक का उपयोग किया। सादर। –

उत्तर

11

इस सुरुचिपूर्ण समाधान आप देख रहे हैं नहीं हो सकता है, लेकिन सिर्फ ज्यादातर मामलों के लिए परिणाम चाहते हैं, तो आप कर सकते हैं "क्लिप" बड़े और आपके प्लॉट किए गए डेटा के छोटे मूल्य +∞ और -∞ क्रमशः। Matplotlib इन साजिश नहीं करता है। बेशक आपको सावधान रहना होगा कि आपका रिज़ॉल्यूशन बहुत कम न हो या आपकी क्लिपिंग थ्रेसहोल्ड बहुत अधिक न हो।

utol = 100. 
ltol = -100. 
yy = 1/(xx-2) 
yy[yy>utol] = np.inf 
yy[yy<ltol] = -np.inf 

ax.plot(xx, yy, zorder=100, linewidth=3, color='red') 
+0

यह बहुत अच्छी तरह से काम करता है। यदि आप '∞' – MackM

5

नहीं, मुझे लगता है कोई अंतर्निहित तरीका इन अंक की अनदेखी करने के matplotlib बताने के लिए। आखिरकार, यह सिर्फ अंक जोड़ता है और कार्यों के बारे में कुछ भी नहीं जानता या बिंदुओं के बीच क्या होता है।

हालांकि, आप ध्रुवों को खोजने के लिए sympy का उपयोग कर सकते हैं, और उसके बाद अपने फ़ंक्शन के निरंतर टुकड़े एक साथ पैच कर सकते हैं। यहाँ कुछ वैसे बदसूरत कोड है कि वास्तव में करता है:

from pylab import * 
from sympy import solve 
from sympy.abc import x 
from sympy.functions.elementary.complexes import im 

xmin = -0.5 
xmax = 5.5 
xstep = 0.01 

# solve for 1/f(x)=0 -- we will have poles there 
discontinuities = sort(solve(1/(1/(x-2)),x)) 

# pieces from xmin to last discontinuity 
last_b = xmin 
for b in discontinuities: 
    # check that this discontinuity is inside our range, also make sure it's real 
    if b<last_b or b>xmax or im(b): 
     continue 
    xi = np.arange(last_b, b, xstep) 
    plot(xi, 1./(xi-2),'r-') 
    last_b = b 

# from last discontinuity to xmax 
xi = np.arange(last_b, xmax, xstep) 
plot(xi, 1./(xi-2),'r-') 

xlim(xmin, xmax) 
ylim(-4,4) 
show() 

example http://i43.tinypic.com/30mvbzb.jpg

+0

यह प्रयोज्यता में बहुत सीमित है: यदि फ़ंक्शन 1/(x-2) के बजाय तन (x) था, तो हल आदेश को 1/तन (x) की कोई जड़ नहीं मिलेगी। यह केवल यहां काम करता है क्योंकि 1/(1/(x-2)) x-2 के लिए सरलीकृत है। –

20

masked arrays का उपयोग करके आप वक्र के चयनित क्षेत्रों की साजिश से बच सकते हैं।

import matplotlib.numerix.ma as M # for older versions, prior to .98 
#import numpy.ma as M    # for newer versions of matplotlib 
from pylab import * 

figure() 

xx = np.arange(-0.5,5.5,0.01) 
vals = 1/(xx-2)   
vals = M.array(vals) 
mvals = M.masked_where(xx==2, vals) 

subplot(121) 
plot(xx, mvals, linewidth=3, color='red') 
xlim(-1,6) 
ylim(-5,5) 

यह सरल वक्र में थोड़ा और अधिक स्पष्ट हो सकता है, जिस पर अंक बाहर रखा गया है:

व्यक्तित्व x = 2 पर निकालने के लिए

xx = np.arange(0,6,.2) 
vals = M.array(xx) 
mvals = M.masked_where(vals%2==0, vals) 
subplot(122) 
plot(xx, mvals, color='b', linewidth=3) 
plot(xx, vals, 'rx') 
show() 

enter image description here

+0

से बचने का एक और कारण रखते हैं तो आप' np.inf' के बजाय 'np.nan' का भी उपयोग कर सकते हैं, यह क्यों है कि जब मैं आपका कोड चलाता हूं तो मुझे लाल वक्र को जोड़ने वाली सीधी लंबवत रेखा मिलती है? –