Plot/Convert an expression coming from sympy: Tayl

2020-06-27 07:51发布

问题:

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!

回答1:

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.