python - 如何使用不同列中的值和文本注释分组条

标签 python pandas matplotlib seaborn grouped-bar-chart

我正在尝试在seaborn中获取具有垂直文本对齐的条形图。名称文本垂直对齐,但每个条之间保持一定的间隙。我需要垂直对齐栏顶部的名称文本以及栏内的 col3 值。请帮我解决这个问题。

enter image description here

我尝试过的代码是,

df= pd.DataFrame({'name':['Name1','Name2','Nmae3','Name4','Name2','Name1'],'Col1':[1,1,1,2,2,2],'col2':['a','b','c','a','b','c'],'col3':[22,33,4,11,3,43]})

    name  Col1 col2  col3
0  Name1     1    a    22
1  Name2     1    b    33
2  Nmae3     1    c     4
3  Name4     2    a    11
4  Name2     2    b     3
5  Name1     2    c    43

tm = sns.barplot(x="Col1", y="col3", hue="col2", data=df)

for index in range(len(df)):
    tm.text(index,df.col3.values[index]+0.2, str(df.name.values[index]),fontdict=dict(color='black', rotation=90,fontsize=10),horizontalalignment='left')

最佳答案

  • 主要问题是从数据帧中获取正确的'name'值。
  • 使用matplotlib.pyplot.bar_label和自定义标签,如下所述:
  • 使用具有色调值 ('col2') 和条形高度的列来获取条形顶部的正确 'name' 注释。
    • df.loc[(df.col2.eq(col) & df.col3.eq(h)), '名称'].iloc[0]
    • 如果多个组中存在相同的值,则这两列都用于获取正确的“名称”
  • 分组条形图按色调组的顺序绘制,因此先是 'a' 条形图,然后是 'b' 条形图,依此类推
  • python 3.10pandas 1.4.3matplotlib 3.5.1seaborn 0.11.2<中测试
    • 赋值表达式 (:=) - python >= 3.8
    • .bar_label - matplotlib >= 3.4.0
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(9, 7))
sns.barplot(x='Col1', y='col3', hue='col2', data=df, ax=ax)

# get the unique values for hue
hue_col = df.col2.unique()

# iterate through each group of containers - in order by hue groups
for c, col in zip(ax.containers, hue_col):
    
    # use the column and bar height to get the correct value for name
    labels = [f"{df.loc[(df.col2.eq(col) & df.col3.eq(h)), 'name'].iloc[0]}" if (h := v.get_height()) > 0 else '' for v in c ]
    # labels without using assignment expression
    # labels = [f"{df.loc[(df.col2.eq(col) & df.col3.eq(v.get_height())), 'name'].iloc[0]}" if v.get_height() > 0 else '' for v in c ] 
 
    # add the name annotation to the top of the bar
    ax.bar_label(c, labels=labels, padding=3)  # rotation=90 if needed
    
    # add the bar value annotation inside the bar
    ax.bar_label(c, label_type='center')

    # pad the spacing between the number and the edge of the figure
    ax.margins(y=0.1)

enter image description here

关于python - 如何使用不同列中的值和文本注释分组条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73491317/

相关文章:

python - 在现有数据帧上添加多级索引

python - 为什么 np.where 比 pd.apply 快

c++ - 使用自定义模块构建 python 解释器时出现问题

python - 更改绘图的标记方向和图例位置

python - DataFrame GroupBy 多级选择

python - 使用 Python 求解非线性微分一阶方程

python - 如何将文件读取为多个多边形的嵌套坐标列表?

python - 如何在x轴线图上显示年份?

python - 优雅地为 Pandas 中的群体重新采样

python - scikit 学习虚拟变量的创建