You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Matplotlib绘图中查找并显示特定坐标点?

问题

我用plt.plot(xdata,ydata)绘制了一幅图,希望找到y坐标等于125.94937644205281 + 1(卡方值+1)时对应的x坐标,并将该点在图中显示出来。尝试过找根法,但寻找满足卡方+1的参数耗时极久,代码还陷入了无限循环。如果Matplotlib没有直接查找图中特定点的方法,应该选择哪种求解器?如何使用?

附上我尝试的代码:

target = chisq_min + 1
def target_chisq_plus1 (gradient):
    return chisq([gradient], xval, yval, yerr) - target

# 寻找根
initials = [(a_soln, 0.0121320), (0.0122193, a_soln)] # <- 导致卡方值+1的两个参数初始边界

tolerance = 0.01
chisquard_plus_one_solutions = []
while True:
    for initial in initials:
        if target_chisq_plus1(initial[0]) > 0:
            xp = initial[0]
            xn = initial[1]
        else:
            xp = initial[1]
            xn = initial[0]
        next_approximation = (xp + xn) / 2
        if target_chisq_plus1(next_approximation) > 0:
            xp = next_approximation
        else:
            xn = next_approximation
        if abs(target_chisq_plus1(next_approximation)) < tolerance:
            gradient_solutions.append((next_approximation, chisq([next_approximation], xval, yval, yerr)))
            break
解决方案

1. 用SciPy专业求解器替代手动二分法

你手动实现的二分法存在逻辑漏洞(比如while True无终止条件,极易无限循环),直接用SciPy内置的求解器更高效可靠,推荐scipy.optimize.bisect或root_scalar,二者都是专门针对单变量函数找根的工具:

示例代码(bisect版本)

from scipy.optimize import bisect
import matplotlib.pyplot as plt

# 保留你的目标值与目标函数
target = chisq_min + 1
def target_chisq_plus1(gradient):
    return chisq([gradient], xval, yval, yerr) - target

gradient_solutions = []
# 遍历每个初始边界对求解
for lower, upper in initials:
    # bisect要求区间两端函数值符号相反,先做校验
    if target_chisq_plus1(lower) * target_chisq_plus1(upper) >= 0:
        print(f"区间[{lower}, {upper}]两端函数值符号相同,无法用bisect求解")
        continue
    # 执行求解,设置精度阈值
    sol = bisect(target_chisq_plus1, lower, upper, xtol=0.01)
    gradient_solutions.append((sol, chisq([sol], xval, yval, yerr)))

选择SciPy求解器的优势

  • 自带收敛判断与终止条件,不会陷入无限循环
  • 经过底层优化,求解速度远快于手动实现的二分法
  • 严谨处理边界异常情况,避免无效计算

2. 在Matplotlib图中标注目标点

找到x坐标后,用plt.scatter标记点,搭配plt.annotate添加坐标标注:

# 先绘制原始曲线
plt.plot(xdata, ydata, label='原始曲线')

# 遍历所有解,逐个标注
for x_sol, y_sol in gradient_solutions:
    # 红色标记目标点,zorder确保点在曲线上方
    plt.scatter(x_sol, y_sol, color='red', s=50, zorder=5)
    # 添加坐标文本,偏移位置避免遮挡
    plt.annotate(f'({x_sol:.4f}, {y_sol:.4f})', 
                 xy=(x_sol, y_sol), 
                 xytext=(x_sol+0.0001, y_sol+2),
                 fontsize=10)

plt.xlabel('X轴')
plt.ylabel('Y轴(卡方值)')
plt.legend()
plt.show()

3. 额外提示

  • 若chisq是多变量函数,需要找二维卡方+1等高线,可改用scipy.optimize.root或scipy.optimize.minimize来寻找满足条件的参数组合
  • 初始区间尽量缩小合理范围,能大幅提升求解效率

内容的提问来源于stack exchange,提问作者D Son

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:25:32