# 4.2.3:自定义坐标刻度 ## 主次要刻度 学习前最好先对`matplotlib`图形的对象层级有深入了解。`matplotlib`的`figure`对象是一个盛放图形元素的包围盒。可以将每个`matplotlib`对象都看成是子对象的容器,每个`figure`都包含`axes`对象,每个`axes`对象又包含其他表示图形内容的对象,比如`xaxis/yaxis`,每个属性包含构成坐标轴的线条、刻度和标签的全部属性。 每一个坐标轴都有主次要刻度,主要刻度要比次要刻度更大更显著,而次要刻度往往更小。 ```python import matplotlib.pyplot as plt import numpy as np ax = plt.axes(xscale='log', yscale='log') plt.show() ``` ![](14.jpg) 可以看到主要刻度都显示为一个较大的刻度线和标签,而次要刻度都显示为一个较小的可读性,不显示标签。 ## 隐藏刻度与标签 最常用的刻度/标签格式化操作可能就是隐藏刻度与标签了,可以通过`plt.NullLocator()`和`plt.NullFormatter()`实现。 示例如下: ```python ax = plt.axes() ax.plot(np.random.rand(50)) ax.yaxis.set_major_locator(plt.NullLocator()) ax.xaxis.set_major_formatter(plt.NullFormatter()) plt.show() ``` ![](15.jpg) 这里`x`轴的标签隐藏了但是保留了刻度线,`y`轴的刻度和标签都隐藏了。有的图片中都不需要刻度线,比如下面这张包含人脸的图形: ```python fig, ax = plt.subplots(5, 5, figsize=(5, 5)) fig.subplots_adjust(hspace=0, wspace=0) # 从scikit-learn获取一些人脸照片数据 from sklearn.datasets import fetch_olivetti_faces faces = fetch_olivetti_faces().images for i in range(5): for j in range(5): ax[i, j].xaxis.set_major_locator(plt.NullLocator()) ax[i, j].yaxis.set_major_locator(plt.NullLocator()) ax[i, j].imshow(faces[10 * i + j], cmap="bone") plt.show() ``` ![](16.png) ## 花哨的刻度格式 `matplotlib`默认的刻度格式可以满足大部分的需求。虽然默认配置已经很不错了,但是有时候可能需要更多的功能,比如正弦曲线和余弦曲线,默认情况下刻度为整数,如果将刻度与网格线画在`π`的倍数上图形会更加自然,可以通过设置一个`multipleLocator`来实现将刻度放在你提供的数值倍数上: ```python fig, ax = plt.subplots() x = np.linspace(0, 3 * np.pi, 1000) ax.plot(x, np.sin(x), lw=3, label='Sine') ax.plot(x, np.cos(x), lw=3, label='Cosine') # 设置网格、图例和坐标轴上下限 ax.grid(True) ax.legend(frameon=False) ax.axis('equal') ax.set_xlim(0, 3 * np.pi) ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2)) ax.xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 4)) plt.show() ``` ![](17.jpg) `matplotlib`还支持用数学符号来做刻度,在数学表达式两侧加上美元符号`$`,这样就可以方便地显示数学符号和数学公式。可以用`plt.FuncFormatter`来实现,用一个自定义函数设置不同刻度标签的显示: ```python def format_func(value, tick_number): # 找到π/2的倍数刻度 N = int(np.round(2 * value / np.pi)) if N == 0: return "0" elif N == 1: return r"$\pi/2$" elif N == 2: return r"$\pi$" elif N % 2 > 0: return r"${0}\pi/2$".format(N) else: return r"${0}\pi$".format(N // 2) ax.xaxis.set_major_formatter(plt.FuncFormatter(format_func)) ``` ![](18.jpg) ## 格式生成器与定位器 前面已经介绍了一些格式生成器和定位器,这里再用表格简单总结一些内置的格式生成器和定位器: | 定位器 |描述 | | :------------: | :------------: | |NullLocator |无刻度 | | FixedLocator | 刻度位置固定 | | IndexLocator | 用索引作为定位器 | | LinearLocator | 从min 到max 均匀分布刻度 | | LogLocator |从min 到max 按对数分布刻度 | |MultipleLocator |刻度和范围都是基数的倍数 | |MaxNLocator |为最大刻度找到最优位置 | |AutoMinorLocator | 次要刻度的定位器 | |格式生成器 |描述 | | :------------: | :------------: | |NullFormatter |刻度上无标签 | |IndexFormatter | 将一组标签设置为字符串 | |FixedFormatter |手动为刻度设置标签 | |FuncFormatter |用自定义函数设置标签 | |FormatStrFormatter |为每个刻度值设置字符串格式 | |ScalarFormatter |为标量值设置标签 | |LogFormatter |对数坐标轴的默认格式生成器 |