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

Seaborn水平条形图使用全月名时y轴标签重叠如何解决

问题修复方案

问题根源

重叠问题由三个原因共同导致:

  • 英文月份作为普通字符串传入时,value_counts()默认按计数降序返回统计结果,而seaborn barplot默认按字符串字典序排列y轴分类,二者排序规则不一致,直接导致条形、y轴标签、数值标注三者错位。Nov、Dec在字典序中位置相邻,错位表现为重叠。
  • 原代码没有适配pandas不同版本的返回列名逻辑,2.0+版本pandas中value_counts().reset_index()会把计数列命名为count而非原列名,会直接导致坐标轴映射错误。
  • 数值标注直接定位在条形右端点,没有预留偏移空间;完整英文月份名长度远大于数字,默认画布边距不足会挤压绘图区域,进一步加重重叠。

修复代码

修复点包括:固定分类排序规则、兼容pandas版本差异、给数值标注加自适应偏移、自动调整画布边距。如果是月份列,调用时把is_month参数设为True即可自动适配数字/英文月份的自然顺序,不会乱序。

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

def bar_plot(dataset, col, figsize=(16,8), is_month=False):
    fig, ax = plt.subplots(figsize=figsize)
    # 设置边框样式
    for loc in ['bottom', 'left']:
        ax.spines[loc].set_visible(True)
        ax.spines[loc].set_linewidth(2)
        ax.spines[loc].set_color('black')
    # 隐藏多余边框
    for loc in ['top', 'right']:
        ax.spines[loc].set_visible(False)
    
    # 月份列固定排序规则,避免自动排序错位
    if is_month:
        if pd.api.types.is_numeric_dtype(dataset[col]):
            cat_order = list(range(1, 13))
        else:
            cat_order = ['January', 'February', 'March', 'April', 'May', 'June',
                         'July', 'August', 'September', 'October', 'November', 'December']
        dataset[col] = pd.Categorical(dataset[col], categories=cat_order, ordered=True)
        # 统计时保留分类原有顺序,不按计数排序
        data = dataset[col].value_counts(sort=False).reset_index(name='count')
    else:
        data = dataset[col].value_counts().reset_index(name='count')

    # 绘图时明确指定坐标轴映射,兼容所有pandas版本
    sns.barplot(
        data=data,
        x='count',
        y=col,
        orient='h',
        linewidth=1,
        edgecolor='k',
        color='#005EB8',
        ax=ax
    )
            
    ax.set_title(f'Change counts by: {col.capitalize()}', size=16, fontweight='bold', color='#425563')
    ax.set_ylabel('')
    
    # 数值标注加自适应偏移,避免贴边重叠
    max_val = data['count'].max()
    for p in ax.patches:
        width = p.get_width()
        ax.text(
            width + max_val * 0.01,  # 按最大值1%加偏移,适配不同数据量级
            p.get_y() + 0.55 * p.get_height(),
            round(width),
            va='center',
            color='#425563'
        )
    
    # 自动调整边距,适配长文本标签
    plt.tight_layout()
    plt.show()

调用示例

# 传入英文月份列
bar_plot(df, 'month_name', is_month=True)
# 传入数字月份列
bar_plot(df, 'month_num', is_month=True)
# 传入其他普通分类列
bar_plot(df, 'category')

内容的提问来源于stack exchange,提问作者1cjtc jj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:33:22