Python如何绘制含winner_rank_status及获胜方颜色占比的堆叠柱状图
实现方案
你当前的代码是对每个winner_rank_status分组单独做了占比归一化,导致所有柱子总高度均为100%,按照需求修改后的代码如下:
import pandas as pd import matplotlib.pyplot as plt # 1. 统计每个(winner_rank_status, winner)组合的样本数 Q3_count = games_df.groupby(['winner_rank_status', 'winner']).size().reset_index(name='count') # 2. 计算每个组合占总样本的比例,堆叠后总高度即为对应winner_rank_status的整体占比 total_sample = Q3_count['count'].sum() Q3_count['total_pct'] = round(100 * Q3_count['count'] / total_sample, 2) # 3. 计算每个获胜方在所属rank分组内的占比,用于柱子内部标注 Q3_count['inner_pct'] = Q3_count.groupby('winner_rank_status')['count'].apply(lambda x: round(100 * x / x.sum(), 2)) # 4. 转换为绘图需要的宽表格式 Q3_df = Q3_count.pivot(index='winner_rank_status', columns='winner', values='total_pct').fillna(0) # 绘制堆叠柱状图 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' ) # 按顺序生成内部标注内容 inner_labels = Q3_count.sort_values(['winner_rank_status', 'winner'])['inner_pct'].values label_index = 0 for container in ax.containers: labels = [f"{val}%" for val in inner_labels[label_index:label_index+len(container)]] ax.bar_label(container, labels=labels, label_type='center', color='b') label_index += len(container) # 可选:在柱子顶部添加当前rank分类的整体占比标注 total_pct_per_group = Q3_df.sum(axis=1).values ax.bar_label(ax.containers[-1], labels=[f"{round(val,2)}%" for val in total_pct_per_group], label_type='edge', color='r', fontweight='bold') plt.ylabel('占总样本比例') plt.show()
效果说明
- 每个柱子的总高度为对应
winner_rank_status分类占全部样本的真实占比 - 柱子内部蓝色标注为对应颜色获胜方在当前分类下的占比
- 可选添加的顶部红色标注为当前分类的整体占比,方便直观读取数值
内容的提问来源于stack exchange,提问作者Vahid
相关产品推荐
相关产品推荐

