【问题标题】:how to add a common legend for subplots of bar charts with ax.legend()如何使用 ax.legend() 为条形图的子图添加公共图例
【发布时间】:2021-11-15 18:47:52
【问题描述】:

不幸的是,我已经尝试过我发现的不同的东西。如何在图的顶部为我的三个子图创建一个共同的图例?下面的代码不起作用,执行被卡住了,下面你还会发现整个代码sn-p。其实我以为我自己能搞定,但我确实需要你的帮助。

fig.tight_layout()
handles, labels = axs[0].get_legend_handles_labels()
fig.legend(handles, labels, fontsize=fs, loc='upper center', bbox_to_anchor=(0.5, 1.05), ncol=4)

这是我的整个代码 sn-p:


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

# Figure Properties
fs = 4  # 30
lw = 2  # 3
width_bars=0.5
ec = 'dimgray'

# Create Subplots
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)

#adjust Time Stamp to desired format

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].grid(True, linestyle=':')
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 = axs.get_legend_handles_labels() #does not work?
fig.legend(handles, labels, fontsize=fs, loc='upper center', bbox_to_anchor=(0.5, 1.05), ncol=4)

plt.show()

【问题讨论】:

  • 能否请您发布您的完整代码以及您的错误消息?我想我知道哪里出了问题(您正在访问所有轴,而不仅仅是一个轴),但是这里有一半的变量没有定义,我想在回答您的问题之前确定一下。
  • 谢谢!请欣赏它。我已经发布了。你能帮帮我吗?
  • 请提供足够的代码,以便其他人更好地理解或重现问题。

标签: python matplotlib plot legend figure


【解决方案1】:

总体思路有效(我相信this postthis one 是您的来源或适用于一个轴)。这里的问题是你有几个轴包裹在axs(这是一个numpy数组)中,所以当你做你写的事情时,你会得到类似的东西

AttributeError: 'numpy.ndarray' object has no attribute 'get_legend_handles_labels'

解决这个问题的方法是遍历所有轴并连接图例(它们的标签和句柄),例如。通过以下方式:

...
handles,labels=[],[]
for ax in axs.flatten():
    h, l = ax.get_legend_handles_labels()
    handles+=h
    labels+=l

fig.legend(handles, labels, fontsize=fs, loc='upper center', bbox_to_anchor=(0.5, 1.05), ncol=4)

【讨论】:

  • "感谢您的帮助!如果我采纳您的建议,我将收到以下错误消息:TimeoutError: Lock error: Matplotlib failed to acquire the following lock file: [C:\Users. ..] 这可能是由于另一个进程持有此锁定文件。如果您确定没有其他 Matplotlib 进程正在运行,请删除此文件并重试。"如果我不使用图例(分别是您的建议),则不会显示此错误消息并且代码运行成功。
  • 我相信这是另一个问题的另一个问题。我没有得到类似的东西,而且我以前从未见过此错误消息。我建议清理你的环境,也许检查其他帖子,如 stackoverflow.com/questions/50141983/…stackoverflow.com/questions/58647755/…,或检查你的 tex
  • 感谢您的帮助!它对我有用!
  • 不客气。如果问题已解决,则将答案标记为已接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
  • 2021-01-11
  • 2020-11-05
  • 2015-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多