如何用for循环绘制多条指数曲线并标记相邻曲线的交点?
问题原因
TypeError: can't multiply sequence by non-int of type 'numpy.float64'报错是因为你使用Python原生列表类型的基准参数直接和浮点缩放系数相乘,Python原生列表仅支持和整数相乘做重复操作,不支持和浮点数做元素级运算。- 仅画出单条曲线是因为没有将绘图逻辑放在缩放系数的遍历循环内,或是缩放参数生成逻辑错误导致所有曲线参数完全一致。
完整实现代码
import numpy as np import matplotlib.pyplot as plt # 定义指数函数 def exponenial_func(x, a, b): return a * np.exp(-b * x) # 基准参数转为numpy数组,避免元素级运算报错 popt1 = np.array([8.05267292e+03, 1.48857925e+00]) # 生成1到10倍、步长0.1的缩放系数,共91条曲线符合接近100条的需求 scale_arr = np.arange(1, 10.1, 0.1) # 生成x轴采样点,区间可根据实际需要调整 x = np.linspace(0, 6, 1000) # 存储所有曲线的y值用于后续交点计算 y_list = [] plt.figure(figsize=(10, 6)) # 绘制所有指数曲线 for scale in scale_arr: curr_a, curr_b = popt1 * scale curr_y = exponenial_func(x, curr_a, curr_b) y_list.append(curr_y) plt.plot(x, curr_y, linewidth=0.8, alpha=0.7) # 标记相邻两条曲线的交点 for i in range(1, len(y_list)): y_prev = y_list[i-1] y_curr = y_list[i] # 定位差值符号切换的区间,即交点所在位置 diff = y_curr - y_prev sign_change_idx = np.where(np.diff(np.sign(diff)))[0] for idx in sign_change_idx: # 线性插值计算精确交点坐标 x_left, x_right = x[idx], x[idx+1] diff_left, diff_right = diff[idx], diff[idx+1] x_intersect = x_left - diff_left * (x_right - x_left) / (diff_right - diff_left) y_intersect = exponenial_func(x_intersect, *(popt1 * scale_arr[i-1])) plt.scatter(x_intersect, y_intersect, c='red', s=10, zorder=5) plt.xlabel('x') plt.ylabel('y') plt.title('指数族曲线与相邻交点') plt.grid(alpha=0.3) plt.show()
关键逻辑说明
- 参数运算处理:所有参数运算统一使用numpy数组,避免Python原生列表的运算限制,从根源解决类型报错问题
- 多曲线绘制:遍历所有缩放系数生成对应参数的曲线,逐次调用绘图接口,设置半透明参数避免曲线重叠导致辨识度降低
- 交点计算:通过相邻曲线y值的差值符号变化定位交点所在区间,用线性插值得到精确交点坐标后使用散点标记,zorder参数保证交点标记显示在曲线上层
内容的提问来源于stack exchange,提问作者tjsmert44
相关产品推荐
相关产品推荐

