Python绘制函数与x轴相切交点问题:以x²为例
解决x²与x轴交点检测的问题
你遇到的核心问题是重根交点的检测失效:x²=0的根是二重根,函数值在根的两侧始终非负,没有符号变化,所以依赖np.diff(np.sign(g))的原方法无法捕捉到这个交点。而直接用g < epsilon会选中根附近所有满足条件的采样点,自然会出现一堆红点。
下面给两种实用的解决方案:
方案一:用数值求根工具精准定位(推荐)
既然找交点本质是解方程g(x)=0,直接用数值求根库能精准拿到根的位置,不管是普通根还是重根都能处理。示例代码:
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import root_scalar # 定义目标函数 def func(x): return x ** 2 # 调用数值求根,指定搜索区间和方法 root_result = root_scalar(func, bracket=[-1, 1], method='brentq') root_x = root_result.root root_y = func(root_x) # 绘图展示 x = np.arange(-5, 5, 0.01) plt.plot(x, func(x), '-') plt.plot(root_x, root_y, 'ro') plt.axhline(y=0, color='gray', linestyle='--') # 画出x轴更直观 plt.show()
这个方法的优势是通用性极强,不管是多项式还是复杂的自定义函数,只要连续就能用,结果精准。如果是多项式函数,还可以用np.roots([1, 0, 0])直接求出所有根(返回array([0., 0.]))。
方案二:纯numpy改进采样检测逻辑
如果不想引入scipy,可以结合符号变化检测普通根和极值点检测重根的思路:
- 原方法保留,用来检测函数跨轴的普通交点;
- 检测函数的极值点,判断极值点的函数值是否足够接近0(即重根情况);
- 合并两种结果,去重后得到所有交点。
示例代码:
import numpy as np import matplotlib.pyplot as plt x = np.arange(-5, 5, 0.01) g = x ** 2 # 检测普通跨轴交点(原方法) sign_change_idx = np.argwhere(np.diff(np.sign(g))).flatten() # 检测重根:找极值点且函数值接近0的位置 # 近似计算导数(差分) derivative = np.diff(g) / np.diff(x) # 找导数变号的位置(极值点) extrema_idx = np.argwhere(np.diff(np.sign(derivative))).flatten() # 筛选出极值点中函数值足够小的 epsilon = 1e-4 root_extrema_idx = extrema_idx[g[extrema_idx] < epsilon] # 合并并去重所有交点索引 all_root_idx = np.unique(np.concatenate([sign_change_idx, root_extrema_idx])) # 绘图 plt.plot(x, g, '-') plt.plot(x[all_root_idx], g[all_root_idx], 'ro') plt.axhline(y=0, color='gray', linestyle='--') plt.show()
这种方案不需要额外依赖,适合轻量场景,能同时处理普通根和重根的情况。
内容的提问来源于stack exchange,提问作者Hgorski6
相关产品推荐
相关产品推荐

