在 seaborn barplots 中灵活放置标签

Flexible placement of labels in seaborn barplots

我想根据 space 可用的数量在 Seaborn 中的条形图上放置标签。

例如,在下面的示例中,如果它们适合图形,我想使用 outside labels,当它们不适合时,我想使用 inside labels 't。我想为许多地块自动执行此操作,因此我正在寻找一种灵活地执行此操作的智能方法。有什么想法吗?

import seaborn as sns
import matplotlib.pyplot as plt
titanic=sns.load_dataset('titanic')
titanic.head()

fig, ax = plt.subplots()
sns.countplot(
    y='sex',
    data=titanic,
    orient="h",
    ax=ax
)
for p in ax.patches:
    perc = "{:.1f}%".format(100 * p.get_width() / titanic.shape[0])
    x = p.get_width()
    y = p.get_y() + p.get_height() / 2
    # inside labels
    ax.annotate(perc, (x*0.8, y), color="white")
    # outside labels
    ax.annotate(perc, (x*1.1, y), color="black")

我想要实现的质量差的例子:

这有帮助吗?

fig, ax = plt.subplots()
sns.countplot(
    y='sex',
    data=titanic,
    orient="h",
    ax=ax
    )

values = []
for p in ax.patches:
    
    x = p.get_width() # counts; dimension of the bar
    y = p.get_y() + p.get_height() / 2
    values.append(x) #collect the bar sizes in a list
    x_max = max(values)   #determine the largest bar size
    
#adjust percentage of the maximum bar size where inside/outside annotation occurs
cut_off = 0.8*x_max

for p in ax.patches:
    perc = "{:.1f}%".format(100 * p.get_width() / titanic.shape[0]) #the label for the bar
    x = p.get_width()
    y = p.get_y() + p.get_height() / 2
    
    if x >= cut_off:
        ax.annotate(perc, (x*0.8, y), color="white") 
    else: 
        ax.annotate(perc, (x*1.1, y), color="black")