首页 > 解决方案 > 如何在 Seaborn barplot Python 中将数据标签注释添加到基于名称的单个条

问题描述

我有以下数据框产生以下情节:

# Import pandas library 
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# initialize list of lists 
data = [['tom', 10,1,'a'], ['matt', 15,5,'b'],['nick', 18,2,'b'],['luke', 12,6,'b'],['geoff', 20,10,'a']]

# Create the pandas DataFrame 
df = pd.DataFrame(data, columns = ['Name', 'Attempts','Score','Category']) 
df

# Create plot
f, ax = plt.subplots(figsize=(8.27,11.7,))
df = df.sort_values(['Attempts'],ascending=False)
sns.set_color_codes("muted")
sns.barplot(x="Attempts", y="Name", data=df,
            label="Total", palette=["b" if x!='nick' else 'r' for x in df.Name], ax=ax)

# Annotate every single bar with its value
for p in ax.patches:
    width = p.get_width()
    ax.text(width - 1,
            p.get_y() + p.get_height() / 1 + 0.1,
            '{:1.2f}'.format(width),ha="center")

希伯恩情节

我只想包含数据标签注释'Nick'(即在这种情况下,条本身的值 18)是突出显示的条,并且在其余条上没有标签注释。是否有捷径可寻?非常感谢 !

标签: pythonpandasmatplotlibseaborn

解决方案


欢迎来到 StackOverflow。这是我的解决方案:

首先我重置您的 df 的索引,然后找到符合条件的行的索引号(在这种情况下nick):

# Create plot
f, ax = plt.subplots(figsize=(8.27,11.7,))
df = df.sort_values(['Attempts'],ascending=False)
#Reset index values
df = df.reset_index(drop=True)
#Return the index number of name required
indexno = df[df['Name'] == 'nick'].index
#Create array
a = np.array(indexno)
a= a[0]
print(a)

这给了我:

1

(您的第二行df

然后我找到了所有的get_width值:

#Plot
sns.set_color_codes("muted")
sns.barplot(x="Attempts", y="Name", data=df,
            label="Total", palette=["b" if x!='nick' else 'r' for x in df.Name], ax=ax)

# Final all width values in plot
values = []
for i in ax.patches:
    values.append(i.get_width())
    
print(values)

返回:

[20.0, 18.0, 15.0, 12.0, 10.0]

现在最后一个循环仅显示条件匹配的值(因此值 (18) 中的第二个值)。

#Final loop to annotate only the row where width equals the value of `nick`
for p in ax.patches:
    width = p.get_width()
    x = values[a]
    if width==x:        
        ax.text(width - 1,
                p.get_y() + p.get_height() / 1 + 0.1,
                '{:1.2f}'.format(width),ha="center")
plt.show()

在此处输入图像描述

完整代码:

 # Import pandas library 
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# initialize list of lists 
data = [['tom', 10,1,'a'], ['matt', 15,5,'b'],['nick', 18,2,'b'],['luke', 12,6,'b'],['geoff', 20,10,'a']]

# Create the pandas DataFrame 
df = pd.DataFrame(data, columns = ['Name', 'Attempts','Score','Category']) 
df

# Create plot
f, ax = plt.subplots(figsize=(8.27,11.7,))
df = df.sort_values(['Attempts'],ascending=False)
#Reset index values
df = df.reset_index(drop=True)
#Return the index number of name required
indexno = df[df['Name'] == 'nick'].index
#Create array
a = np.array(indexno)
a = a[0]
print((a))

#Plot
sns.set_color_codes("muted")
sns.barplot(x="Attempts", y="Name", data=df,
            label="Total", palette=["b" if x!='nick' else 'r' for x in df.Name], ax=ax)

# Final all width values in plot
values = []
for i in ax.patches:
    values.append(i.get_width())
    
print(values[a])

#Final loop to annotate only the
for p in ax.patches:
    width = p.get_width()
    x = values[a]
    if width==x:        
        ax.text(width - 1,
                p.get_y() + p.get_height() / 1 + 0.1,
                '{:1.2f}'.format(width),ha="center")
plt.show()

推荐阅读