如何在Matplotlib中将拟合直线下移至触达图中最左下数据点
利用最大叉积平移拟合优度曲线至最下方目标数据点
我已得到幂律拟合曲线(在半对数图中呈现为直线),需将其向下平移,使其触达图表中位于拟合曲线下方最远的数据点。以下是完整可复现代码及实现逻辑:
import matplotlib.pyplot as plt import numpy as np from scipy.optimize import curve_fit class FatigueCurve: def __init__(self) -> None: # 原始试验数据 stress_data = [862.0,716.0,862.0,793.0,690.0,690.0,621.0,621.0,690.0,552.0,552.0,552.0] cycle_data = [1.0,1.0,11.0,160.0,563.0,680.0,4130.0,7528.0,9768.0,77843.0,115530.0,394498.0] cycles = np.array(cycle_data) stress = np.array(stress_data) # 拟合幂律曲线(对应半对数图中的直线) popt, _ = curve_fit(self.powerLaw, cycles, stress) fit_A, fit_B = popt # 生成拟合曲线的绘图采样点 plot_x = np.logspace(np.log10(min(cycles)), np.log10(max(cycles)), 100) fit_y = self.powerLaw(plot_x, fit_A, fit_B) # 定义拟合曲线的两个端点(用于叉积计算) x1, y1 = min(plot_x), max(fit_y) x2, y2 = max(plot_x), min(fit_y) # 计算每个数据点相对于拟合直线的叉积 cross_products = [] for x_point, y_point in zip(cycles, stress): # 叉积公式:反映点与直线的相对位置和距离 cp_value = (x2 - x1) * (y_point - y1) - (y2 - y1) * (x_point - x1) cross_products.append(cp_value) # 定位叉积最小的点(即拟合曲线下方最远的目标点) min_cp = np.min(cross_products) target_index = np.argmin(cross_products) target_x, target_y = cycles[target_index], stress[target_index] # 计算曲线下移量:拟合曲线在目标点x处的y值与目标点y值的差值 shift_delta = self.powerLaw(target_x, fit_A, fit_B) - target_y shifted_fit_y = fit_y - shift_delta # 可视化结果 fig, ax = plt.subplots() ax.semilogx(cycles, stress, 'bo', label='原始数据') ax.plot(plot_x, fit_y, c='red', label='初始拟合曲线') ax.plot(plot_x, shifted_fit_y, c='green', linestyle='--', label='下移后曲线') # 标记触达的目标点 ax.scatter(target_x, target_y, c='black', s=100, zorder=5, label='目标触达点') ax.set_xlabel('循环次数') ax.set_ylabel('应力') ax.legend() plt.show() def powerLaw(self, S, A, B): return A * np.power(S, B) if __name__ == "__main__": FatigueCurve()
核心逻辑说明
- 曲线拟合:使用
curve_fit拟合幂律模型y=A*x^B,得到初始拟合曲线。 - 叉积计算:通过拟合曲线的两个端点构建参考直线,计算每个数据点与该直线的叉积——负值表示点在直线下方,值越小代表距离直线越远。
- 平移量计算:找到叉积最小的目标点,计算初始拟合曲线在该点x值处的y值与目标点y值的差值,即为曲线需要向下平移的距离。
- 平移实现:将初始拟合曲线的所有y值减去平移量,得到下移后的曲线。
内容的提问来源于stack exchange,提问作者Willy
相关产品推荐
相关产品推荐

