在对数图中仅显示某些刻度标签

Show only certain tick labels in log plot

下面的代码生成如下图:

我只需要显示 y 轴上 超过 水平线的刻度标签。在这种情况下,标签 [2,3,4,5] 需要隐藏。我试过使用

ax.get_yticks()
ax.get_yticklabels()

检索绘制的刻度,并从那些 select 中仅显示高于 y_min 值的刻度。既不命令 returns 图中绘制的实际刻度标签。

我该怎么做?


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

# Some random data
x = np.random.uniform(1, 20, 100)
y = np.array(list(np.random.uniform(1, 150, 97)) + [4, 7, 9])
y_min = np.random.uniform(4, 10)

ax = plt.subplot(111)
ax.scatter(x, y)
ax.hlines(y_min, xmin=min(x), xmax=max(x))

ax.set_xscale('log')
ax.set_yscale('log')
ax.yaxis.set_minor_formatter(FormatStrFormatter('%.0f'))
ax.yaxis.set_major_formatter(FormatStrFormatter('%.0f'))

plt.show()

您必须获取当前的 y 刻度标签:

fig.canvas.draw()
labels = [float(text.get_text()) for text in ax.yaxis.get_ticklabels(which = 'minor')]

然后应用您需要的过滤器:

labels_above_threshold = [label if label >= y_min else '' for label in labels]

最后设置过滤标签:

ax.yaxis.set_ticklabels(labels_above_threshold, minor = True)

完整代码

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

x = np.random.uniform(1, 20, 100)
y = np.array(list(np.random.uniform(1, 150, 97)) + [4, 7, 9])
y_min = np.random.uniform(4, 10)

fig, ax = plt.subplots()
ax.scatter(x, y)
ax.hlines(y_min, xmin=min(x), xmax=max(x))

ax.set_xscale('log')
ax.set_yscale('log')
ax.yaxis.set_minor_formatter(FormatStrFormatter('%.0f'))
ax.yaxis.set_major_formatter(FormatStrFormatter('%.0f'))

fig.canvas.draw()

# MINOR AXIS
labels = [int(text.get_text()) for text in ax.yaxis.get_ticklabels(which = 'minor')]
labels_above_threshold = [label if label >= y_min else '' for label in labels]
ax.yaxis.set_ticklabels(labels_above_threshold, minor = True)

# MAJOR AXIS
labels = [int(text.get_text()) for text in ax.yaxis.get_ticklabels(which = 'major')]
labels_above_threshold = [label if label >= y_min else '' for label in labels]
ax.yaxis.set_ticklabels(labels_above_threshold, minor = False)

plt.show()

刻度标签仅在有效绘制绘图时可用。请注意,当图形以交互方式调整大小或放大时,位置会发生变化。

一个想法是将测试添加到格式化程序函数中,这样在缩放等之后一切都会保持正常。

以下示例代码使用最新的matplotlib,它允许设置一个FuncFormatter而不需要单独声明一个函数:

import numpy as np
import matplotlib.pyplot as plt

x = np.random.uniform(1, 20, 100)
y = np.array(list(np.random.uniform(1, 150, 97)) + [4, 7, 9])
y_min = np.random.uniform(4, 10)

ax = plt.subplot(111)
ax.scatter(x, y)
ax.axhline(y_min) # occupies the complete width of the plot

ax.set_xscale('log')
ax.set_yscale('log')
ax.yaxis.set_minor_formatter(lambda x, t: f'{x:.0f}' if x >= y_min else None)
ax.yaxis.set_major_formatter(lambda x, t: f'{x:.0f}' if x >= y_min else None)

plt.show()

PS:您可以使用 ax.tick_params(length=4, which='both') 为次要和主要刻度设置相同的刻度长度。