python - 如何在水平 Seaborn 条形图上注释文本?

标签 python pandas seaborn

我的问题是,一旦我想注释我的水平条,就会出现一些错误消息:

posx and posy should be finite values

然后我查看了代码,令人惊讶的是,我得到了一些仅在使用 hue 参数时出现的 nan 值。

代码:

ax = sns.barplot(x="Points", y="Characters", hue="Average Speeds", data=albion_dataset, palette="Set1", dodge=False)
for p in ax.patches:
    width = p.get_width()
    print(width)

Output:
nan
nan
2.57562
nan
nan
nan
nan
1.526325
nan
...

但是当我删除 hue 选项时,没有 nan 并且注释工作完美无瑕。数据框本身没有 nan 值。如何解决这个问题,以便我可以使用色调功能。 dtypes 是 x 和 hue 的 floats 和 y 的 object

更新: 找到了注释条的方法,但现在最后一个条没有注释文本。

i = 0
for p in ax.patches:
    ax.annotate("%.4f" % albion_dataset["Average Speeds"][i], (p.get_x() + p.get_width(), p.get_y() + 1.2),
            xytext=(5, 10), textcoords='offset points')
    print(i)
    i += 1

此外,我如何将色调图例中的文本添加到条形图中,因为上面的代码没有考虑色调值的顺序。因此,我在条形图上得到了错误的值。

最佳答案

一种选择是依靠补丁本身的宽度,而不是尝试将条形与数据框匹配:

tips = sns.load_dataset("tips")
tips.loc[(tips.day=="Thur")&(tips.sex=='Female')] = np.nan
tips.loc[(tips.day=="Sat")&(tips.sex=='Male')] = np.nan
ax = sns.barplot(y="day", x="total_bill", hue="sex", data=tips, ci=None)

for p in ax.patches:
    ax.annotate("%.4f" % p.get_width(), xy=(p.get_width(), p.get_y()+p.get_height()/2),
            xytext=(5, 0), textcoords='offset points', ha="left", va="center")

enter image description here

如果您需要知道 hue 的值(或访问每个 bar 对应的子数据帧),那么我建议您显式传递 order=和一个 hue_order= 参数,因此您知道绘制条形的顺序。

import itertools
tips = sns.load_dataset("tips")
tips.loc[(tips.day=="Thur")&(tips.sex=='Female')] = np.nan
tips.loc[(tips.day=="Sat")&(tips.sex=='Male')] = np.nan

group_col = 'day'
hue_col = 'sex'
order=['Sat','Sun','Thur','Fri']
hue_order = ['Female','Male']

ax = sns.barplot(y=group_col, x="total_bill", hue=hue_col, order=order, hue_order=hue_order, data=tips, ci=None)

for p,(cur_hue, cur_y) in zip(ax.patches,itertools.product(hue_order,order)):
    temp_df = tips.loc[(tips[group_col]==cur_y)&(tips[hue_col]==cur_hue)]
    # temp_df is the sub-dataframe that corresponds to the current bar `p`. It can contain 0 or more rows
    pos = p.get_width() if p.get_width()>0 else 0
    ax.annotate(cur_hue, xy=(pos, p.get_y()+p.get_height()/2),
                xytext=(5, 0), textcoords='offset points', ha="left", va="center")

enter image description here

关于python - 如何在水平 Seaborn 条形图上注释文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59213470/

相关文章:

python - 如何在 Seaborn Jointplot 中为单个标记着色?

python - Jupiter Python seaborn 热图未显示所有相关性

python - 如何在 PyTorch 中构建具有两个输入的网络

python - 如何从 bash 脚本执行多行 python 代码?

python - 从 python 调用开发人员命令提示符

python - Python Pandas 中的 DataFrame 转换

python-3.x - 找出Python中数据框中特定行的特定列中有多少个值匹配

python - 根据条件合并相邻行

python - 如何传播默认值

python - 为seaborn lmplot添加文本注释