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

如何优化Python中年度月度聚合数据的子图绘制代码?

优化年度月度NET值子图绘制代码

我编写了一段代码,用于绘制8个子图展示数据中按月度聚合的各年度NET值。尝试用循环优化这段冗长代码,但不知道如何处理Pandas DataFrame的query部分,希望能改写或优化。VF_data是包含年度、月度聚合正负数值以及month、year、date列的Pandas DataFrame,原代码如下:

def plot_MTY(df, aggregate_col='NET'):   

plt.subplot(2, 4, 1)
VF_data=df.query("(YEAR == '2015')")
aggregated_target = aggregate_data(VF_data, 'DATES', aggregate_col)
plt.plot(aggregated_target, label = 'df', linestyle="-")
plt.axhline(y=0, color='b', linestyle='-')
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)

plt.subplot(2, 4, 2)
VF_data=df.query("(YEAR == '2016')")
aggregated_target = aggregate_data(VF_data, 'DATES', aggregate_col)
plt.plot(aggregated_target, label = 'df', linestyle="-")
plt.axhline(y=0, color='b', linestyle='-')
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)

plt.subplot(2, 4, 3)
VF_data=df.query("(YEAR == '2017')")
aggregated_target = aggregate_data(VF_data, 'DATES', aggregate_col)
plt.plot(aggregated_target, label = 'df', linestyle="-")
plt.axhline(y=0, color='b', linestyle='-')
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)

plt.subplot(2, 4, 4)
VF_data=df.query("(YEAR == '2018')")
aggregated_target = aggregate_data(VF_data, 'DATES', aggregate_col)
plt.plot(aggregated_target, label = 'df', linestyle="-")
plt.axhline(y=0, color='b', linestyle='-')
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)

plt.subplot(2, 4, 5)
VF_data=df.query("(YEAR == '2019')")
aggregated_target = aggregate_data(VF_data, 'DATES', aggregate_col)
plt.plot(aggregated_target, label = 'df', linestyle="-")
plt.axhline(y=0, color='b', linestyle='-')
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)

plt.subplot(2, 4, 6)
VF_data=df.query("(YEAR == '2020')")
aggregated_target = aggregate_data(VF_data, 'DATES', aggregate_col)
plt.plot(aggregated_target, label = 'df', linestyle="-")
plt.axhline(y=0, color='b', linestyle='-')
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)

plt.subplot(2, 4, 7)
VF_data=df.query("(YEAR == '2021')")
aggregated_target = aggregate_data(VF_data, 'DATES', aggregate_col)
plt.plot(aggregated_target, label = 'df', linestyle="-")
plt.axhline(y=0, color='b', linestyle='-')
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)

plt.subplot(2, 4, 8)
VF_data=df.query("(YEAR == '2022')")
aggregated_target = aggregate_data(VF_data, 'DATES', aggregate_col)
plt.plot(aggregated_target, label = 'df', linestyle="-")
plt.axhline(y=0, color='b', linestyle='-')
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)

plt.gcf().set_size_inches(15, 8)
plt.show()

优化后的代码

import matplotlib.pyplot as plt

def plot_MTY(df, aggregate_col='NET'):
    # 定义需要展示的年份列表,也可以从数据中自动提取:df['YEAR'].unique()
    years = ['2015', '2016', '2017', '2018', '2019', '2020', '2021', '2022']
    # 一次性创建2行4列的子图布局,指定整体尺寸
    fig, axes = plt.subplots(2, 4, figsize=(15, 8))
    # 将二维axes数组扁平化,方便循环遍历
    axes = axes.flatten()
    
    for idx, year in enumerate(years):
        # 用布尔索引筛选年份数据,替代query写法,适配循环变量传入
        year_data = df[df['YEAR'] == year]
        # 执行数据聚合
        aggregated_target = aggregate_data(year_data, 'DATES', aggregate_col)
        
        # 获取当前子图对象
        ax = axes[idx]
        # 绘制折线图
        ax.plot(aggregated_target, label='df', linestyle="-")
        # 添加0值参考线
        ax.axhline(y=0, color='b', linestyle='-')
        # 设置x轴标签旋转90度
        ax.tick_params(axis='x', rotation=90)
        # 给子图添加年度标题,提升可读性
        ax.set_title(f'年度 {year}')
    
    # 自动调整子图间距,避免标签重叠
    plt.tight_layout()
    plt.show()

优化说明

  • 替代query逻辑:用df[df['YEAR'] == year]的布尔索引替代query字符串查询,避免循环中拼接字符串的麻烦,代码更简洁易维护
  • 批量创建子图:使用plt.subplots一次性生成所有子图,返回的axes数组扁平化后可直接按索引匹配年份,无需手动指定subplot(2,4,n)
  • 复用绘图逻辑:把重复的绘图、格式设置逻辑放入循环,通过枚举年份和子图索引一一对应,消除代码冗余
  • 提升图表可读性:给每个子图添加年度标题,用tight_layout自动调整布局避免元素重叠
  • 灵活适配数据:年份列表可以替换为df['YEAR'].unique(),自动适配数据中存在的所有年份,无需手动修改年份值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:30:52