I a*_*rge 25 python matplotlib seaborn
鉴于以下计数图,我如何将百分比放在栏杆上?
import seaborn as sns
sns.set(style="darkgrid")
titanic = sns.load_dataset("titanic")
ax = sns.countplot(x="class", hue="who", data=titanic)
Run Code Online (Sandbox Code Playgroud)
例如,对于"第一",我想要总的第一人/总第一,总第一女人/总第一,总第一个孩子/总第一个在他们各自的酒吧之上.
如果我的解释不清楚,请告诉我.
谢谢!
cph*_*wis 48
sns.barplot没有明确地返回条形图值的方式matplotlib.pyplot.bar(参见最后一段),但如果你没有绘制任何其他内容,你可以冒险假设patches轴中的所有值都是你的值.然后,您可以使用barplot函数为您计算的小计:
from matplotlib.pyplot import show
import seaborn as sns
sns.set(style="darkgrid")
titanic = sns.load_dataset("titanic")
total = float(len(titanic)) # one person per row
#ax = sns.barplot(x="class", hue="who", data=titanic)
ax = sns.countplot(x="class", hue="who", data=titanic) # for Seaborn version 0.7 and more
for p in ax.patches:
height = p.get_height()
ax.text(p.get_x()+p.get_width()/2.,
height + 3,
'{:1.2f}'.format(height/total),
ha="center")
show()
Run Code Online (Sandbox Code Playgroud)
产生
另一种方法是明确地进行子求和,例如,使用优秀的pandas,与情节一起绘制matplotlib,并且自己也做样式.(尽管sns即使使用matplotlib绘图功能,您也可以从上下文中获得相当多的样式.尝试一下 - )
小智 9
如果您的图中有“色调”参数,with_hue函数将在条形图上绘制百分比。它以实际图形、特征、特征中的 Number_of_categories 和hue_categories(色调特征中的类别数)作为参数。
如果您有正常绘图,without_hue函数将在条形图上绘制百分比。它以实际图形和特征为参数。
def with_hue(plot, feature, Number_of_categories, hue_categories):
a = [p.get_height() for p in plot.patches]
patch = [p for p in plot.patches]
for i in range(Number_of_categories):
total = feature.value_counts().values[i]
for j in range(hue_categories):
percentage = '{:.1f}%'.format(100 * a[(j*Number_of_categories + i)]/total)
x = patch[(j*Number_of_categories + i)].get_x() + patch[(j*Number_of_categories + i)].get_width() / 2 - 0.15
y = patch[(j*Number_of_categories + i)].get_y() + patch[(j*Number_of_categories + i)].get_height()
ax.annotate(percentage, (x, y), size = 12)
plt.show()
def without_hue(plot, feature):
total = len(feature)
for p in plot.patches:
percentage = '{:.1f}%'.format(100 * p.get_height()/total)
x = p.get_x() + p.get_width() / 2 - 0.05
y = p.get_y() + p.get_height()
ax.annotate(percentage, (x, y), size = 12)
plt.show()
Run Code Online (Sandbox Code Playgroud)
答案是受到 jrjc 和 cphlewis 答案的启发,如上所述,但更简单易懂
sns.set(style="whitegrid")
plt.figure(figsize=(8,5))
total = float(len(train_df))
ax = sns.countplot(x="event", hue="event", data=train_df)
plt.title('Data provided for each event', fontsize=20)
for p in ax.patches:
percentage = '{:.1f}%'.format(100 * p.get_height()/total)
x = p.get_x() + p.get_width()
y = p.get_height()
ax.annotate(percentage, (x, y),ha='center')
plt.show()
Run Code Online (Sandbox Code Playgroud)
matplotlib 3.4.2是使用matplotlib.pyplot.bar_label..bar_label。labels使用赋值表达式 ( :=),这需要python >= 3.8. 这可以重写为标准的 for 循环。
labels = [f'{v.get_height()/data.who.count()*100:0.1f}' for v in c]无需赋值表达式即可工作。v.get_width().python 3.10, pandas 1.4.2, matplotlib 3.5.1,seaborn 0.11.2import matplotlib.pyplot as plt
import seaborn as sns
# load the data
data = sns.load_dataset('titanic')[['survived', 'class', 'who']]
survived class who
0 0 Third man
1 1 First woman
2 1 Third woman
Run Code Online (Sandbox Code Playgroud)
seaborn.countplot与或 一起使用seaborn.barplot# plot
ax = sns.countplot(x="class", hue="who", data=data)
ax.set(ylabel='Bar Count', title='Bar Count and Percent of Total')
# add annotations
for c in ax.containers:
# custom label calculates percent and add an empty string so 0 value bars don't have a number
labels = [f'{h/data.who.count()*100:0.1f}%' if (h := v.get_height()) > 0 else '' for v in c]
ax.bar_label(c, labels=labels, label_type='edge')
plt.show()
Run Code Online (Sandbox Code Playgroud)
fg = sns.catplot(data=data, kind='count', x='class', hue='who', col='survived')
fg.fig.subplots_adjust(top=0.9)
fg.fig.suptitle('Bar Count and Percent of Total')
for ax in fg.axes.ravel():
# add annotations
for c in ax.containers:
# custom label calculates percent and add an empty string so 0 value bars don't have a number
labels = [f'{h/data.who.count()*100:0.1f}%' if (h := v.get_height()) > 0 else '' for v in c]
ax.bar_label(c, labels=labels, label_type='edge')
plt.show()
Run Code Online (Sandbox Code Playgroud)
在cphlewis 的解决方案的帮助下,我设法将正确的百分比放在图表的顶部,因此这些类的总和为 1。
for index, category in enumerate(categorical):
plt.subplot(plot_count, 1, index + 1)
order = sorted(data[category].unique())
ax = sns.countplot(category, data=data, hue="churn", order=order)
ax.set_ylabel('')
bars = ax.patches
half = int(len(bars)/2)
left_bars = bars[:half]
right_bars = bars[half:]
for left, right in zip(left_bars, right_bars):
height_l = left.get_height()
height_r = right.get_height()
total = height_l + height_r
ax.text(left.get_x() + left.get_width()/2., height_l + 40, '{0:.0%}'.format(height_l/total), ha="center")
ax.text(right.get_x() + right.get_width()/2., height_r + 40, '{0:.0%}'.format(height_r/total), ha="center")
Run Code Online (Sandbox Code Playgroud)
但是,该解决方案假设有 2 个选项(男人、女人)而不是 3 个(男人、女人、孩子)。
由于Axes.patches以奇怪的方式排序(首先是所有蓝色条,然后是所有绿色条,然后是所有红色条),因此您必须将它们分开并相应地将它们拉回一起。
| 归档时间: |
|
| 查看次数: |
26778 次 |
| 最近记录: |