高级定制:坐标轴与刻度

坐标轴和刻度是图表的重要组成部分,直接影响数据的可读性和美观度。 Matplotlib 提供了极其灵活的坐标轴控制系统,允许你自定义标签、范围、刻度位置、刻度格式,甚至创建双坐标轴和对数坐标。 本章将全面介绍如何精调坐标轴和刻度,让你的图表更加专业。

🏷️ 1. 设置坐标轴标签

使用 xlabel()ylabel() 为坐标轴添加描述性标签:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)

plt.plot(x, y)
plt.xlabel('时间 (秒)', fontsize=12, color='blue')
plt.ylabel('振幅', fontsize=12, color='red')
plt.title('带标签的正弦曲线')
plt.show()
✔️ 可以使用 fontsize, color, fontweight 等参数定制样式。

📏 2. 设置坐标轴范围

使用 xlim()ylim() 控制坐标轴的显示范围:

plt.plot(x, y)
plt.xlim(0, 2*np.pi)    # X轴范围 0~2π
plt.ylim(-1.5, 1.5)     # Y轴范围 -1.5~1.5
plt.title('限制坐标轴范围')
plt.show()
✔️ 也可以使用 ax.set_xlim()ax.set_ylim()

🔢 3. 设置刻度和刻度标签

xticks()yticks() 可以同时设置刻度位置和标签:

plt.plot(x, y)
# 设置 X 轴刻度位置和标签
plt.xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi],
           ['0', 'π/2', 'π', '3π/2', '2π'])
plt.yticks([-1, 0, 1], ['低', '中', '高'])
plt.title('定制刻度标签')
plt.show()
✔️ 第一个参数是位置列表,第二个参数是标签列表(可选)。

🔧 4. 面向对象方式设置刻度

使用 ax.set_xticks()ax.set_xticklabels() 更灵活:

fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi])
ax.set_xticklabels(['0', 'π/2', 'π', '3π/2', '2π'], fontsize=10)
ax.set_yticks([-1, 0, 1])
ax.set_yticklabels(['Low', 'Medium', 'High'], rotation=45)
ax.set_title('面向对象刻度设置')
plt.show()

📝 5. 使用刻度格式化器

Matplotlib 提供多种格式化器,例如 StrMethodFormatter, FuncFormatter, ScalarFormatter 等:

import matplotlib.ticker as ticker

fig, ax = plt.subplots()
ax.plot(np.arange(0, 10, 0.1), np.exp(np.arange(0, 10, 0.1)))

# 使用字符串格式化器
ax.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:.1f}'))

# 使用函数格式化器(自定义函数)
def millions(x, pos):
    return f'{x/1e6:.1f}M'
ax.yaxis.set_major_formatter(ticker.FuncFormatter(millions))

plt.title('使用格式化器')
plt.show()
✔️ 格式化器可以精确控制刻度标签的显示方式。

🔄 6. 创建双坐标轴

使用 twinx() 创建共享 X 轴的第二个 Y 轴,twiny() 创建共享 Y 轴的第二个 X 轴:

fig, ax1 = plt.subplots()
x = np.arange(0, 10, 0.1)
y1 = np.sin(x)
y2 = np.exp(x)

ax1.plot(x, y1, 'b-')
ax1.set_xlabel('X')
ax1.set_ylabel('sin(x)', color='b')
ax1.tick_params(axis='y', labelcolor='b')

ax2 = ax1.twinx()  # 创建第二个Y轴
ax2.plot(x, y2, 'r-')
ax2.set_ylabel('exp(x)', color='r')
ax2.tick_params(axis='y', labelcolor='r')

plt.title('双Y轴示例')
plt.show()
✔️ 常用于在同一图中展示量纲不同的两组数据。

📊 7. 对数坐标轴

使用 semilogx(), semilogy(), loglog()set_xscale('log') 设置对数坐标:

