Matplotlib仅绘制星形线复函数一半?求完整绘制解决方案
星形线方程仅显示一半图形及
real_root()报错问题解决 问题概况
- 能正常绘制
y=(2*x + 1)**(1/3)-(2*x - 1)**(1/3)这类复函数,但绘制星形线方程x**(2/3) + y**(2/3) = 4**(2/3)时,仅显示一半图形。 - 尝试用
real_root()方法时触发报错:All-NaN axis encountered y_max = np.nanmax([self._bbox[1][1], y], axis=0) - 调整
adaptive参数、改用plot_implicit替代plot后,问题依旧。
原测试代码:
import matplotlib.pyplot as plt import numpy as np from sympy import * from matplotlib.colors import ListedColormap import spb import regex def queryMatplotlibEq(qVal): x, y = symbols('x y', real= True) lhs, rhs = qVal.split('=') lhs = eval(lhs) rhs = eval(rhs) expr = lhs - rhs sols = solve(expr, y) spb.plot(*sols, (x, -10, 10), {"color": "teal"},legend=False, aspect="equal",xlim=(-5,5), ylim=(-5, 5), show=True, adaptive=True,n=10000,is_point=True) # 可正常运行的示例 # qVal="y=(2*x + 1)**(1/3)-(2*x - 1)**(1/3)" # qVal="y=real_root((2*x + 1), 3) - real_root((2*x - 1), 3)" # 出现问题的示例 qVal="x**(2/3) + y**(2/3) = 4**(2/3)" # qVal="real_root((x**2),3) + real_root((y**2),3) = real_root(16,3)" queryMatplotlibEq(qVal)
问题原因
sympy.solve求解星形线方程时,默认只返回非负平方根分支,导致仅绘制出上半部分图形。- 使用
real_root(x**2, 3)时,虽然x²非负,但符号运算转数值计算的过程中,容易出现NaN值,触发边界计算报错。
解决方法
方法一:手动补全正负分支
在求解后为每个解添加负分支,覆盖上下两部分图形:
import matplotlib.pyplot as plt import numpy as np from sympy import * import spb import regex def queryMatplotlibEq(qVal): x, y = symbols('x y', real= True) lhs, rhs = qVal.split('=') lhs = eval(lhs) rhs = eval(rhs) expr = lhs - rhs sols = solve(expr, y) # 生成正负分支,确保完整图形 all_sols = [] for sol in sols: all_sols.append(sol) all_sols.append(-sol) # 绘制所有分支 spb.plot(*all_sols, (x, -8, 8), {"color": "teal"},legend=False, aspect="equal",xlim=(-5,5), ylim=(-5, 5), show=True, adaptive=True,n=10000) # 测试星形线方程 qVal="x**(2/3) + y**(2/3) = 4**(2/3)" queryMatplotlibEq(qVal)
方法二:用参数方程绘制(更稳定)
星形线的标准参数方程为x = 4*cos(t)³、y = 4*sin(t)³(t∈[0, 2π]),完全规避分支丢失问题:
import matplotlib.pyplot as plt import numpy as np t = np.linspace(0, 2*np.pi, 1000) x = 4 * np.cos(t)**3 y = 4 * np.sin(t)**3 plt.figure(figsize=(6,6)) plt.plot(x, y, color='teal') plt.xlim(-5,5) plt.ylim(-5,5) plt.gca().set_aspect('equal') plt.show()
方法三:调整隐函数方程形式
把x**(2/3)替换为(x**2)**(1/3),确保sympy能正确识别所有实根,再用plot_implicit绘制:
import matplotlib.pyplot as plt from sympy import * import spb x, y = symbols('x y', real=True) # 重新定义方程,确保实根计算逻辑正确 expr = (x**2)**(1/3) + (y**2)**(1/3) - (4**2)**(1/3) spb.plot_implicit(expr, (x, -5,5), (y,-5,5), {"color": "teal"}, aspect="equal", show=True)
内容的提问来源于stack exchange,提问作者Joshua Guevara
相关产品推荐
相关产品推荐

