如何为多份材料测试CSV文件绘制应力应变平均线?
应力应变曲线添加平均线的实现方案
需求背景
我正在处理9份同类材料样本测试的CSV文件,已通过代码将所有样本的应力应变曲线绘制在同一张图中,现在希望添加一条平均线来对比同类材料的测试结果,减少图中曲线数量。不确定是生成存储平均值的新CSV文件,还是直接在现有循环中计算平均值,寻求最优方案。理想效果为在多条测试曲线之上叠加一条加粗的黑色平均线,作为所有样本的性能参考基准。
数据格式示例
Time,Displacement,Force,Flexure stress,Flexure strain (Displacement) (s),(mm),(N),(MPa),(%) "0.0000","0.0000","0.0007","0.0000","0.0000" "0.0200","0.0000","0.0069","0.0004","0.0000" "0.0400","0.0001","-0.0024","-0.0001","0.0003" "0.0600","0.0005","0.0040","0.0002","0.0014" "0.0800","0.0014","0.0106","0.0006","0.0041"
现有绘图代码
import os import pandas as pd import matplotlib.pyplot as plt import numpy as np ### Set path to the folder containing the .csv files PATH = 'my path' ### Fetch all files in path fileNames = os.listdir(PATH) ### Filter file name list for files ending with .csv fileNames = [file for file in fileNames if '.csv' in file] ### Loop over all files for file in fileNames: ### Read .csv file and append to list df = pd.read_csv(PATH + file, usecols = [3, 4], skiprows=2, names=['Stress', 'Strain'], header=None) strain_df = df['Strain']*0.01 side = 6.2 #mm stress_df = (df['Stress'])/(side**2) # N/mm**2 ### Create line for every file plt.plot(strain_df, stress_df) ### Generate the plot plt.xlabel(r'Strain $\epsilon$ (mm/mm)') plt.ylabel(r'Stress $\sigma$ (N/mm$^2$)') plt.title(r'Stress Strain Curve - 4$^\circ$C/min ') plt.show()
方案建议
两种方式各有适用场景:
- 直接计算平均值绘图:如果仅需完成当前绘图需求,无需后续复用平均值数据,这种方式更高效,无需额外存储文件。
- 生成平均值CSV文件:如果需要后续对平均值数据进行分析、复现或其他用途,建议将平均值保存为CSV,方便后续调用。
方式1:直接计算并绘制平均线
修改现有代码,在循环中收集所有样本的应力数据,计算平均值后叠加绘图:
import os import pandas as pd import matplotlib.pyplot as plt import numpy as np PATH = 'my path' fileNames = [file for file in os.listdir(PATH) if '.csv' in file] # 初始化列表存储所有样本的应力数据 all_stress = [] # 存储基准应变序列(取第一个文件的应变,假设所有文件应变点一致) base_strain = None for file in fileNames: df = pd.read_csv(PATH + file, usecols=[3,4], skiprows=2, names=['Stress','Strain'], header=None) strain_df = df['Strain']*0.01 side = 6.2 stress_df = df['Stress']/(side**2) plt.plot(strain_df, stress_df, alpha=0.5) # 原曲线设为半透明,突出平均线 # 存储应变和应力数据 if base_strain is None: base_strain = strain_df.values all_stress.append(stress_df.values) # 计算平均应力 mean_stress = np.mean(all_stress, axis=0) # 绘制平均线 plt.plot(base_strain, mean_stress, color='black', linewidth=2, label='Average') plt.xlabel(r'Strain $\epsilon$ (mm/mm)') plt.ylabel(r'Stress $\sigma$ (N/mm$^2$)') plt.title(r'Stress Strain Curve - 4$^\circ$C/min ') plt.legend() plt.show()
方式2:计算平均值并保存为CSV文件
在方式1的基础上,添加保存CSV的逻辑,后续可直接读取该文件绘图:
import os import pandas as pd import matplotlib.pyplot as plt import numpy as np PATH = 'my path' fileNames = [file for file in os.listdir(PATH) if '.csv' in file] all_stress = [] base_strain = None for file in fileNames: df = pd.read_csv(PATH + file, usecols=[3,4], skiprows=2, names=['Stress','Strain'], header=None) strain_df = df['Strain']*0.01 side = 6.2 stress_df = df['Stress']/(side**2) plt.plot(strain_df, stress_df, alpha=0.5) if base_strain is None: base_strain = strain_df.values all_stress.append(stress_df.values) mean_stress = np.mean(all_stress, axis=0) # 保存平均值到CSV mean_df = pd.DataFrame({'Strain': base_strain, 'Stress': mean_stress}) mean_df.to_csv(os.path.join(PATH, 'average_stress_strain.csv'), index=False) # 绘制平均线 plt.plot(base_strain, mean_stress, color='black', linewidth=2, label='Average') plt.xlabel(r'Strain $\epsilon$ (mm/mm)') plt.ylabel(r'Stress $\sigma$ (N/mm$^2$)') plt.title(r'Stress Strain Curve - 4$^\circ$C/min ') plt.legend() plt.show()
注:如果不同文件的应变点数量或数值不一致,需先对所有样本的应力数据进行插值对齐(例如以统一的应变序列为基准,用
np.interp插值得到对应应力),再计算平均值,确保平均线的准确性。
内容的提问来源于stack exchange,提问作者Anders Bleak
相关产品推荐
相关产品推荐

