绘制/转换来自sympy的表达式:使用matplotlib的泰勒级数 [英] Plot/Convert an expression coming from sympy: Taylor series with matplotlib

查看:137
本文介绍了绘制/转换来自sympy的表达式:使用matplotlib的泰勒级数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图绘制函数sin(x)/x及其泰勒近似. 我使用python 3和pyzo-第一个绘图可以工作,但是我无法将来自sympy模块的序列转换为可以工作的numpy表达式.

import numpy as np
import matplotlib.pyplot as plt
import sympy as sp
from sympy.abc import x

x = np.linspace(-10, 10, 100)
y = np.sin(x)/x #first function
plt.plot(x, y, 'k') #this is working fine

### this is a code that removes the "0(x**something)" part of 
the series at the end 

我在这里找到它 http://pastebin.com/ZNQakWP7

def series(expr, x, x0, n, removeO=False):
"""
sympy bugs avoided
"""
# expr_series = expr.series(x, x0, n)
# return expr_series.removeO() if removeO else expr_series
expansion = list()
for t in expr.lseries(x, x0):
    p = t.as_coeff_exponent(x)[1]
    if p < n:
        expansion.append(t)
    else:
        break
if not removeO:
    expansion.append(sp.O(x**n))
return sp.Add(*expansion)
### my code continued ####

y_t=series(sp.sin(x)/x,x,0,6,removeO=True)

如果我现在看y_t,我得到这个近似值

out: x**4/120 - x**2/6 + 1

现在,我尝试将其转换为numpy,以便像我对第一个函数所做的那样对其进行绘制.

f_t = lambdify(x, y_t,modules=['numpy'])
x = np.linspace(-10, 10, 100) #i do this because x has
#been a symbolic variable before

plt.plot(x, y_t, 'b') #this is where the problem occurs

我得到了第一张图,也得到了第二条错误消息:

 File "<console>", line 1, in <module>
  File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\pyplot.py", line 2832, in plot
    ret = ax.plot(*args, **kwargs)
  File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\axes.py", line 3998, in plot
    for line in self._get_lines(*args, **kwargs):

我如何实现我的想法来绘制来自sympy的东西? 我的另一个想法是将sympy从系列转换为字符串,然后以某种方式将其解析为numpy表达式.感谢您在这里提供的帮助!

解决方案

我认为您的问题是这样的:

plt.plot(x, y_t, 'b') #this is where the problem occurs

应该是这样的:

plt.plot(x, f_t(x), 'b')

f_t是lambdified系列,因此它是可调用的函数,用于计算其参数.

在以下示例中,我使用了 lambdify ,并且它对我有用:

from sympy.abc import x
from sympy import sin, series
from sympy.utilities.lambdify import lambdify

import numpy as np
import matplotlib.pyplot as plt


func = sin(x)/x
taylor = series(func, n=6).removeO()

evalfunc = lambdify(x, func, modules=['numpy'])
evaltaylor = lambdify(x, taylor, modules=['numpy'])

t = np.linspace(-5.5, 5.5, 100)
plt.plot(t, evalfunc(t), 'b', label='sin(x)/x')
plt.plot(t, evaltaylor(t), 'r', label='Taylor')
plt.legend(loc='best')
plt.show()

这是脚本生成的情节.

i´am trying to plot the function sin(x)/x and a taylor approximation of it. i use python 3 and pyzo - the first plot works but i have problems converting the series coming from the sympy module to an numpy expression that would work.

import numpy as np
import matplotlib.pyplot as plt
import sympy as sp
from sympy.abc import x

x = np.linspace(-10, 10, 100)
y = np.sin(x)/x #first function
plt.plot(x, y, 'k') #this is working fine

### this is a code that removes the "0(x**something)" part of 
the series at the end 

i found it here http://pastebin.com/ZNQakWP7

def series(expr, x, x0, n, removeO=False):
"""
sympy bugs avoided
"""
# expr_series = expr.series(x, x0, n)
# return expr_series.removeO() if removeO else expr_series
expansion = list()
for t in expr.lseries(x, x0):
    p = t.as_coeff_exponent(x)[1]
    if p < n:
        expansion.append(t)
    else:
        break
if not removeO:
    expansion.append(sp.O(x**n))
return sp.Add(*expansion)
### my code continued ####

y_t=series(sp.sin(x)/x,x,0,6,removeO=True)

if i look at y_t now i get this approximation

out: x**4/120 - x**2/6 + 1

Now i try to convert this to numpy in order to plot it as i did with the first function.

f_t = lambdify(x, y_t,modules=['numpy'])
x = np.linspace(-10, 10, 100) #i do this because x has
#been a symbolic variable before

plt.plot(x, y_t, 'b') #this is where the problem occurs

i get the first plot also a second error message:

 File "<console>", line 1, in <module>
  File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\pyplot.py", line 2832, in plot
    ret = ax.plot(*args, **kwargs)
  File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\axes.py", line 3998, in plot
    for line in self._get_lines(*args, **kwargs):

How can i achieve my idea to plot something coming from sympy? Another idea i had was to convert the sympy out from the series to a string and then parsing this somehow to a numpy expression. I would be thankful for any help here!

解决方案

I think your problem is that this:

plt.plot(x, y_t, 'b') #this is where the problem occurs

should be something like:

plt.plot(x, f_t(x), 'b')

f_t is the lambdified series, so it is a callable function that evaluates its argument.

I used lambdify in the following example, and it works for me:

from sympy.abc import x
from sympy import sin, series
from sympy.utilities.lambdify import lambdify

import numpy as np
import matplotlib.pyplot as plt


func = sin(x)/x
taylor = series(func, n=6).removeO()

evalfunc = lambdify(x, func, modules=['numpy'])
evaltaylor = lambdify(x, taylor, modules=['numpy'])

t = np.linspace(-5.5, 5.5, 100)
plt.plot(t, evalfunc(t), 'b', label='sin(x)/x')
plt.plot(t, evaltaylor(t), 'r', label='Taylor')
plt.legend(loc='best')
plt.show()

Here's the plot generated by the script.

这篇关于绘制/转换来自sympy的表达式:使用matplotlib的泰勒级数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