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

如何在Matplotlib中高亮不同长度列表生成的曲线交点?

直线与Sigmoid函数交点检测及凹包络优化方案

针对直线(仅两个端点)与Sigmoid曲线(大量采样点)的交点检测问题,以及调整上界获取最紧凑凹包络的需求,提供以下可行方案:


方案1:插值直线到Sigmoid采样点集,用符号差法找交点

通过插值将直线扩展到与Sigmoid相同的x采样点上,让两个函数的点列表长度一致,即可使用你熟悉的符号差方法检测交点。

实现代码

import matplotlib.pyplot as plt
import numpy as np

a = 2.5
x = np.linspace(-5, 5, 100)
z = 1 / (1 + np.exp(-x))
# 直线端点定义
x_line = [-5, a]
y_line = [1 / (1 + np.exp(5)), 1 / (1 + np.exp(-a))]

# 将直线插值到Sigmoid的x采样点上
line_y = np.interp(x, x_line, y_line)

# 检测交点:找符号变化的位置
diff = z - line_y
cross_indices = np.argwhere(np.diff(np.sign(diff))).flatten()
cross_points = [(x[i], z[i]) for i in cross_indices]

# 绘图并高亮交点
plt.figure(figsize=(8,5))
plt.plot(x, z, '-b', label='Sigmoid函数')
plt.plot(x_line, y_line, 'o--g', label='凹包络', alpha=0.75)
for cx, cy in cross_points:
    plt.scatter(cx, cy, s=100, c='r', marker='*', label='交点')
plt.xlabel("x")
plt.ylabel("Sigmoid(x)")
plt.legend()
plt.grid()
plt.show()

方案2:数值求解联立方程,高精度找交点

直接定义直线与Sigmoid的误差函数,用数值根查找方法求解交点,不依赖采样点密度,精度更高。

实现代码

import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import root_scalar

a = 2.5
x = np.linspace(-5, 5, 100)
z = 1 / (1 + np.exp(-x))
# 直线端点
x0, x1 = -5, a
y0 = 1 / (1 + np.exp(5))
y1 = 1 / (1 + np.exp(-a))

# 直线函数表达式
def line_func(x_val):
    return y0 + (y1 - y0)/(x1 - x0) * (x_val - x0)

# 误差函数:Sigmoid值 - 直线值
def error_func(x_val):
    sigmoid_val = 1 / (1 + np.exp(-x_val))
    return sigmoid_val - line_func(x_val)

# 求解交点(在[x0, x1]区间内找根)
result = root_scalar(error_func, bracket=[x0, x1], method='brentq')
cross_x, cross_y = result.root, line_func(result.root)

# 绘图并高亮交点
plt.figure(figsize=(8,5))
plt.plot(x, z, '-b', label='Sigmoid函数')
plt.plot([x0, x1], [y0, y1], 'o--g', label='凹包络', alpha=0.75)
plt.scatter(cross_x, cross_y, s=100, c='r', marker='*', label='交点')
plt.xlabel("x")
plt.ylabel("Sigmoid(x)")
plt.legend()
plt.grid()
plt.show()

调整上界获取最紧凑凹包络

要让直线右端点与交点重合,本质是找到直线成为Sigmoid切线的上界a——此时直线仅在左端点和(a, sigmoid(a))处与Sigmoid相交,是最紧凑的凹包络线段。

实现代码(求解最优上界)

import numpy as np
from scipy.optimize import root_scalar
import matplotlib.pyplot as plt

y0 = 1 / (1 + np.exp(5))

# 定义目标函数:切线斜率与直线斜率的误差
def target_func(a):
    sig_a = 1 / (1 + np.exp(-a))
    # Sigmoid在a处的导数(切线斜率)
    tangent_slope = sig_a * (1 - sig_a)
    # 左端点到(a, sig_a)的直线斜率
    line_slope = (sig_a - y0) / (a + 5)
    return tangent_slope - line_slope

# 求解最优上界a
result = root_scalar(target_func, bracket=[0, 5], method='brentq')
optimal_a = result.root
optimal_y = 1 / (1 + np.exp(-optimal_a))

print(f"最优上界a: {optimal_a:.4f}")
print(f"对应Sigmoid值: {optimal_y:.4f}")

# 验证绘图
x = np.linspace(-5, 5, 100)
z = 1 / (1 + np.exp(-x))
plt.figure(figsize=(8,5))
plt.plot(x, z, '-b', label='Sigmoid函数')
plt.plot([-5, optimal_a], [y0, optimal_y], 'o--g', label='最优凹包络', alpha=0.75)
plt.scatter(optimal_a, optimal_y, s=100, c='r', marker='*', label='切点/交点')
plt.xlabel("x")
plt.ylabel("Sigmoid(x)")
plt.legend()
plt.grid()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:14:57