如何优化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
相关产品推荐
相关产品推荐

