python - 图例中的误差条 - 熊猫条形图
问题描述
是否可以在图例中显示误差线?
(就像我用红色画的那样)
它们不一定必须是正确的长度,如果它们被指示和识别就足够了。
我的工作样本:
import pandas as pd
import matplotlib.pyplot as plt
test = pd.DataFrame(data={'one':2000,'two':300,'three':50,'four':150}, index=['MAX'])
fig, ax = plt.subplots(figsize=(5, 3), dpi=230)
ax.set_ylim(-.12,.03)
# barplot
ax = test.loc[['MAX'],['one']].plot(position=5.5,color=['xkcd:camo green'], xerr=test.loc[['MAX'],['two']].values.T, edgecolor='black',linewidth = 0.3, error_kw=dict(lw=1, capsize=2, capthick=1),ax=ax,kind='barh',width=.025)
ax = test.loc[['MAX'],['one']].plot(position=7,color=['xkcd:moss green'], xerr=test.loc[['MAX'],['three']].values.T, edgecolor='black',linewidth = 0.3, error_kw=dict(lw=1, capsize=2, capthick=1),ax=ax,kind='barh',width=.025)
ax = test.loc[['MAX'],['one']].plot(position=8.5,color=['xkcd:light olive green'],xerr=test.loc[['MAX'],['four']].values.T, edgecolor='black',linewidth = 0.3, error_kw=dict(lw=1, capsize=2, capthick=1),ax=ax,kind='barh',width=.025)
# Legende
h0, l0 = ax.get_legend_handles_labels()
l0 = [r'MAX $1$', r'MAX $2$', r'MAX $3$']
legend = plt.legend(h0, l0, borderpad=0.15,labelspacing=0.1, frameon=True, edgecolor="xkcd:black", ncol=1, loc='upper left',framealpha=1, facecolor='white')
legend.get_frame().set_linewidth(0.3)
cur_axes = plt.gca()
cur_axes.axes.get_yaxis().set_ticklabels([])
cur_axes.axes.get_yaxis().set_ticks([])
plt.show()
我尝试了几种方法,没有一个有效。使用 legend_elements 中的补丁,我没有得到错误栏的线条,使用 errorbar() 函数我可以绘制一个带有错误栏的图形,但它似乎在图例中不起作用:
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
from matplotlib.lines import Line2D
legend_elements = [
Line2D([1,2], [5,4], color='b', lw=1, label='Line'),
Patch(facecolor='orange', edgecolor='r', label='Color Patch'),
matplotlib.pyplot.errorbar(3, 3, yerr=None, xerr=1, marker='s',mfc='xkcd:camo green', mec='black',
ms=20, mew=2, fmt='-', ecolor="black", elinewidth=2, capsize=3,
barsabove=True, lolims=False, uplims=False, xlolims=False, xuplims=False,
errorevery=2, capthick=None, label="error"),
]
test = pd.DataFrame(data={'one':2000,'two':300,'three':50,'four':150}, index=['MAX'])
fig, ax = plt.subplots(figsize=(5, 3), dpi=230)
ax.set_ylim(-.12,.03)
# barplot
ax = test.loc[['MAX'],['one']].plot(position=5.5,color=['xkcd:camo green'], xerr=test.loc[['MAX'],['two']].values.T, edgecolor='black',linewidth = 0.3, error_kw=dict(lw=1, capsize=2, capthick=1),ax=ax,kind='barh',width=.025)
ax = test.loc[['MAX'],['one']].plot(position=7,color=['xkcd:moss green'], xerr=test.loc[['MAX'],['three']].values.T, edgecolor='black',linewidth = 0.3, error_kw=dict(lw=1, capsize=2, capthick=1),ax=ax,kind='barh',width=.025)
ax = test.loc[['MAX'],['one']].plot(position=8.5,color=['xkcd:light olive green'],xerr=test.loc[['MAX'],['four']].values.T, edgecolor='black',linewidth = 0.3, error_kw=dict(lw=1, capsize=2, capthick=1),ax=ax,kind='barh',width=.025)
# Legende
h0, l0 = ax.get_legend_handles_labels()
l0 = [r'MAX $1$', r'MAX $2$', r'MAX $3$']
legend = plt.legend(h0, l0, borderpad=0.15,labelspacing=0.1, frameon=True, edgecolor="xkcd:black", ncol=1, loc='upper left',framealpha=1, facecolor='white')
legend.get_frame().set_linewidth(0.3)
ax.legend(handles=legend_elements, loc='center')
cur_axes = plt.gca()
cur_axes.axes.get_yaxis().set_ticklabels([])
cur_axes.axes.get_yaxis().set_ticks([])
#plt.show()
基于r-beginners思想的实现:
import pandas as pd
import matplotlib.pyplot as plt
test = pd.DataFrame(data={'one':2000,'two':300,'three':50,'four':150}, index=['MAX'])
fig, ax = plt.subplots(figsize=(5, 3), dpi=150)
ax.set_ylim(0, 6)
ax.set_xlim(0, 2400)
ax1 = ax.twiny()
ax1.set_xlim(0, 2400)
ax1.set_xticks([])
ax.barh(1, width=test['one'], color=['xkcd:camo green'], edgecolor='black',linewidth = 0.3, label='MAX1')
ax.barh(2, width=test['one'], color=['xkcd:moss green'], edgecolor='black',linewidth = 0.3, label='MAX2')
ax.barh(3, width=test['one'], color=['xkcd:light olive green'], edgecolor='black',linewidth = 0.3, label='MAX3')
ax1.errorbar(test['one'], 1, xerr=test['two'], color='k', ecolor='k', fmt=',', lw=1, capsize=2, capthick=1, label='MAX1')
ax1.errorbar(test['one'], 2, xerr=test['three'], color='k', ecolor='k', fmt=',', lw=1, capsize=2, capthick=1, label='MAX2')
ax1.errorbar(test['one'], 3, xerr=test['four'], color='k', ecolor='k', fmt=',', lw=1, capsize=2, capthick=1, label='MAX3')
handler, label = ax.get_legend_handles_labels()
handler1, label1 = ax1.get_legend_handles_labels()
label1 = ['' for l in label1]
ax.legend(handler, label, loc='upper left', handletextpad=1.5)
ax1.legend(handler1, label1, loc='upper left', handletextpad=1., markerfirst=False, framealpha=0.001)
plt.show()
变化:
ax1
得到相同的限制ax
- 来自的所有字符串
label1
都被删除 - 按
ax1.legend()
处理程序和标签的顺序交换,并且handlertextpad
错误栏向右移动
解决方案
我想出的方法是绘制“ax.barh”和“ax1.errorbar()”,然后将每个的图例叠加在一起。一方面,我最小化了透明度,以便下面的图例可见;误差条看起来不同,因为我把它做成了双轴的。
import pandas as pd
import matplotlib.pyplot as plt
test = pd.DataFrame(data={'one':2000,'two':300,'three':50,'four':150}, index=['MAX'])
fig, ax = plt.subplots(figsize=(5, 3), dpi=230)
ax.set_ylim(0, 15)
ax.set_xlim(0, 2400)
ax1 = ax.twiny()
ax.barh(5.5, width=test['one'], color=['xkcd:camo green'], edgecolor='black',linewidth = 0.3, label='MAX1')
ax.barh(7.0, width=test['one'], color=['xkcd:moss green'], edgecolor='black',linewidth = 0.3, label='MAX2')
ax.barh(8.5, width=test['one'], color=['xkcd:light olive green'], edgecolor='black',linewidth = 0.3, label='MAX3')
ax1.errorbar(test['one'], 5.5, xerr=test['two'], color='k', ecolor='k', capsize=3, fmt='|', label='MAX1')
ax1.errorbar(test['one'], 7.0, xerr=test['three'], color='k', ecolor='k', capsize=3, fmt='|', label='MAX2')
ax1.errorbar(test['one'], 8.5, xerr=test['four'], color='k', ecolor='k', capsize=3, fmt='|', label='MAX3')
handler, label = ax.get_legend_handles_labels()
handler1, label1 = ax1.get_legend_handles_labels()
ax.legend(handler, label, loc='upper left', title='mix legend')
ax1.legend(handler1, label1, loc='upper left', title='mix legend', framealpha=0.001)
plt.show()
推荐阅读
- c++ - 在 C++ 中以凯撒密码显示空格
- php - 输入错误的用户名时返回“注意:尝试访问 null 类型值的数组偏移量”
- javascript - VS Code 设置 JavaScript 属性颜色
- java - Spring Hateoas 问题呈现 HAL 内容
- websphere - 如何使用累积函数作为目标函数的时间尺度?或者,任何替代解决方案?
- javascript - 用于过滤三个不同列表的 Javascript 函数
- python - 在 Python 中的列表元组中查找负值
- sql-server - 如何在使用 SSIS 加载数据时生成 ID 以保持多级 XML 的关系完整性?
- powerbi - 如何通过数据流设置更改 Power BI 中的数据流参数?
- r - 如何在 r 中按串联组过滤