You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现基于label列、带计数/百分比标注的任意列堆叠柱状图

堆叠柱状图(带计数与百分比)实现方案

原始数据

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib 
print('matplotlib: {}'.format(matplotlib.__version__))
# 输出:3.5.3

df=pd.DataFrame({'Type': [ 'Sentence', 'Array', 'String', '-','-', 'Sentence', 'Array', 'String', '-','-', 'Sentence'],
                 'Length': [42,21,11,6,6,42,21,11,6,6,42],
                 'label': [1,1,0,0,0,1,1,0,0,0,1],
                 })
print(df)
# 输出结果:
#        Type  Length  label
# 0   Sentence      42      1
# 1      Array      21      1
# 2     String      11      0
# 3          -       6      0
# 4          -       6      0
# 5   Sentence      42      1
# 6      Array      21      1
# 7     String      11      0
# 8          -       6      0
# 9          -       6      0
# 10  Sentence      42      1

需求说明

针对DataFrame中的任意列(数值列如Length或分类列如Type),以label列为堆叠依据绘制堆叠柱状图,同时标注计数和百分比,且稀有观测的小数值也需正常显示。

现有问题分析

直接使用df.plot.bar(stacked=True)无法正确统计分组计数;使用groupby+pivot_table时出现TypeError: unsupported operand type(s) for +: 'int' and 'str'错误,核心原因是未正确统计目标列与label的分组频次,且百分比计算逻辑有误。


解决方案一:Matplotlib + Seaborn 实现(通用函数)

编写通用函数,传入目标列名即可生成符合要求的图表:

import seaborn as sns
import matplotlib.pyplot as plt

def plot_stacked_bar(df, target_col):
    # 1. 统计目标列与label的分组计数
    count_df = df.groupby([target_col, 'label']).size().unstack(fill_value=0)
    # 2. 计算每行的占比百分比
    percent_df = count_df.div(count_df.sum(axis=1), axis=0) * 100
    
    # 3. 绘制堆叠柱状图
    ax = count_df.plot(kind='bar', stacked=True, figsize=(10,6), rot=0)
    
    # 4. 添加计数+百分比标注
    for container in ax.containers:
        counts = [v.get_height() for v in container]
        percents = [percent_df.iloc[i, int(container.get_label())] for i, v in enumerate(container)]
        
        ax.bar_label(container, labels=[f'{cnt}\n({pct:.1f}%)' if cnt > 0 else '' 
                                       for cnt, pct in zip(counts, percents)],
                    label_type='center', fontsize=9)
    
    # 5. 调整图例与标题
    ax.legend(title='标签', labels=['0: 正常', '1: 异常'], bbox_to_anchor=(1, 1.02), loc='upper left')
    ax.set_title(f'按{target_col}分组的堆叠柱状图(带计数与百分比)', fontsize=12)
    ax.set_xlabel(target_col, fontsize=10)
    ax.set_ylabel('计数', fontsize=10)
    plt.tight_layout()
    plt.show()

调用示例

针对分类列Type

plot_stacked_bar(df, 'Type')

生成的图表与预期输出一致,每个堆叠块清晰标注计数和对应百分比(如Sentence的label=1计数为3,占比100%)。

针对数值列Length

plot_stacked_bar(df, 'Length')

按Length的不同取值分组,展示每个长度对应的label分布情况。


解决方案二:Plotly 实现(交互式图表)

如果需要交互式体验,Plotly可生成支持hover查看详情的堆叠柱状图:

import plotly.express as px
import plotly.graph_objects as go

def plot_stacked_bar_plotly(df, target_col):
    # 统计分组计数与总数
    count_df = df.groupby([target_col, 'label']).size().reset_index(name='count')
    total_counts = df.groupby(target_col).size().reset_index(name='total')
    count_df = count_df.merge(total_counts, on=target_col)
    count_df['percent'] = (count_df['count'] / count_df['total']) * 100
    
    # 创建堆叠柱状图
    fig = px.bar(count_df, x=target_col, y='count', color='label',
                 color_discrete_map={0: '#1f77b4', 1: '#ff7f0e'},
                 labels={'label': '标签', 'count': '计数', target_col: target_col},
                 title=f'按{target_col}分组的堆叠柱状图')
    
    # 添加文本标注
    for idx, row in count_df.iterrows():
        # 计算标注的y轴位置(堆叠块的中心)
        prev_sum = count_df[(count_df[target_col]==row[target_col]) & (count_df['label'] < row['label'])]['count'].sum()
        fig.add_annotation(
            x=row[target_col],
            y=prev_sum + row['count']/2,
            text=f'{row["count"]}\n({row["percent"]:.1f}%)',
            showarrow=False,
            font_size=10
        )
    
    # 调整图例布局
    fig.update_layout(
        legend=dict(title='标签', items=[
            dict(label='0: 正常', color='#1f77b4'),
            dict(label='1: 异常', color='#ff7f0e')
        ], bbox_to_anchor=(1, 1), yanchor='top'),
        title_x=0.5
    )
    
    fig.show()

调用示例

plot_stacked_bar_plotly(df, 'Type')

生成的交互式图表支持hover查看详细数据,标注清晰直观。


内容的提问来源于stack exchange,提问作者Mario

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:24:31