Python绘图:解决直方图极值差异导致小值无法显示的问题
解决数据量级差异大导致柱状图小数值不可见的问题
嘿,这个场景我做实验可视化时也碰到过!当一组数据里有个“巨无霸”数值时,普通柱状图确实会把小数值的柱子压缩到几乎看不见,下面分享几个实用的解决思路,既有数值缩放技巧,也有替代的可视化方法:
一、数值缩放技巧(让原有柱状图能展示所有数据)
1. 使用对数坐标轴
对数刻度可以压缩大范围数值的显示空间,同时放大小数值之间的差异,完美适配这种量级差距极大的场景,而且你的数据都是正数,完全适用!
修改你的代码只需加一行:
import numpy as np import matplotlib.pyplot as plt height = [0.422602, 0.000011, 0.000453] bars = ('2X2', '4X4', '8X8') y_pos = np.arange(len(bars)) plt.bar(y_pos, height, color=(0.572549, 0.2862, 0.0, 1)) plt.xlabel('Matrix Dimensions') plt.ylabel('Fidelity for Matrices with Sparsity 1') plt.xticks(y_pos, bars) # 启用对数y轴 plt.yscale('log') # 手动设置刻度,让小数值显示更清晰 plt.yticks([1e-5, 4e-5, 1e-4, 4e-4, 1e-3, 1e-2, 1e-1, 0.5]) plt.show()
这样既能清楚看到三个柱子的高度差异,也能直观感受到数值的量级差距。
2. 截断Y轴并添加注释
如果你不想用对数刻度(比如需要保留线性的直观感),可以把Y轴的显示范围截断到小数值区间,再给大数值的柱子加注释说明实际值:
import numpy as np import matplotlib.pyplot as plt height = [0.422602, 0.000011, 0.000453] bars = ('2X2', '4X4', '8X8') y_pos = np.arange(len(bars)) fig, ax = plt.subplots() ax.bar(y_pos, height, color=(0.572549, 0.2862, 0.0, 1)) ax.set_xlabel('Matrix Dimensions') ax.set_ylabel('Fidelity for Matrices with Sparsity 1') ax.set_xticks(y_pos) ax.set_xticklabels(bars) # 把Y轴范围限制在小数值区间 ax.set_ylim(0, 0.0005) # 给最大的柱子添加带箭头的注释,标注实际值 ax.annotate(f'Actual value: {height[0]}', xy=(y_pos[0], 0.0005), # 箭头指向柱子顶端(截断后的位置) xytext=(y_pos[0], 0.0006), # 注释文本的位置 arrowprops=dict(facecolor='gray', shrink=0.05)) plt.show()
二、替代的可视化方法
如果柱状图实在不适合你的数据,这些方法也能帮你清晰展示所有数值:
- 散点图+数值标注:直接用散点标记每个数值,再在每个点旁标注具体数值,简单直接:
plt.scatter(y_pos, height, color=(0.572549, 0.2862, 0.0, 1)) plt.xlabel('Matrix Dimensions') plt.ylabel('Fidelity for Matrices with Sparsity 1') plt.xticks(y_pos, bars) # 给每个点添加数值标注 for x, h in zip(y_pos, height): plt.text(x, h + 0.0001, f'{h:.6f}', ha='center') plt.show() - 子图拆分:把大数值和小数值分别放在两个子图里,各自用合适的刻度:
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(6, 8)) # 上子图显示大数值 ax1.bar(y_pos[:1], height[:1], color=(0.572549, 0.2862, 0.0, 1)) ax1.set_xticks(y_pos[:1]) ax1.set_xticklabels(bars[:1]) ax1.set_ylabel('Fidelity (Large Value)') # 下子图显示小数值 ax2.bar(y_pos[1:], height[1:], color=(0.572549, 0.2862, 0.0, 1)) ax2.set_xticks(y_pos[1:]) ax2.set_xticklabels(bars[1:]) ax2.set_xlabel('Matrix Dimensions') ax2.set_ylabel('Fidelity (Small Values)') plt.tight_layout() plt.show() - 饼图(展示占比):如果你的需求是看各数值的占比,饼图能直观展示大数值的主导地位,还可以把小数值的部分“炸开”突出显示:
plt.pie(height, labels=bars, explode=[0, 0.1, 0.1], autopct='%1.6f%%', colors=[(0.572549,0.2862,0.0,1), '#888888', '#AAAAAA']) plt.title('Fidelity Distribution') plt.show()
你可以根据具体需求选择最合适的方法:如果要保留数值的量级对比,对数坐标轴或子图拆分是不错的选择;如果要展示占比,饼图更直观~
内容的提问来源于stack exchange,提问作者Protik Nag
相关产品推荐
相关产品推荐

