【问题标题】:Show only certain tick labels in log plot在对数图中仅显示某些刻度标签
【发布时间】:2021-10-15 21:05:37
【问题描述】:

下面的代码产生这样的图:

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

ax.get_yticks()
ax.get_yticklabels()

检索已绘制的刻度,并从中仅选择y_min 值以上的刻度来显示。这两个命令都不会返回绘图中绘制的实际刻度标签。

我该怎么做?


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()

【问题讨论】:

  • 试试ax.set_ylim(y_min,y_max)
  • @ShervinRad - 这是一个 NameError: name 'y_max' is not defined,OP 询问的是 yticklabels,而不是 ylim。

标签: python numpy matplotlib plot data-visualization


【解决方案1】:

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

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

以下示例代码使用最新的 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') 为次要刻度和主要刻度设置相同的刻度长度。

【讨论】:

  • 我选择这个问题是因为它更简洁,并且不会像 Andrea 那样抛出 FixedFormatter should only be used together with FixedLocator 类型的警告。谢谢!
【解决方案2】:

你必须得到当前的 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()

【讨论】:

  • 这几乎给了我我需要的情节,我只需将float 更改为int 以删除.0 小数位。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
相关资源
最近更新 更多