让我们考虑以下示例,为给定的y
值绘制一些x
值。
import matplotlib.pyplot as pyplot
if __name__ == "__main__":
x = [1000000000, 2000000000, 4000000000, 8000000000]
y = [0.342, 0.543, 0.874, 1.324]
pyplot.bar(x, y)
pyplot.savefig("test1.png", format="png")
pyplot.close()
pyplot.bar([str(int(x_value / 1000000000)) for x_value in x], y)
pyplot.savefig("test2.png", format="png")
pyplot.close()
我的目标是为所有x
值设置等距的x刻度(即,不是线性缩放)。此外,我希望以科学计数法(即1e9
)看到这些值。
test1.png
根本没有显示任何有意义的内容。
test2.png
以所需的方式显示值,但右下角(1e9
)没有科学标签。
我如何手动将1e9
放在x轴单位位置或解决我的问题?
答案 0 :(得分:1)
您的第一张图没有显示这些条形图,因为默认宽度0.8使其与x轴上的数据范围相比非常细。您需要使它们更宽。
对数刻度将使位置等距。要根据需要显示刻度,可以显式设置刻度,默认的ScalarFormatter
可以替换LogFormatter
随附的plt.xscale('log')
。在默认位置(例如,对数刻度上的3,5,6,7)仍会出现较小的滴答声,可以用NullLocator
来消除。
要获得精确居中的条形图,默认居中不适用于对数刻度。可以在对数空间中计算出精确的位置和宽度,然后将其再次转换为线性空间。下面的示例采用最短的x距离,并将其乘以0.8进行分离。
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter, NullLocator
import numpy as np
x = np.array([1000000000, 2000000000, 4000000000, 8000000000])
y = [0.342, 0.543, 0.874, 1.324]
log_x = np.log(x)
log_width = 0.8 * np.diff(np.log(x)).min()
lefts = np.exp(log_x - log_width / 2)
rights = np.exp(log_x + log_width / 2)
ax = plt.gca()
ax.bar(lefts, y, width=[xi * 0.6 for xi in x], align='edge')
ax.set_xscale('log')
ax.set_xticks(x)
ax.xaxis.set_major_formatter(ScalarFormatter())
ax.xaxis.set_minor_locator(NullLocator()) # optionally remove the minor ticks
plt.tight_layout()
plt.show()