2010-03-29 16 views
21

Przy wykreślaniu wykresu z nieciągłością/asymptotą/osobliwością/czymkolwiek, czy istnieje jakiś automatyczny sposób, aby uniemożliwić Matplotlib "dołączenie kropek" do "przerwy"? (proszę zobaczyć kod/obrazek poniżej).
Przeczytałem, że Sage ma obiekt [detect_poles], który wyglądał dobrze, ale naprawdę chcę, aby działał z Matplotlib.jak radzić sobie z asymptotą/nieciągłością z Matplotlibem

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

Dziękuję za ten pytanie; chociaż oznaczyłeś go 'python', pamiętaj, że jest to raczej pytanie' matplotlib'; Użyłem jednej z odpowiedzi od Julii zamiast Pythona. Pozdrowienia. –

Odpowiedz

11

To nie może być eleganckie rozwiązanie szukasz, ale jeśli po prostu chcesz wyników dla większości przypadków, można „klip” duże i małe wartości wykreślonych danych odpowiednio do +∞ i -∞. Matplotlib nie kreśli ich. Oczywiście musisz uważać, aby nie obniżyć rozdzielczości lub uzyskać zbyt wysoki próg przycinania.

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

To działa bardzo dobrze. Możesz też użyć 'np.nan' zamiast' np.inf', jeśli masz inny powód, aby unikać '∞' – MackM

5

Nie, myślę, że nie ma wbudowanego sposób powiedzieć matplotlib ignorować te punktów. Przecież po prostu łączy punkty i nie wie nic o funkcjach ani o tym, co dzieje się pomiędzy punktami.

Można jednak użyć sympy, aby znaleźć bieguny, a następnie połączyć ciągłe elementy swojej funkcji. Oto niektóre wprawdzie brzydki kod, który robi dokładnie to:

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

Jest to bardzo ograniczone pod względem zastosowania: jeśli funkcja była opalenizna (x) zamiast 1/(x-2), polecenie solve nie znajdzie żadnych korzeni 1/tan (x). Działa to tylko dlatego, że 1/(1/(x-2)) jest uproszczony do x-2. –

20

Za pomocą masked arrays można uniknąć drukowania wybranych regionów krzywej.

Aby usunąć osobliwość w punkcie x = 2:

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) 

Ta prosta krzywa może być nieco bardziej jasne, na których punkty są wykluczone:

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

dlaczego po uruchomieniu kodu nadal otrzymuję prostą pionową linię łączącą czerwone krzywe? –

Powiązane problemy