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

如何用Python迭代实现多ID的DataFrame重叠子图绘制?

迭代绘制多ID的双数据源重叠子图

核心思路

先提取两个DataFrame中所有唯一的id,根据ID数量动态生成子图布局,然后循环每个ID,统一执行数据筛选、绘图、样式设置的逻辑,彻底避免重复编写子图代码。

完整实现代码

import pandas as pd
import matplotlib.pyplot as plt

# ----------------------
# 示例数据(可替换为你的真实数据)
# ----------------------
df_1 = pd.DataFrame({
    'id': [1,1,2,2,3,3,4,4],
    'cycle': [1,2,1,2,1,2,1,2],
    'Salary': [5000, 5500, 6000, 6200, 7000, 7500, 8000, 8300]
})

df_2 = pd.DataFrame({
    'id': [1,1,2,2,3,3,4,4],
    'cycle': [1,2,1,2,1,2,1,2],
    'Salary': [4800, 5300, 5900, 6100, 6800, 7300, 7800, 8100]
})

# ----------------------
# 核心绘图逻辑
# ----------------------
# 获取所有唯一ID(两个DF结构一致,取任意一个即可)
unique_ids = df_1['id'].unique()
total_ids = len(unique_ids)

# 设置子图布局:2列,自动计算行数
cols = 2
rows = (total_ids + cols - 1) // cols  # 向上取整计算行数

# 创建画布和子图集合
fig, axes = plt.subplots(rows, cols, figsize=(14, 10))
axes = axes.flatten()  # 将多维子图数组转为一维,方便循环遍历

# 循环每个ID绘制子图
for idx, current_id in enumerate(unique_ids):
    # 筛选当前ID的两组数据
    df1_filtered = df_1[df_1['id'] == current_id]
    df2_filtered = df_2[df_2['id'] == current_id]
    
    # 获取当前子图对象
    ax = axes[idx]
    
    # 绘制两条重叠曲线
    ax.plot(df1_filtered['cycle'], df1_filtered['Salary'], 
            marker='o', color='#1f77b4', linewidth=2, label='df_1')
    ax.plot(df2_filtered['cycle'], df2_filtered['Salary'], 
            marker='s', color='#ff7f0e', linewidth=2, label='df_2')
    
    # 设置子图样式
    ax.set_title(f'ID: {current_id}', fontsize=12, fontweight='bold')
    ax.set_xlabel('Cycle', fontsize=10)
    ax.set_ylabel('Salary', fontsize=10)
    ax.legend()
    ax.grid(True, alpha=0.3, linestyle='--')

# 隐藏多余的空白子图(当ID数量不是列数的整数倍时)
for ax in axes[total_ids:]:
    ax.axis('off')

# 自动调整子图间距,避免标签重叠
plt.tight_layout()
plt.show()

优化扩展:封装绘图函数

如果需要多次复用绘图逻辑,可以把单ID的绘图代码封装成独立函数,让主代码更简洁:

def plot_salary_by_id(ax, df_a, df_b, target_id):
    """
    在指定子图上绘制单个ID的双数据源Salary曲线
    :param ax: 子图对象
    :param df_a: 第一个DataFrame
    :param df_b: 第二个DataFrame
    :param target_id: 要绘制的ID值
    """
    df_a_sub = df_a[df_a['id'] == target_id]
    df_b_sub = df_b[df_b['id'] == target_id]
    
    ax.plot(df_a_sub['cycle'], df_a_sub['Salary'], 
            marker='o', color='#1f77b4', linewidth=2, label='df_1')
    ax.plot(df_b_sub['cycle'], df_b_sub['Salary'], 
            marker='s', color='#ff7f0e', linewidth=2, label='df_2')
    
    ax.set_title(f'ID: {target_id}', fontsize=12, fontweight='bold')
    ax.set_xlabel('Cycle', fontsize=10)
    ax.set_ylabel('Salary', fontsize=10)
    ax.legend()
    ax.grid(True, alpha=0.3, linestyle='--')

调用时只需在循环中执行:

for idx, current_id in enumerate(unique_ids):
    plot_salary_by_id(axes[idx], df_1, df_2, current_id)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:53:26