Figure 和 Axes 当作对象,给它们“精雕细琢”!import matplotlibmatplotlib.use('TkAgg') # 指定后端,防止IDE中图表闪退import matplotlib.pyplot as pltimport numpy as np# 💡 【避坑指南】全局设置中文字体# Windows 用户用 'SimHei' (黑体)# Mac 用户用 'Arial Unicode MS' 或 'PingFang SC'plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']plt.rcParams['axes.unicode_minus'] = False # 正常显示负号
当你需要对比多组数据时,把它们画在同一张图的不同区域(子图)是最佳选择。
plt.subplot():像填格子一样,plt.subplot(2, 2, 1) 表示 2行2列的第1个位置。(不推荐,容易状态混乱)plt.subplots():🌟 强烈推荐! 返回画布和包含所有子图对象的 NumPy 数组,完美契合 OOP 思想。# 创建一个 2x2 的画布,大小为 10x8 英寸fig, axes = plt.subplots(2, 2, figsize=(10, 8))# axes 是一个 2x2 的二维数组,通过索引获取具体的 Axes 对象axes[0, 0].plot([1, 2, 3], [4, 5, 6], color='red')axes[0, 0].set_title('折线图')axes[0, 1].scatter([1, 2, 3], [4, 5, 6], color='blue')axes[0, 1].set_title('散点图')axes[1, 0].bar(['A', 'B', 'C'], [5, 7, 3], color='green')axes[1, 0].set_title('柱状图')axes[1, 1].hist([1, 2, 2, 3, 3, 3, 4, 4, 4, 4], bins=4, color='purple')axes[1, 1].set_title('直方图')# 💡 【扩展】tight_layout() 自动调整子图参数,使之填充整个图像区域,防止重叠plt.tight_layout()plt.show()
坐标轴是图表的骨架。通过 OOP 的方式,我们可以像操作对象属性一样控制它。
ax.set()不用写一堆 set_xlabel, set_xlim,ax.set() 可以一次性搞定:
fig, ax = plt.subplots()ax.plot([1, 2, 3], [2, 4, 6])# 批量设置坐标轴属性ax.set(title='一站式设置示例',xlabel='X轴 (自定义)',ylabel='Y轴 (自定义)',xlim=(0, 4),ylim=(0, 8),xticks=[0, 1, 2, 3, 4],yticks=[0, 2, 4, 6, 8])plt.show()
你看那些顶级期刊(如 Nature, Science)上的图表,通常没有顶部和右侧的边框线,看起来非常干净。在 Matplotlib 中,边框被称为 Spines。
fig, ax = plt.subplots()ax.plot([1, 2, 3], [4, 5, 6])# 💡 【扩展】隐藏上、右边框ax.spines['top'].set_visible(False)ax.spines['right'].set_visible(False)# 💡 【扩展】将下、左边框移动到数据 0 的位置(适合画数学函数坐标系)ax.spines['bottom'].set_position('zero')ax.spines['left'].set_position('zero')plt.show()
当你的数据跨越多个数量级(比如从 1 暴增到 10000),普通的线性坐标轴会把小数据挤成一条线。这时候需要求出对数坐标轴。
x = np.linspace(1, 10, 100)y = np.exp(x) # 指数爆炸数据fig, ax = plt.subplots()ax.plot(x, y, label='指数增长')# 将 Y 轴设置为对数刻度ax.set_yscale('log')ax.set_title('半对数坐标轴 (Y轴Log)')ax.legend()plt.show()
loc 参数指定位置,或者用 frameon=False 去掉图例的边框。ax.legend(loc='upper right', # 位置:右上角 (也可写数字代码 1)fontsize=12, # 字体大小frameon=False, # 去掉边框shadow=True # 添加阴影(可选))
让标题和重点标签脱颖而出:
ax.set_title('抛物线示例',fontsize=16, # 字号fontweight='bold', # 加粗 (可选 'light', 'normal')fontstyle='italic',# 斜体color='darkblue') # 颜色# 💡 【扩展】单独修改刻度标签的字体大小ax.tick_params(axis='both', which='major', labelsize=12)
linestyle): '-' (实线), '--' (虚线), '-.' (点划线), ':' (点线)color): 支持英文单词 ('red')、首字母 ('r')、十六进制 ('#FF5733')、RGB元组 ((0.1, 0.2, 0.5))。推荐使用十六进制,可以搭配网上的配色网站获取高级色!linewidth): 数值越大越粗。默认的白底黑线看腻了?我们来给它“换个皮肤”:
fig, ax = plt.subplots()ax.plot([1, 2, 3], [4, 5, 6], color='#E74C3C', linewidth=2)# 1. 更改整个 Figure 的背景色fig.patch.set_facecolor('#F5F5F5') # 浅灰色# 2. 更改 Axes (绘图区) 的背景色ax.set_facecolor('#FFFFFF') # 纯白色# 3. 添加网格线 (虚线、灰色、半透明)ax.grid(True, linestyle='--', color='gray', alpha=0.6)# 💡 【扩展】开启次级刻度并显示次级网格线(适合科研图表)# ax.minorticks_on()# ax.grid(which='minor', linestyle=':', alpha=0.4)plt.show()
让我们把今天学的子图、Spines隐藏、高级配色、网格、对数坐标全部融合在一起,看看 OOP 定制的强大威力!
# 1. 准备数据x = np.linspace(1, 10, 50)y1 = x**2 # 二次函数y2 = np.exp(x) # 指数函数# 2. 创建 1行2列 的子图,设置整体大小fig, axes = plt.subplots(1, 2, figsize=(12, 5))# ================= 左图:线性坐标与极简风 =================ax1 = axes[0]ax1.plot(x, y1, color='#2980B9', linewidth=2.5, linestyle='-', label='y = x^2')ax1.set_title('二次函数增长 (线性坐标)', fontsize=14, fontweight='bold', pad=15)ax1.set_xlabel('时间', fontsize=12)ax1.set_ylabel('数值', fontsize=12)ax1.legend(frameon=False, fontsize=11)ax1.grid(True, linestyle=':', alpha=0.7)# 隐藏上右边框ax1.spines['top'].set_visible(False)ax1.spines['right'].set_visible(False)# ================= 右图:对数坐标展示指数爆炸 =================ax2 = axes[1]ax2.plot(x, y2, color='#C0392B', linewidth=2.5, linestyle='--', marker='o', markersize=4, label='y = e^x')ax2.set_title('指数函数增长 (半对数坐标)', fontsize=14, fontweight='bold', color='#C0392B', pad=15)ax2.set_xlabel('时间', fontsize=12)ax2.set_ylabel('数值 (Log)', fontsize=12)ax2.set_yscale('log') # 核心:Y轴对数化ax2.legend(frameon=False, fontsize=11)ax2.grid(True, which='both', linestyle='--', alpha=0.5) # 主副网格都显示# 隐藏上右边框ax2.spines['top'].set_visible(False)ax2.spines['right'].set_visible(False)# 3. 整体布局与背景fig.patch.set_facecolor('#FAFAFA') # 画布浅灰背景plt.tight_layout()# 4. 高清保存plt.savefig('advanced_plot.png', dpi=300, bbox_inches='tight')plt.show()
fig, ax = plt.subplots(),通过 ax.xxx() 去定制对象,这比 plt.xxx() 更清晰、更可控。ax.spines['top/right'].set_visible(False) 是提升图表专业度的最快方法。set_yscale('log')。#2980B9),图表质感瞬间提升。