как обработать асимптоту/разрыв с Matplotlib

При построении графика с discontinuity/asymptote/singularity/whatever, там какой-либо автоматический способ предотвратить Matplotlib от 'присоединения к точкам' через 'повреждение'? (см. код/изображение ниже).
Я читал, у того Sage есть [detect_poles] средство, которое выглядело хорошим, но я действительно хочу, чтобы оно работало с 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

23
задан Adaline Simonian 13 August 2017 в 08:31
поделиться

3 ответа

Возможно, это не самое элегантное решение, которое вы ищете, но если вам нужны результаты только в большинстве случаев, вы можете «вырезать» большие и маленькие значения вашего нанесенные данные на + ∞ и -∞ соответственно. 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') 
13
ответ дан 29 November 2019 в 02:01
поделиться

Используя маскированные массивы, можно избежать построения выделенных областей кривой.

Чтобы убрать сингулярность при 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) 

Эта простая кривая может быть более ясной в отношении того, какие точки исключены:

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

23
ответ дан 29 November 2019 в 02:01
поделиться

Нет, я думаю, что нет встроенного способа указать 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

5
ответ дан 29 November 2019 в 02:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: