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

使用sns.countplot()绘制MNIST数据时如何添加柱状图数值标注?

搞定Seaborn Countplot标注不显示、绘图顺序及副Y轴命名问题

一、先解决柱子数值标注不显示的坑

你这代码逻辑其实没问题,为啥标注不出来?大概率是坐标定位的小细节没调对,还有可能是没在最后调用plt.show()渲染图像。我给你改了下代码,保证标注能正常显示:

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# 假设Y_train是你的MNIST训练集标签
plt.figure(figsize=(12,5))
# 建议显式指定x参数,避免不同Seaborn版本的兼容问题
digit_count = sns.countplot(x=Y_train)  
plt.title('Distribution of digits')

# 遍历每个柱子加标注
for d in digit_count.patches:
    # 把标注放在柱子正上方,计算水平居中位置
    x_pos = d.get_x() + d.get_width() / 2  
    y_pos = d.get_height()
    # 添加标注,设置对齐方式让位置更美观
    digit_count.annotate(f'{int(y_pos)}',  # MNIST样本数是整数,直接显示更清楚
                        (x_pos, y_pos),
                        ha='center',  # 水平居中
                        va='bottom',  # 标注紧贴柱子顶部
                        fontsize=10)

plt.show()  # 必须加这个,不然图像和标注都不会渲染出来!

关键调整点:

  • 显式传x=Y_train:有些Seaborn版本对隐式传参支持不好,显式指定更稳。
  • 水平居中计算:原来的d.get_x()+0.1是固定偏移,换成d.get_x()+d.get_width()/2能自动适配柱子宽度,保证标注在正上方。
  • 对齐参数:ha='center'和va='bottom'让标注位置更规整,不会歪歪扭扭。
  • 格式调整:用int(y_pos)直接显示整数,比百分比更贴合MNIST的样本数量场景。

二、绘图先于print输出?调整顺序就行

为啥绘图总比print先出来?因为Matplotlib的绘图渲染是异步的,而print是同步执行的。你只要把print语句放到plt.show()之前就行,或者在Jupyter环境里,确保print代码在绘图代码之后、plt.show()之前执行。比如:

# 先统计数量并打印
counts = np.bincount(Y_train)
for digit, cnt in enumerate(counts):
    print(f"数字{digit}的样本数:{cnt}")

# 再绘图
plt.figure(figsize=(12,5))
digit_count = sns.countplot(x=Y_train)
plt.title('Distribution of digits')
# ... 加标注的代码 ...
plt.show()

要是用Jupyter Notebook,记得开头加%matplotlib inline,能保证图像和打印内容按顺序显示。


三、副Y轴怎么命名?一行代码的事

你用twinx()创建副Y轴后,直接调用set_ylabel()就能给它加名称啦。不过说实话,如果你只是想显示样本数量,完全没必要用副Y轴——上面的柱子标注已经够用了。要是确实需要副轴,给你个示例:

plt.figure(figsize=(12,5))
digit_count = sns.countplot(x=Y_train)
plt.title('Distribution of digits')

# 创建副Y轴
twin_table = digit_count.twinx()
# 设置副Y轴刻度(根据你的需求调范围)
twin_table.set_yticks(np.arange(0, 7000, 1000))
# 给副Y轴起名字
twin_table.set_ylabel('样本数量(副轴)', fontsize=12)

# 加柱子标注
for d in digit_count.patches:
    x_pos = d.get_x() + d.get_width()/2
    y_pos = d.get_height()
    digit_count.annotate(f'{int(y_pos)}', (x_pos, y_pos), ha='center', va='bottom')

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:30:00