当前位置:首页>python>一起学Python第102天:

一起学Python第102天:

  • 2026-10-11 05:46:41
一起学Python第102天:
欢迎来到Python学习的第102天!
如果说昨天我们学会了如何把数据“画”出来,那么今天我们要学的就是如何把数据 “画得漂亮、画得专业”。
在数据科学界有一句名言:“字不如表,表不如图”。但一张未经定制的“默认图表”,往往显得粗糙且缺乏重点。今天我们将深入 Matplotlib 的图表定制,结合你之前学过的 OOP(面向对象) 思想,把 Figure 和 Axes 当作对象,给它们“精雕细琢”!

🎨 课前准备:标准“起手式”

为了避免后续代码中反复出现中文乱码和后端问题,我们先确立今天的全局初始化模板。建议你把这段代码刻在DNA里:
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  # 正常显示负号

一、 排兵布阵:子图与画布布局 📐

1. 创建多个子图(多面板展示)

当你需要对比多组数据时,把它们画在同一张图的不同区域(子图)是最佳选择。

  • 状态机方式 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 的方式,我们可以像操作对象属性一样控制它。

1. 一站式设置 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()

2. 高阶玩法:隐藏边框(打造学术/极简风) 🌟

你看那些顶级期刊(如 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()

3. 数据降维打击:对数坐标轴

当你的数据跨越多个数量级(比如从 1 暴增到 10000),普通的线性坐标轴会把小数据挤成一条线。这时候需要求出对数坐标轴。

  • 半对数:Y轴指数增长,X轴线性(如:病毒传播、复利计算)。
  • 双对数:X和Y都是对数(如:幂律分布、帕累托法则)。
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()

三、 点睛之笔:文本、图例与字体 🖋️

1. 图例的智能摆放

图例(Legend)如果挡住了数据线就尴尬了。可以通过 loc 参数指定位置,或者用 frameon=False 去掉图例的边框。
ax.legend(    loc='upper right',  # 位置:右上角 (也可写数字代码 1)    fontsize=12,        # 字体大小    frameon=False,      # 去掉边框    shadow=True         # 添加阴影(可选))

2. 字体样式大赏

让标题和重点标签脱颖而出:

ax.set_title('抛物线示例',              fontsize=16,       # 字号             fontweight='bold', # 加粗 (可选 'light', 'normal')             fontstyle='italic',# 斜体             color='darkblue')  # 颜色# 💡 【扩展】单独修改刻度标签的字体大小ax.tick_params(axis='both', which='major', labelsize=12)

四、 视觉盛宴:线条、色彩与背景 🌈

1. 线条的“三要素”:样式、颜色、宽度

2. 背景与网格(营造高级感)

默认的白底黑线看腻了?我们来给它“换个皮肤”:

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

💡 今日学习总结

  1. OOP 思维是核心:永远优先使用 fig, ax = plt.subplots(),通过 ax.xxx() 去定制对象,这比 plt.xxx() 更清晰、更可控。
  2. 学术风秘诀:ax.spines['top/right'].set_visible(False) 是提升图表专业度的最快方法。
  3. 对数坐标:遇到“指数爆炸”的数据,不要犹豫,直接 set_yscale('log')。
  4. 配色:放弃 Matplotlib 默认的红蓝绿,尝试使用十六进制颜色码(如 #2980B9),图表质感瞬间提升。
🎯 今日金句: "Data without visualization is like a song without melody; it has the notes, but lacks the soul." (没有可视化的数据就像没有旋律的歌;它有音符,却缺乏灵魂。)

最新文章

随机文章