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

如何为Matplotlib条形图子图添加顶部统一图例,现有代码执行卡顿

问题修复方案

核心错误原因

  • 直接调用axs.get_legend_handles_labels()报错:axs是存放3个子图对象的numpy数组,只有单个子图(Axes实例)才支持get_legend_handles_labels()方法,需要手动收集所有子图的图例句柄与标签。
  • 执行卡顿常见诱因:x轴使用DateTimeStamp字符串作为刻度,若数据量过大,再配合300DPI大尺寸画布、LaTeX文字渲染,会显著增加计算量,导致卡顿。

修正后完整代码

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('energy_production_ver4.csv', sep=",")

# 画布参数配置
fs = 4  # 30
lw = 2  # 3
width_bars=0.5
ec = 'dimgray'

# 创建子图
fig, axs = plt.subplots(3, sharex=True, sharey=True, num=None, figsize=(25, 16), dpi=300, facecolor='w',
                        edgecolor='k')  # 26 15
plt.rc('text', usetex=True)
plt.rc('font', family='serif')
plt.rc('font', size=fs-1)
plt.gcf().subplots_adjust(bottom=0.15)

# 读取数据列
temp_x=df["DateTimeStamp"]
y1 = df['Production']
y2 = df['Consumption']
y3 = df['Production CHP 22kW']
y4 = df['Battery charge']
y5 = df['Battery discharge']
y6 = df['Grid supply']
y7 = df['Feed in grid']

# 绘制第一个子图
axs[0].yaxis.grid(linestyle=':')
axs[0].tick_params(axis='both', labelsize=fs)
axs[0].bar(temp_x, y1, label=r'$PV^\mathrm{s}$', color='blue', linewidth=lw / 2, width=width_bars)
axs[0].bar(temp_x, y2, label=r'$EV^\mathrm{s}$', color='orange', linewidth=lw / 2, width=width_bars)
axs[0].bar(temp_x, y3, label=r'CHP', color='green', linewidth=lw / 2, width=width_bars)
axs[0].set_ylabel(r'Energy in MWh', fontsize=fs)

# 绘制第二个子图
axs[1].yaxis.grid(linestyle=':')
axs[1].tick_params(axis='both', labelsize=fs)
axs[1].bar(temp_x, y4, label=r'$BSS^\mathrm{CH}$', color='red', linewidth=lw / 2, width=width_bars)
axs[1].bar(temp_x, y5, label=r'$BSS^\mathrm{d}$', color='purple', linewidth=lw / 2, width=width_bars)
axs[1].set_ylabel(r'Energy in MWh', fontsize=fs)

# 绘制第三个子图
axs[2].yaxis.grid(linestyle=':')
axs[2].tick_params(axis='both', labelsize=fs)
axs[2].bar(temp_x, y6, label=r'$GRID^\mathrm{CH}$', color='brown', linewidth=lw / 2, width=width_bars)
axs[2].bar(temp_x, y7, label=r'$GRID^\mathrm{d}$', color='pink', linewidth=lw / 2, width=width_bars)
axs[2].set_ylabel(r'Energy in MWh', fontsize=fs)

plt.xticks(rotation=90)
# 收集所有子图的图例句柄和标签
handles = []
labels = []
for ax in axs:
    h, l = ax.get_legend_handles_labels()
    handles.extend(h)
    labels.extend(l)
fig.legend(handles, labels, fontsize=fs, loc='upper center', bbox_to_anchor=(0.5, 1.05), ncol=4)
# 调整布局,给顶部图例预留空间
fig.tight_layout(rect=[0, 0, 1, 0.96])

plt.show()

优化建议

  • 若仍卡顿可先关闭LaTeX渲染测试:将plt.rc('text', usetex=True)改为False,确认卡顿来源。
  • 若x轴时间标签过密,可添加抽稀逻辑:比如plt.xticks(ticks=range(len(temp_x))[::10], labels=temp_x[::10], rotation=90),每隔10个显示一个标签,大幅降低渲染压力。
  • 可根据实际图例高度调整bbox_to_anchor的y值,避免图例和子图重叠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:09:04