鋒哥原創的Matplotlib3 Python數據可視化視頻教程:
2026版 Matplotlib3 Python 數據可視化 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili
課程介紹
本課程講解利用python進行數據可視化 科研繪圖-Matplotlib,學習Matplotlib圖形參數基本設置,繪圖參數及主要函數,以及Matplotlib基礎繪圖,和Matplotlib高級繪圖。
多子圖及布局實現
Matplotlib 提供了多種創建多子圖布局的方式,適用于數據對比、多維度可視化等場景。以下是三種核心方法及示例:
方法一:plt.subplots()
(推薦)
適用場景:創建均勻網格布局的子圖
plt.subplots()
是 Matplotlib 中用于批量創建圖形(Figure)和子圖(Axes)的核心函數。它簡化了多子圖的布局管理,比傳統的 plt.subplot()
更靈活高效。下面從功能、參數到示例詳細解析:
fig, axes = plt.subplots(nrows=1, ? ? ? ? ? # 子圖行數 (默認1)ncols=1, ? ? ? ? ? # 子圖列數 (默認1)sharex=False, ? ? ?# 是否共享x軸sharey=False, ? ? ?# 是否共享y軸figsize=None, ? ? ?# 圖形大小 (元組: (寬, 高))constrained_layout=False, ?# 自動調整布局**kwargs ? ? ? ? ? # 其他Figure參數 (如dpi, facecolor等)
)
我們看一個示例:
import matplotlib.pyplot as plt
import numpy as np
?
# 設置中文字體支持
plt.rcParams['font.sans-serif'] = ['SimHei'] ?# 用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus'] = False ?# 用來正常顯示負號
?
# 生成數據
x = np.linspace(0, 2 * np.pi, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
y4 = np.exp(x / 8)
?
# 創建2×2子圖布局 (返回Figure對象和Axes數組)
fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(10, 8))
fig.suptitle('2×2 子圖示例', fontsize=16)
?
# 繪制第一個子圖
axs[0, 0].plot(x, y1, 'r-')
axs[0, 0].set_title('正弦函數')
axs[0, 0].grid(True)
?
# 繪制第二個子圖
axs[0, 1].plot(x, y2, 'b--')
axs[0, 1].set_title('余弦函數')
axs[0, 1].set_facecolor('#f0f0f0') ?# 設置背景色
?
# 繪制第三個子圖 (對數坐標)
axs[1, 0].semilogy(x, y4, 'g-')
axs[1, 0].set_title('指數函數(對數Y軸)')
axs[1, 0].set_xlabel('X軸')
?
# 繪制第四個子圖 (設置Y軸范圍)
axs[1, 1].plot(x, y3, 'm-.')
axs[1, 1].set_title('正切函數')
axs[1, 1].set_ylim(-5, 5) ?# 限制Y軸范圍
?
# 調整布局
plt.tight_layout(rect=[0, 0, 1, 0.96]) ?# 為總標題留空間
plt.show()
運行截圖:
方法二:GridSpec
(復雜布局)
適用場景:創建不規則大小的子圖
GridSpec
是 Matplotlib 中用于創建復雜、非均勻子圖布局的高級工具。它提供了比 plt.subplots()
更精細的控制,允許你定義不同大小的子圖、跨行列的子圖以及復雜的布局比例。
核心概念
GridSpec
通過定義一個網格系統來工作:
-
將整個圖形區域劃分為行和列的網格
-
允許子圖跨越多個網格單元
-
支持設置行和列的相對大小比例
基本語法:
from matplotlib.gridspec import GridSpec
?
# 創建 GridSpec 對象
gs = GridSpec(nrows, ? ? ? ? ? ? ?# 網格總行數ncols, ? ? ? ? ? ? ?# 網格總列數figure=None, ? ? ? ?# 關聯的 Figure 對象left=None, ? ? ? ? ?# 網格左側位置 (0-1)right=None, ? ? ? ? # 網格右側位置 (0-1)bottom=None, ? ? ? ?# 網格底部位置 (0-1)top=None, ? ? ? ? ? # 網格頂部位置 (0-1)wspace=None, ? ? ? ?# 列間距 (寬度比例)hspace=None, ? ? ? ?# 行間距 (高度比例)width_ratios=None, ?# 列寬度比例列表height_ratios=None, # 行高度比例列表
)
我們看一個示例:
import matplotlib.pyplot as plt
import numpy as np
?
from matplotlib.gridspec import GridSpec
?
# 設置中文字體支持
plt.rcParams['font.sans-serif'] = ['SimHei'] ?# 用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus'] = False ?# 用來正常顯示負號
?
# 生成數據
x = np.linspace(0, 2 * np.pi, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
y4 = np.exp(x / 8)
?
fig = plt.figure(figsize=(12, 8))
gs = GridSpec(3, 3, figure=fig) ?# 3×3網格
?
# 創建跨行列的子圖
ax1 = fig.add_subplot(gs[0, :]) ?# 首行全寬
ax2 = fig.add_subplot(gs[1, :-1]) ?# 第二行左側兩列
ax3 = fig.add_subplot(gs[1:, 2]) ?# 后兩行最右列
ax4 = fig.add_subplot(gs[2, 0]) ?# 第三行首列
ax5 = fig.add_subplot(gs[2, 1]) ?# 第三行第二列
?
# 填充子圖內容
ax1.plot(x, y1, color='tab:blue')
ax1.set_title('全寬標題區')
?
ax2.scatter(x, y2, c=y4, cmap='viridis')
ax2.set_title('散點圖(帶顏色映射)')
?
ax3.barh(x[:10], y4[:10], height=0.3)
ax3.set_title('橫向柱狀圖')
?
ax4.pie([15, 30, 45, 10], labels=['A', 'B', 'C', 'D'])
ax4.set_title('餅圖')
?
ax5.hist(np.random.randn(1000), bins=30)
ax5.set_title('直方圖')
?
plt.suptitle('GridSpec 不規則布局', fontsize=16)
plt.tight_layout()
plt.show()
運行截圖:
方法三:subplot2grid
(傳統方法)
適用場景:快速實現簡單不規則布局
subplot2grid()
是 Matplotlib 中用于創建復雜子圖布局的靈活方法,特別適合構建非均勻網格布局。它結合了 subplot()
的簡單性和 GridSpec
的靈活性,是創建自定義布局的高效工具。
核心概念
subplot2grid()
允許你:
-
定義一個網格系統(行和列)
-
指定子圖的起始位置(行索引和列索引)
-
設置子圖跨越的行數和列數
-
直接創建 Axes 對象
基本語法:
ax = plt.subplot2grid(shape, ? ? ? ? ?# 網格形狀 (行數, 列數)loc, ? ? ? ? ? ?# 子圖起始位置 (行索引, 列索引)rowspan=1, ? ? ?# 子圖跨越的行數(默認為1)colspan=1, ? ? ?# 子圖跨越的列數(默認為1)fig=None, ? ? ? # 關聯的Figure對象**kwargs ? ? ? ?# 其他Axes參數
)
我們看一個示例:
import matplotlib.pyplot as plt
import numpy as np
?
# 設置中文字體支持
plt.rcParams['font.sans-serif'] = ['SimHei'] ?# 用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus'] = False ?# 用來正常顯示負號
?
# 生成數據
x = np.linspace(0, 2 * np.pi, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
y4 = np.exp(x / 8)
?
plt.figure(figsize=(10, 6))
?
# 定義網格形狀 (3×3)
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=2)
ax2 = plt.subplot2grid((3, 3), (0, 2), rowspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 0))
ax4 = plt.subplot2grid((3, 3), (1, 1))
ax5 = plt.subplot2grid((3, 3), (2, 0), colspan=3)
?
# 填充內容
ax1.fill_between(x, y1, y2, alpha=0.3)
ax2.plot(x, y3, 'r--', linewidth=2)
ax3.scatter(x[::5], y4[::5], s=50)
ax4.boxplot([np.random.normal(0, std, 100) for std in range(1, 4)])
ax5.stackplot(x, y1, y2, labels=['sin', 'cos'])
?
# 添加圖例和標題
ax5.legend(loc='lower right')
plt.suptitle('subplot2grid 布局示例', fontsize=14)
plt.tight_layout()
plt.show()