Python中的分组、百分比和条形图

Posted

技术标签:

【中文标题】Python中的分组、百分比和条形图【英文标题】:grouping, percentage, and barchart in Python 【发布时间】:2021-10-21 23:03:56 【问题描述】:

我对 Python 很陌生,我正在尝试绘制一个显示winner_rank_status 百分比的条形图,并且在每个条形中,我想显示获胜者的百分比(颜色)。

我的数据集是这样的:

我写的代码:

Q3_df=games_df[['winner','winner_rank_status']]
Q3_df=Q3_df.groupby(['winner_rank_status','winner']).size().groupby(level=0).apply(lambda x: round(100*x/x.sum(),2))
Q3_df=Q3_df.unstack()
ax= Q3_df.plot(
    kind='bar',
    stacked=True,
    figsize=(14,7),
    rot=0,
    title='Effect of piece colour and winner rating status on the result',
    color=['black','grey','white'],
    edgecolor='black',
    
)
for c in ax.containers:
    ax.bar_label(c, label_type='center',color='b')

这是我得到的结果:

这个结果是错误的,因为它显示了所有类别的 100%!!!我需要显示每个类别(相等、更高、更低)的真实百分比,然后在每个类别中显示每种颜色的比例......

请您指导我如何实现它?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

您可以为每组条形图的标签赋予不同的颜色。要获得所有 9 个值总和为 100 的百分比,您可以除以游戏总数:

from matplotlib import pyplot as plt
import pandas as pd
import numpy as np

winner_options = ['black', 'draw', 'white']
rank_options = ['lower', 'equal', 'higher']
Q3_df = pd.DataFrame('winner_rank_status': pd.Categorical(np.random.choice(rank_options, 1000, p=[.46, .07, .47]), rank_options),
                      'winner': pd.Categorical(np.random.choice(winner_options, 1000, p=[.51, .03, .46]), winner_options))
Q3_rank_winner_df = Q3_df.groupby(['winner_rank_status', 'winner']).size().groupby(level=0).apply(
    lambda x: np.round(100 * x / len(Q3_df), 2))
Q3_rank_winner_df = Q3_rank_winner_df.unstack()
ax = Q3_rank_winner_df.plot(
    kind='bar',
    stacked=True,
    figsize=(14, 7),
    rot=0,
    title='Effect of piece colour and winner rating status on the result',
    color=['black', 'grey', 'white'],
    edgecolor='black')
for bars, color in zip(ax.containers, ['skyblue', 'navy', 'darkblue']):
    ax.bar_label(bars, label_type='center', color=color)
ax.legend(bbox_to_anchor=[1.01, 1.02], loc='upper left')
plt.tight_layout()
plt.show()

新要求有点混乱。可以在条形顶部添加每个等级的百分比:


from matplotlib import pyplot as plt
import pandas as pd
import numpy as np

winner_options = ['black', 'draw', 'white']
rank_options = ['lower', 'equal', 'higher']
Q3_df = pd.DataFrame(
    'winner_rank_status': pd.Categorical(np.random.choice(rank_options, 1000, p=[.65, .05, .30]), rank_options),
     'winner': pd.Categorical(np.random.choice(winner_options, 1000, p=[.46, .07, .47]), winner_options))
Q3_rank_winner_df = Q3_df.groupby(['winner_rank_status', 'winner']).size().groupby(level=0).apply(
    lambda x: np.round(100 * x / x.sum(), 2))
Q3_rank_winner_df = Q3_rank_winner_df.unstack()
ax = Q3_rank_winner_df.plot(
    kind='bar',
    stacked=True,
    figsize=(14, 7),
    rot=0,
    title='Effect of piece colour and winner rating status on the result',
    color=['black', 'grey', 'white'],
    edgecolor='black')
for bars, color in zip(ax.containers, ['skyblue', 'navy', 'darkblue']):
    ax.bar_label(bars, label_type='center', color=color)

Q3_rank_df = Q3_df.groupby(['winner_rank_status']).size() * 100 / len(Q3_df)
for row, percent in enumerate(Q3_rank_df):
    ax.text(row, 103, f'percent:.02f %', color='navy', ha='center', va='center')
ax.margins(y=0.08)  # more space on top

ax.legend(bbox_to_anchor=[1.01, 1.02], loc='upper left')
plt.tight_layout()
plt.show()

【讨论】:

对不起,JohnC,我刚刚注意到它仍然不是答案。如果您查看里面的数字,每个条形加起来并不是 100%。外部更高的类别是正确的;总和是 100%,但不是每个条形图。你能指导我吗? 在原始答案中(请参阅edit history),例如 3 条'lower' 的总和为 100。你还要那个吗?还是别的什么? 每个答案都部分正确,正确答案是:-所有主要类别的总和将为100。这意味着Lower+Equal+Higher=100。 - 现在每个条在黑色、白色和平局上都有自己的百分比。但是,每个栏内的总和应该是 100。例如:在下栏中“黑色+白色+draw=100”你的第一个答案,第二部分是正确的,你的第二个答案只涵盖第一部分。我需要涵盖两个部分!谢谢

以上是关于Python中的分组、百分比和条形图的主要内容,如果未能解决你的问题,请参考以下文章

R语言ggplot2可视化:使用dplyr包计算每个分组个数的比例使用ggplot2可视化条形图(bar plot)并在条形图上添加百分比标签

R语言ggplot2可视化:使用dplyr包计算每个分组个数的比例(对计算获得的百分比进行近似,值保留整数部分)使用ggplot2可视化条形图(bar plot)并在条形图上添加百分比标签

制作条形图时无法解释输入“百分比”[重复]

修改顶部ggplot百分比条形图上的文本标签

python中堆积百分比条形图的问题[重复]

使百分比参与分组但由另一个变量着色