Matplotlib柱状图绘制出现不存在数值的问题排查
matplotlib绘制数值频率柱状图出现不存在值的问题排查
异常产生原因
- 最常见诱因:x轴连续刻度自动补全+柱子宽度设置不当。直接把
Counter统计得到的整数/浮点数键传入plt.bar()时,matplotlib默认会将x轴识别为连续数值轴,自动生成连续的整数刻度,不会只显示你传入的离散值。比如你传入的x值是5、6、8、9,matplotlib会自动补上7这个刻度位;如果此时柱子宽度设置≥1,相邻的6和8对应的柱子会向中间挤占7的刻度位置,视觉上就像7这个不存在的值也有对应柱状条,实际7对应的计数是0。 - 数据类型隐式误差:widthList中可能存在浮点数和整数混用的情况,比如存在
6.999999999999、7.000000000001这类计算误差产生的近似值,Counter会将其识别为独立元素统计,肉眼核对整数7的时候很容易漏掉这类浮点值。 - 统计逻辑错误:调用
Counter时如果没有直接传入原始widthList,而是误传入了做过错误类型转换、切片错误的对象,也会导致统计结果混入额外值。
问题复现
你可以运行下面的最小复现代码,复现“无7但x轴显示7刻度、相邻柱子挤占位置看起来7有计数”的现象:
from collections import Counter import matplotlib.pyplot as plt # 构造完全不含7的测试数据集 widthList = [5,5,6,6,6,8,8,9,9,9,9] count_dict = Counter(widthList) # 错误写法:直接传入数值键,不做离散分类处理 plt.bar(count_dict.keys(), count_dict.values(), width=1) plt.show()
运行后可以看到x轴自动生成了5/6/7/8/9的连续刻度,7的位置没有对应数据,但宽度为1的柱子刚好覆盖了7的刻度区间,视觉上和有计数的柱子没有区别。
修复方案
- 先做前置校验,确认统计结果本身没有问题
先打印Counter的全量统计结果,排查是否存在被忽略的近似浮点值、错误混入的额外值:count_dict = Counter(widthList) print("全量统计结果:", count_dict) print("所有被统计的数值:", list(count_dict.keys())) - 方案一:将x轴数值转为字符串,强制按离散分类绘图
把数值类的键转为字符串后传入,matplotlib会将其识别为分类轴,不会自动补全不存在的中间刻度:x_labels = [str(k) for k in count_dict.keys()] freq = list(count_dict.values()) plt.bar(x_labels, freq, width=0.8) plt.xlabel("width数值") plt.ylabel("出现频率") plt.show() - 方案二:手动指定x轴刻度,关闭自动补全
保留数值类型x轴的前提下,手动指定只显示实际存在的数值作为刻度,同时将柱子宽度设置为小于1,避免相邻柱子挤占空白刻度位置:x_vals = list(count_dict.keys()) freq = list(count_dict.values()) plt.bar(x_vals, freq, width=0.8) # 手动指定刻度只显示实际存在的数值 plt.xticks(ticks=x_vals, labels=x_vals) plt.show()
内容的提问来源于stack exchange,提问作者arizona_3
相关产品推荐
相关产品推荐

