R语言如何绘制X轴归一化多折线图并生成样本平均图
问题解决方法
两个需求的核心注意点是两个样本的距离采样点不对齐、数据行数不同,绘制单样本折线时不需要特殊处理,计算平均前必须先对齐x轴坐标。
1. 同图绘制两个样本的折线
直接调用两次绘图接口,分别传入每个样本对应的x、y数据即可,不需要对齐两个样本的坐标,工具会自动按各自的坐标点位绘制。
以Python的matplotlib实现为例,代码如下:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 替换为你自己的数据读入代码,比如 df = pd.read_csv("your_data_file.csv") # 以下为匹配你给出的示例结构构造的测试数据 df = pd.DataFrame({ "distance1": [0.0000000,0.2174741,0.4349482,0.6520882,0.8695623,1.0870364,1.3045105,1.5216505,1.7391246,1.9565987,2.1740728,2.3912128], "grey1": [-300.364,-296.963,-292.887,-290.310,-285.777,-279.921,-274.418,-272.005,-273.666,-270.381,-270.273,-270.705], "distance2": [0.0000000,0.2114969,0.4229937,0.6341657,0.8456625,1.0571594,1.2686562,1.4798282,1.6913251,1.9028219,2.1143188,2.3254907], "grey2": [-135.219,-132.601,-131.959,-133.514,-127.111,-116.404,-116.850,-115.464,-102.823,-101.497,-98.245,-98.474] }) # 初始化画布 plt.figure(figsize=(8,4), dpi=100) # 绘制样本1折线 plt.plot(df["distance1"], df["grey1"], label="样本1", color="#1f77b4", linewidth=1.5) # 绘制样本2折线 plt.plot(df["distance2"], df["grey2"], label="样本2", color="#ff7f0e", linewidth=1.5) # 添加标注 plt.xlabel("归一化距离(0-100)") plt.ylabel("强度值") plt.legend() plt.grid(alpha=0.3) plt.show()
2. 绘制两个样本的平均折线
禁止直接对两列grey值求平均:两个样本的采样点不对应,直接求平均的结果完全没有意义。必须先将两个样本的强度值插值到一套统一的公共x坐标网格上,再对相同x坐标下的y值逐点求平均。
你的x轴已经归一化到0-100区间,直接生成0-100范围等间距的公共网格即可,步长可以参考你原始数据的采样间隔设置,示例代码用0.2步长:
# 生成公共x轴网格,范围0-100,步长0.2,可按需调整密度 x_common = np.arange(0, 100.1, 0.2) # 分别对两个样本做线性插值,得到公共x坐标下对应的强度值 # 先过滤空值避免插值报错 y1_interp = np.interp( x_common, df["distance1"].dropna().values, df["grey1"].dropna().values ) y2_interp = np.interp( x_common, df["distance2"].dropna().values, df["grey2"].dropna().values ) # 逐点计算平均强度 y_mean = (y1_interp + y2_interp) / 2 # 绘制平均折线,可同时叠加原始两个样本的折线做对比 plt.figure(figsize=(8,4), dpi=100) plt.plot(df["distance1"], df["grey1"], label="样本1", color="#1f77b4", alpha=0.5, linewidth=1) plt.plot(df["distance2"], df["grey2"], label="样本2", color="#ff7f0e", alpha=0.5, linewidth=1) plt.plot(x_common, y_mean, label="平均强度", color="#d62728", linewidth=2) plt.xlabel("归一化距离(0-100)") plt.ylabel("强度值") plt.legend() plt.grid(alpha=0.3) plt.show()
注意事项
- 默认用线性插值,适合连续变化的强度信号,不会引入人为的平滑偏差;如果需要更平滑的曲线,可以替换为scipy库的三次样条插值。
- 如果你的原始数据中两个样本的distance列没有覆盖到0-100全区间,
np.interp会自动用端点值填充外推区域,不需要外推的话可以把x_common的范围限制在两个样本distance的重叠区间内。
内容的提问来源于stack exchange,提问作者Ruthilia Vera
相关产品推荐
相关产品推荐

