在 Matplotlib 中的对数刻度图中设置主要 yticks

setting major yticks in log-scale plot in Matplotlib

我想创建一个垂直比例为对数比例的绘图。我希望主要刻度(带有数字标签)位于 1e-91e-61e-31e0,并且我希望次刻度位于 10 的每一次幂处,即 1e-91e-81e-7、...、1e-11e0。换句话说,我总共想要 4 个主要刻度(带有数字标签)和 10 个次要刻度。我使用以下蛮力方法让它工作:

fig, ax = plt.subplots()

ax.set_yscale('log')

ax.set_ylim([1e-9,1])
ax.set_yticks(np.logspace(-9,0,10))
ax.set_yticklabels([r'^{-9}$','','',r'^{-6}$','','',r'^{-3}$','','',r'^{0}$'])

plt.show()

但我想尽可能避免使用 MathText,因为这会弄乱图形的字体,而且还需要我手动记下刻度,这样如果我更改位置,工作量会很大滴答声。

有没有更自动化的方法?我试过查看 ax.yaxis.set_minor_locator(LogLocator(base=10, numticks=10)),但我无法找出适合我的案例的正确参数值。

您可以将所有刻度设置为 10 的幂:

ax.yaxis.set_major_locator(FixedLocator(locs = np.logspace(-9, 0, 10)))

然后你可以删除指数绝对值不是3的倍数的刻度,这样你只保留1e-91e-61e-31e0 刻度数:

fig.canvas.draw()

yticks = ax.yaxis.get_major_ticks()
for tick in yticks:
    if np.log10(tick.get_loc())%3 != 0:
        tick.label1.set_visible(False)

完整代码

from matplotlib import pyplot as plt
from matplotlib.ticker import FixedLocator
import numpy as np


x = np.linspace(0, 20, 21)
y = np.exp(-x)


fig, ax = plt.subplots()

ax.plot(x, y, marker = 'o')

ax.set_yscale('log')
ax.yaxis.set_major_locator(FixedLocator(locs = np.logspace(-9, 0, 10)))

fig.canvas.draw()

yticks = ax.yaxis.get_major_ticks()
for tick in yticks:
    if np.log10(tick.get_loc())%3 != 0:
        tick.label1.set_visible(False)

plt.show()


您还可以对 1e-91e-61e-31e0(带标签)使用主刻度,对其他刻度(不带标签)使用次刻度:

ax.set_yscale('log')
ax.yaxis.set_major_locator(FixedLocator(locs = np.logspace(-9, 0, 4)))
ax.yaxis.set_minor_locator(FixedLocator(locs = np.logspace(-9, 0, 10)))

fig.canvas.draw()

yticks = ax.yaxis.get_minor_ticks()
for tick in yticks:
    if np.log10(tick.get_loc())%3 != 0:
        tick.label1.set_visible(False)