求助:基于DataFrame中sourceId值绘制ionoCorr子图/单图的问题
DataFrame分组绘图问题解决方案
需求说明
基于DataFrame数据绘制两类图表:
- X轴统一使用
iTOW字段,Y轴为ionoCorr字段 - 方案一:创建2个子图,分别展示
sourceId=1和sourceId=2的ionoCorr变化 - 方案二:在单个子图中同时绘制两组数据的折线
方案一:双生子图实现
原代码问题
- 仅筛选了
sourceId=1的数据,未处理sourceId=2的情况 - 多余的
df2.items()循环会重复创建子图,造成资源浪费 - 无意义的
twinx()调用(若不需要双Y轴)
修正代码
import matplotlib.pyplot as plt from matplotlib.backends.backend_pdf import PdfPages with PdfPages(output_file) as pdf: # 筛选两组目标数据 df_source1 = final_df1.loc[final_df1['sourceId'] == 1.0] df_source2 = final_df1.loc[final_df1['sourceId'] == 2.0] # 创建2行1列的子图,共享X轴保证刻度对齐 fig, (ax_top, ax_bottom) = plt.subplots(nrows=2, ncols=1, figsize=(8.27, 11.69), sharex=True) # 绘制sourceId=1的子图 ax_top.plot(df_source1['iTOW'], df_source1['ionoCorr'], color="green") ax_top.set_ylabel("Correction") ax_top.grid(True) ax_top.set_title(f"sourceId=1 - {input_file_path}", wrap=True) # 绘制sourceId=2的子图 ax_bottom.plot(df_source2['iTOW'], df_source2['ionoCorr'], color="red") ax_bottom.set_ylabel("Correction") ax_bottom.set_xlabel("iTOW") ax_bottom.grid(True) ax_bottom.set_title(f"sourceId=2 - {input_file_path}", wrap=True) # 自动调整子图间距,避免标题/标签重叠 plt.tight_layout() pdf.savefig() plt.close()
方案二:单图双折线实现
原代码问题
绘图区域被填充而非显示折线,核心原因:
iTOW字段未排序,导致折线乱序交叉连成填充块- 可能存在非数值类型数据,导致绘图逻辑异常
修正代码
import matplotlib.pyplot as plt from matplotlib.backends.backend_pdf import PdfPages with PdfPages(output_file) as pdf: fig, ax = plt.subplots(figsize=(8.27, 5)) # 遍历两组sourceId,绘制有序折线 for source_id, color in [(1, "green"), (2, "red")]: # 筛选数据后按iTOW排序,保证折线顺序正确 df_filtered = final_df1[final_df1['sourceId'] == source_id].sort_values(by='iTOW') ax.plot(df_filtered['iTOW'], df_filtered['ionoCorr'], color=color, label=f"Source {source_id}") # 设置图表基础属性 ax.set_ylabel("Correction") ax.set_xlabel("iTOW") ax.grid(True) ax.legend() ax.set_title(input_file_path, wrap=True) pdf.savefig() plt.close()
额外排查步骤
- 检查数据类型:执行
final_df1.dtypes确认iTOW和ionoCorr为数值类型,若为object则转换:final_df1[['iTOW', 'ionoCorr']] = final_df1[['iTOW', 'ionoCorr']].astype(float) - 若数据量过大,可采样后绘图:
df_filtered = df_filtered.sample(frac=0.1, random_state=42) # 采样10%数据
内容的提问来源于stack exchange,提问作者Kapil
相关产品推荐
相关产品推荐

