PAYATHON 2026

Matplotlib 字符串分类轴如何限制刻度数量并支持缩放?

数据小许

结论

字符串形式的 x 值会被 Matplotlib 映射到分类轴上的整数位置。可以自定义 Locator,让刻度根据当前可见范围动态调整:初始视图大约显示 5 个类别刻度,放大后刻度间距缩小,更多类别随之显示。所有刻度仍与类别位置对齐。

StrCategoryLocator 不支持 locator_params(..., nbins=...) 调用的 set_params(),因此会触发题目中的警告。直接使用 MaxNLocator 可以控制刻度密度,但它默认可能生成非整数位置,导致放大后刻度落在类别之间。

设置动态分类刻度

绘图后,为 x 轴设置一个根据可见范围计算步长的定位器:

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

class CategoryLocator(Locator):
    def __init__(self, max_ticks=5):
        super().__init__()
        self.max_ticks = max_ticks

    def __call__(self):
        vmin, vmax = self.axis.get_view_interval()
        return self.tick_values(vmin, vmax)

    def tick_values(self, vmin, vmax):
        if vmin > vmax:
            vmin, vmax = vmax, vmin

        span = max(vmax - vmin, 1)
        step = max(1, int(np.ceil(span / self.max_ticks)))

        first = np.ceil(vmin / step) * step
        last = np.floor(vmax / step) * step
        ticks = np.arange(first, last + 1, step)
        return self.raise_if_exceeds(ticks)

fig, ax = plt.subplots()

x_values = [f"Text{value}" for value in np.arange(25)]
y_values = np.random.randint(5, 10, 25)

ax.scatter(x_values, y_values)
ax.xaxis.set_major_locator(CategoryLocator(max_ticks=5))
ax.grid(True)
plt.show()

定位器会根据当前 x 轴范围计算整数步长,只返回范围内与步长对齐的整数位置。Matplotlib 的分类格式器会继续将这些位置显示为对应的字符串类别。缩小可见范围时,步长也会减小,因此可以看到更多刻度。

注意事项

max_ticks=5 控制的是大致的刻度密度。实际刻度数量会受当前视图边界和整数对齐方式影响,可能少于 5 个。此实现假设分类位置按 Matplotlib 的默认方式映射为整数。如果代码改动了分类轴的位置或转换方式,也需要相应调整定位器。

备注:内容仅供参考。