绘制对数坐标轴

571

我想使用matplotlib绘制一个具有对数坐标轴的图形。

我一直在阅读文档,但是无法弄清语法。我知道它可能像在绘图参数中添加'scale=linear'这样简单,但我似乎无法做对。

示例程序:

import pylab
import matplotlib.pyplot as plt
a = [pow(10, i) for i in range(10)]
fig = plt.figure()
ax = fig.add_subplot(2, 1, 1)

line, = ax.plot(a, color='blue', lw=2)
pylab.show()
7个回答

655
你可以使用 Axes.set_yscale 方法。这允许你在创建 Axes 对象后更改比例尺。如果需要,这也可以让你构建一个控件来让用户选择比例尺。要添加的相关行是:
ax.set_yscale('log')

您可以使用'linear'来切换回线性比例尺。以下是代码示例:

import pylab
import matplotlib.pyplot as plt
a = [pow(10, i) for i in range(10)]
fig = plt.figure()
ax = fig.add_subplot(2, 1, 1)

line, = ax.plot(a, color='blue', lw=2)

ax.set_yscale('log')

pylab.show()

结果图表


7
这种方法很棒,因为它适用于各种类型的图表(例如直方图),而不仅仅是“plot”(这就是semilogx / semilogy所做的)。 - Tim Whitcomb
19
我来到这里是为了学习如何使用轴表示二的幂次方:pylab.gca().set_xscale('log', basex=2)。 - zje
75
Matplotlib有semilogy()函数。此外,直接使用pyplot.yscale()比使用ax.set_yscale('log')更为简便,因为无需获取ax对象(该对象不总是立即可用)。 - Eric O. Lebigot
7
如果你想在两个坐标轴上使用对数刻度,可以尝试使用 loglog(),如果只是在 x 轴上使用对数刻度,则可以尝试使用 semilogx() - drevicko
16
我建议相反。最好使用显式的 ax 对象,而不是仅仅使用 pyplot,因为它只有可能适用于你想要的轴。 - tacaswell
显示剩余4条评论

394

首先,混合使用 pylabpyplot 代码并不是很整洁。此外,优先使用 pyplot 风格而不是使用 pylab。

以下是稍微整理过的代码,只使用了 pyplot 函数:

from matplotlib import pyplot

a = [ pow(10,i) for i in range(10) ]

pyplot.subplot(2,1,1)
pyplot.plot(a, color='blue', lw=2)
pyplot.yscale('log')
pyplot.show()

相关的函数是 pyplot.yscale()。如果您使用面向对象的版本,请将其替换为方法 Axes.set_yscale()。请记住,您还可以使用 pyplot.xscale()(或 Axes.set_xscale())更改X轴的比例尺。查看我的问题什么是“log”和“symlog”的区别?以查看matplotlib提供的几个图形比例尺的示例。

20
pyplot.semilogy() 更加直接。 - Eric O. Lebigot

108

如果您想改变对数的底数,只需添加:

plt.yscale('log',base=2) 

在Matplotlib 3.3之前,你需要使用basex/basey作为对数的底数。


78

您只需要使用semilogy而不是plot:

from pylab import *
import matplotlib.pyplot  as pyplot
a = [ pow(10,i) for i in range(10) ]
fig = pyplot.figure()
ax = fig.add_subplot(2,1,1)

line, = ax.semilogy(a, color='blue', lw=2)
show()

11
还有一个函数叫做semilogx。如果你需要在两个轴上都使用对数尺度,可以使用loglog - drevicko

12

我知道这有点偏题,因为有些评论提到ax.set_yscale('log')是最好的解决方案,我想进行反驳。我不建议在直方图和条形图中使用ax.set_yscale('log')。在我的版本(0.99.1.1)中,我遇到了一些渲染问题-不确定这个问题有多普遍。然而,直方图和条形图都有可选参数,可以将y轴设置为对数尺度,它们能够很好地工作。

参考资料: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.bar

http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.hist


11

所以,如果您只是简单地使用不太复杂的API,就像我经常使用它一样(我在ipython中经常使用它),那么这就是简单明了的。

yscale('log')
plot(...)

希望这篇文章能够帮助到一些寻找简单答案的人!:)

0
这个页面上给出了几种方法(semilogxsemilogyloglog),但它们在底层都做了同样的事情,即调用set_xscale('log')(对于x轴)和set_yscale('log')(对于y轴)。此外,plt.yscale/plt.scale是状态机中的函数,它们在当前Axes对象上调用set_yscale/set_xscale。即使对于条形图(以及直方图,因为它们只是条形图),log=True参数也会根据条形的方向调用set_yscale('log')/set_xscale('log')
所以无论你使用哪个,它们最终都会调用同一个方法。顺便说一下,在选择对数的基数之外,你还可以在同一个函数调用中设置次要刻度位置(使用subs关键字参数)。
data = np.random.choice(np.logspace(-0.5, 1, base=20), 10)
plt.plot(data)
plt.yscale('log', base=10, subs=[10**x for x in (0.25, 0.5, 0.75)], nonpositive='mask')
#                          ^^^ <-- 3 equal-spaced minor ticks       ^^^^ mask invalid values

result


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接