x = np.logspace(0, 3, 100)  # 对数间隔的点
y = x**2

plt.subplot(1,2,1)
plt.plot(x, y)
plt.title('线性坐标')

plt.subplot(1,2,2)
plt.loglog(x, y)
plt.title('双对数坐标')

plt.tight_layout()
plt.show()
✔️ 对数坐标适用于呈指数或幂律关系的数据。

🦴 8. 定制脊柱(坐标轴线)

通过 ax.spines 可以控制坐标轴线的位置、颜色、线宽等:

fig, ax = plt.subplots()
ax.plot(x, y)

# 将右侧和顶部的脊柱隐藏
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

# 将底部和左侧的脊柱移动到通过原点
ax.spines['bottom'].set_position('zero')
ax.spines['left'].set_position('zero')

plt.title('移动脊柱到原点')
plt.show()
✔️ set_position 可以是 'zero', 'center', 或 (位置, 数值) 元组。

⚙️ 9. 添加次刻度

使用 MultipleLocatorAutoMinorLocator 添加次刻度线:

import matplotlib.ticker as ticker

fig, ax = plt.subplots()
ax.plot(np.arange(0, 10, 0.1), np.sin(np.arange(0, 10, 0.1)))

# 设置主刻度间隔为1
ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
# 设置次刻度间隔为0.2
ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.2))

# 设置次刻度线样式
ax.tick_params(which='minor', length=4, color='gray')

plt.title('添加次刻度')
plt.show()
✔️ 次刻度有助于更精确地读取数据。

🙈 10. 隐藏坐标轴

使用 ax.set_axis_off() 可以完全隐藏坐标轴,常用于图像显示:

fig, ax = plt.subplots()
ax.imshow(np.random.rand(50,50))
ax.set_axis_off()  # 隐藏坐标轴
plt.title('隐藏坐标轴的图像')
plt.show()

🔄 11. 刻度参数微调

tick_params() 可以统一设置刻度线和标签的样式:

plt.plot(x, y)
plt.tick_params(axis='x', direction='in', length=8, labelsize=8, labelrotation=45)
plt.tick_params(axis='y', direction='out', length=10, width=2, colors='red')
plt.title('刻度参数微调')
plt.show()
✔️ 可以分别对 x 轴和 y 轴进行精细控制。

🏆 12. 综合示例

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

# 生成数据
x = np.linspace(0, 2*np.pi, 1000)
y = np.sin(x) * np.exp(-0.1*x)

fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, y, linewidth=2, color='navy', label='阻尼振荡')

# 设置标签
ax.set_xlabel('时间 (rad)', fontsize=12)
ax.set_ylabel('振幅', fontsize=12)

# 设置范围
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-0.8, 0.8)

# 主刻度
ax.xaxis.set_major_locator(ticker.MultipleLocator(np.pi/2))
ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda val, pos: f'{val/np.pi:.0f}π' if val != 0 else '0'))
ax.yaxis.set_major_locator(ticker.MultipleLocator(0.2))

# 次刻度
ax.xaxis.set_minor_locator(ticker.MultipleLocator(np.pi/4))
ax.yaxis.set_minor_locator(ticker.MultipleLocator(0.05))

# 刻度样式
ax.tick_params(axis='both', which='major', length=8, width=1.5)
ax.tick_params(axis='both', which='minor', length=4, width=1, color='gray')

# 脊柱
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

# 网格
ax.grid(True, which='major', linestyle='-', alpha=0.6)
ax.grid(True, which='minor', linestyle='--', alpha=0.3)

# 图例
ax.legend()

plt.title('综合示例:精心定制的坐标轴')
plt.tight_layout()
plt.show()
✔️ 本例展示了主次刻度、格式化器、脊柱隐藏、网格等多种定制技巧。

掌握坐标轴和刻度的定制后,你可以让图表呈现任何你想要的样子。下一章我们将学习如何添加图例、文本注释和箭头,进一步提升图表的表达力。