在 Matplotlib 中的对数刻度图中设置主要 yticks
setting major yticks in log-scale plot in Matplotlib
我想创建一个垂直比例为对数比例的绘图。我希望主要刻度(带有数字标签)位于 1e-9
、1e-6
、1e-3
、1e0
,并且我希望次刻度位于 10 的每一次幂处,即 1e-9
、1e-8
、1e-7
、...、1e-1
、1e0
。换句话说,我总共想要 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-9
、1e-6
、1e-3
和1e0
刻度数:
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-9
、1e-6
、1e-3
和 1e0
(带标签)使用主刻度,对其他刻度(不带标签)使用次刻度:
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)
我想创建一个垂直比例为对数比例的绘图。我希望主要刻度(带有数字标签)位于 1e-9
、1e-6
、1e-3
、1e0
,并且我希望次刻度位于 10 的每一次幂处,即 1e-9
、1e-8
、1e-7
、...、1e-1
、1e0
。换句话说,我总共想要 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-9
、1e-6
、1e-3
和1e0
刻度数:
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-9
、1e-6
、1e-3
和 1e0
(带标签)使用主刻度,对其他刻度(不带标签)使用次刻度:
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)