Matplotlib柱状图对数刻度失效问题咨询
解决Matplotlib对数刻度柱状图显示异常的问题
你遇到的情况很典型:当使用ax.set_yscale('log')或者bar(log=True)绘制对数刻度柱状图时,图1、图2显示异常(柱子无法正确体现两个数值的对数差异,比如看起来高度几乎一致);但手动计算log10(y2)后绘制的图3却正常,这是因为Matplotlib的默认设置在对数刻度下有个小坑。
问题根源
Matplotlib绘制柱状图时,默认把柱子的底部放在0的位置,但对数坐标系里0是没有定义的(log10(0)无意义),这就导致柱子的渲染出现异常——要么被截断,要么高度显示失真。而你手动转换log10(y2)后,是在线性刻度下绘制转换后的数据,自然就避开了这个问题。
解决方案
只需要给柱状图设置一个大于0的底部值(bottom参数),或者调整y轴的下限,让柱子的底部落在对数刻度的有效范围内。下面是修改后的可运行代码:
from __future__ import division import numpy as np from matplotlib import pyplot as plt ind = np.array(['US', 'EU']) y2 = [545000, 600000] # 设置一个合适的底部值,比如取数据最小值的1/100,确保在对数刻度内 bottom_val = min(y2) / 100 # 修复example 1:使用set_yscale('log') fig = plt.figure(1) ax = fig.add_subplot(1, 1, 1) plt.bar(ind, y2, bottom=bottom_val) ax.set_yscale('log') # 调整y轴下限,让显示更合理 ax.set_ylim(bottom=bottom_val) plt.title('example 1 (fixed)') # 修复example 2:使用bar的log=True参数 fig = plt.figure(2) ax2 = fig.add_subplot(1, 1, 1) plt.bar(ind, y2, log=True, bottom=bottom_val) ax2.set_ylim(bottom=bottom_val) plt.title('example2 (fixed)') # 保留原来正常的example 3 fig2 = plt.figure(3) ax1 = fig2.add_subplot(1, 1, 1) plt.bar(ind, np.log10(y2)) plt.title('example 3 (original correct)') plt.show()
补充说明
- 如果需要保留原始数据的刻度标签(比如显示
545000而不是5.736),推荐用对数刻度+设置bottom的方式,这样更直观。 - 你手动转换
log10(y2)的方法也完全可行,适合只需要展示对数转换后数值的场景。
内容的提问来源于stack exchange,提问作者Laura
相关产品推荐
相关产品推荐

