sympy matplotlib 分段类型错误?
sympy matplolib piecewise TypeError?
matplotlib 类型错误?请告诉我区别。
我想用plt.plot
好的
from sympy import *
from sympy.plotting import plot
var('x')
def main():
p=Piecewise((0, x < 2), (2 * x - 4, x <= 4), (12 - 2 * x, x <= 6), (2 * x - 12, x <= 12), (36 - 2 * x, x <= 18),
(2 * x - 36, x <= 36))
plot(p)
if __name__ == '__main__':
main()
Error.why?
from sympy import *
import matplotlib.pyplot as plt
var('x')
def main():
p=Piecewise((0, x < 2), (2 * x - 4, x <= 4), (12 - 2 * x, x <= 6), (2 * x - 12, x <= 12), (36 - 2 * x, x <= 18),
(2 * x - 36, x <= 36))
plt.plot(p)
# plt.show()
if __name__ == '__main__':
main()
引发 TypeError(“无法将表达式转换为浮点数”)
类型错误:无法将表达式转换为浮点数
(参考)
Sympy issues with plotting a piecewise function
sympy piecewise:How can I plot a piecewise function using matplotlib?
(20220315)
import sympy as sym
import matplotlib.pyplot as plt
import numpy as np
x = sym.symbols('x')
p = sym.Piecewise(( 0,x<= 2),
( 2*x- 4,x<= 4),
(-2*x+12,x<= 6),
( 2*x-12,x<=12),
(-2*x+36,x<=18),
( 2*x-36,x<=36)
)
xvals = np.linspace(0, 36, 100)
f = sym.lambdify(x, p)
yvals = f(xvals)
plt.plot(xvals, yvals)
# plt.savefig('myPoly.png', dpi=200)
plt.show()
In [182]: x
Out[182]: x
In [183]: p = Piecewise(
...: (0, x < 2),
...: (2 * x - 4, x <= 4),
...: (12 - 2 * x, x <= 6),
...: (2 * x - 12, x <= 12),
...: (36 - 2 * x, x <= 18),
...: (2 * x - 36, x <= 36),
...: )
In [184]: type(p)
Out[184]: Piecewise
In [185]: float(p)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [185], in <module>
----> 1 float(p)
File /usr/local/lib/python3.8/dist-packages/sympy/core/expr.py:359, in Expr.__float__(self)
357 if result.is_number and result.as_real_imag()[1]:
358 raise TypeError("can't convert complex to float")
--> 359 raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float
您可以在 x
值处评估 p
:
In [186]: p.subs(x, 12.3)
Out[186]: 11.4000000000000
或值列表:
In [189]: alist = [p.subs(x,i) for i in np.arange(0,10)]
In [190]: alist
Out[190]: [0, 0, 0, 2, 4, 2, 0, 2, 4, 6]
但您不能简单地将它扔到 matplotlib
并期望它做同样的事情。
Matplotlib 需要点数组而不是符号表达式。 SymPy 的 plot
函数旨在为您处理该转换。如果你想使用 matplotlib 的 plot 函数,那么你需要制作 x 和 y 值的数组而不是给它一个表达式。这样做的有效方法是 lambdify
:
In [1]: import sympy as sym
In [2]: import matplotlib.pyplot as plt
In [3]: import numpy as np
In [4]: x = sym.symbols('x')
In [6]: p = sym.Piecewise((0, x < 2), (2 * x - 4, x <= 4), (12 - 2 * x, x <= 6), (2 * x - 12, x <= 12), (36 - 2 * x, x <= 18), (2 * x - 36, x <= 36))
In [8]: sym.pprint(p)
⎧ 0 for x < 2
⎪
⎪2⋅x - 4 for x ≤ 4
⎪
⎪12 - 2⋅x for x ≤ 6
⎨
⎪2⋅x - 12 for x ≤ 12
⎪
⎪36 - 2⋅x for x ≤ 18
⎪
⎩2⋅x - 36 for x ≤ 36
In [9]: xvals = np.linspace(0, 36, 100)
In [11]: f = sym.lambdify(x, p)
In [12]: yvals = f(xvals)
In [13]: plt.plot(xvals, yvals)
Out[13]: [<matplotlib.lines.Line2D at 0x7f64940c13a0>]
In [14]: plt.show()
https://docs.sympy.org/latest/modules/utilities/lambdify.html#sympy.utilities.lambdify.lambdify
matplotlib 类型错误?请告诉我区别。
我想用plt.plot
好的
from sympy import *
from sympy.plotting import plot
var('x')
def main():
p=Piecewise((0, x < 2), (2 * x - 4, x <= 4), (12 - 2 * x, x <= 6), (2 * x - 12, x <= 12), (36 - 2 * x, x <= 18),
(2 * x - 36, x <= 36))
plot(p)
if __name__ == '__main__':
main()
Error.why?
from sympy import *
import matplotlib.pyplot as plt
var('x')
def main():
p=Piecewise((0, x < 2), (2 * x - 4, x <= 4), (12 - 2 * x, x <= 6), (2 * x - 12, x <= 12), (36 - 2 * x, x <= 18),
(2 * x - 36, x <= 36))
plt.plot(p)
# plt.show()
if __name__ == '__main__':
main()
引发 TypeError(“无法将表达式转换为浮点数”) 类型错误:无法将表达式转换为浮点数
(参考)
Sympy issues with plotting a piecewise function
sympy piecewise:How can I plot a piecewise function using matplotlib?
(20220315)
import sympy as sym
import matplotlib.pyplot as plt
import numpy as np
x = sym.symbols('x')
p = sym.Piecewise(( 0,x<= 2),
( 2*x- 4,x<= 4),
(-2*x+12,x<= 6),
( 2*x-12,x<=12),
(-2*x+36,x<=18),
( 2*x-36,x<=36)
)
xvals = np.linspace(0, 36, 100)
f = sym.lambdify(x, p)
yvals = f(xvals)
plt.plot(xvals, yvals)
# plt.savefig('myPoly.png', dpi=200)
plt.show()
In [182]: x
Out[182]: x
In [183]: p = Piecewise(
...: (0, x < 2),
...: (2 * x - 4, x <= 4),
...: (12 - 2 * x, x <= 6),
...: (2 * x - 12, x <= 12),
...: (36 - 2 * x, x <= 18),
...: (2 * x - 36, x <= 36),
...: )
In [184]: type(p)
Out[184]: Piecewise
In [185]: float(p)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [185], in <module>
----> 1 float(p)
File /usr/local/lib/python3.8/dist-packages/sympy/core/expr.py:359, in Expr.__float__(self)
357 if result.is_number and result.as_real_imag()[1]:
358 raise TypeError("can't convert complex to float")
--> 359 raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float
您可以在 x
值处评估 p
:
In [186]: p.subs(x, 12.3)
Out[186]: 11.4000000000000
或值列表:
In [189]: alist = [p.subs(x,i) for i in np.arange(0,10)]
In [190]: alist
Out[190]: [0, 0, 0, 2, 4, 2, 0, 2, 4, 6]
但您不能简单地将它扔到 matplotlib
并期望它做同样的事情。
Matplotlib 需要点数组而不是符号表达式。 SymPy 的 plot
函数旨在为您处理该转换。如果你想使用 matplotlib 的 plot 函数,那么你需要制作 x 和 y 值的数组而不是给它一个表达式。这样做的有效方法是 lambdify
:
In [1]: import sympy as sym
In [2]: import matplotlib.pyplot as plt
In [3]: import numpy as np
In [4]: x = sym.symbols('x')
In [6]: p = sym.Piecewise((0, x < 2), (2 * x - 4, x <= 4), (12 - 2 * x, x <= 6), (2 * x - 12, x <= 12), (36 - 2 * x, x <= 18), (2 * x - 36, x <= 36))
In [8]: sym.pprint(p)
⎧ 0 for x < 2
⎪
⎪2⋅x - 4 for x ≤ 4
⎪
⎪12 - 2⋅x for x ≤ 6
⎨
⎪2⋅x - 12 for x ≤ 12
⎪
⎪36 - 2⋅x for x ≤ 18
⎪
⎩2⋅x - 36 for x ≤ 36
In [9]: xvals = np.linspace(0, 36, 100)
In [11]: f = sym.lambdify(x, p)
In [12]: yvals = f(xvals)
In [13]: plt.plot(xvals, yvals)
Out[13]: [<matplotlib.lines.Line2D at 0x7f64940c13a0>]
In [14]: plt.show()
https://docs.sympy.org/latest/modules/utilities/lambdify.html#sympy.utilities.lambdify.lambdify