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

如何在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()

核心逻辑说明

  1. 曲线拟合:使用curve_fit拟合幂律模型y=A*x^B,得到初始拟合曲线。
  2. 叉积计算:通过拟合曲线的两个端点构建参考直线,计算每个数据点与该直线的叉积——负值表示点在直线下方,值越小代表距离直线越远。
  3. 平移量计算:找到叉积最小的目标点,计算初始拟合曲线在该点x值处的y值与目标点y值的差值,即为曲线需要向下平移的距离。
  4. 平移实现:将初始拟合曲线的所有y值减去平移量,得到下移后的曲线。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 08:17:53