Matplotlib 繪圖教程(3D)

一、實驗介紹

1.1 實驗內容

Matplotlib 是支持 Python 語言的開源繪圖庫,因爲其支持豐富的繪圖類型、簡單的繪圖方式以及完善的接口文檔,深受 Python 工程師、科研學者、數據工程師等各類人士的喜歡。這是 Matplotlib 繪圖課程的第 3 章節,將帶你瞭解 3D 圖像繪製。

1.2 實驗知識點

  • Matplotlib 繪製 3D 圖像

1.3 實驗環境

  • python2.7
  • Xfce 終端
  • ipython 終端

1.4 適合人羣

本課程難度爲一般,屬於初級級別課程,適合具有 Python 基礎,並對使用 Matplotlib 繪圖感興趣的用戶。

二、三維繪圖

2.1 mplot3d 繪圖模塊介紹

前面,我們已經瞭解瞭如果使用 Matplotlib 中的 pyplot 模塊繪製簡單的 2D 圖像。其實,Matplotlib 也可以繪製 3D 圖像,與二維圖像不同的是,繪製三維圖像主要通過 mplot3d 模塊實現。但是,使用 Matplotlib 繪製三維圖像實際上是在二維畫布上展示,所以一般繪製三維圖像時,同樣需要載入 pyplot 模塊。

mplot3d 模塊下主要包含 4 個大類,分別是:

  • mpl_toolkits.mplot3d.axes3d()
  • mpl_toolkits.mplot3d.axis3d()
  • mpl_toolkits.mplot3d.art3d()
  • mpl_toolkits.mplot3d.proj3d()

其中,axes3d() 下面主要包含了各種實現繪圖的類和方法。axis3d() 主要是包含了和座標軸相關的類和方法。art3d() 包含了一些可將 2D 圖像轉換並用於 3D 繪製的類和方法。proj3d() 中包含一些零碎的類和方法,例如計算三維向量長度等。

一般情況下,我們用到最多的就是 mpl_toolkits.mplot3d.axes3d() 下面的 mpl_toolkits.mplot3d.axes3d.Axes3D() 類,而 Axes3D() 下面又存在繪製不同類型 3D 圖的方法。你可以通過下面的方式導入 Axes3D()

from mpl_toolkits.mplot3d.axes3d import Axes3D

由於 Axes3D() 十分常用,所以 Matplotlib 支持更加方便地導入。

from mpl_toolkits.mplot3d import Axes3D

2.2 三維散點圖

接下來,通過一個簡單的例子,來看一看繪製三維圖像具體需要幾個步驟。代碼均在 ipython 終端執行,你可以通過在線環境左下角的應用程序菜單 > 附件打開。

首先,我們導入 numpy 隨機生成一組數據。

import numpy as np

# x, y, z 均爲 0 到 1 之間的 100 個隨機數
x = np.random.normal(0, 1, 100)
y = np.random.normal(0, 1, 100)
z = np.random.normal(0, 1, 100)

接下來,開始繪圖。第一步是載入 2D, 3D 繪圖模塊。

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

第二步,使用 Axes3D() 創建 3D 圖形對象。

fig = plt.figure()
ax = Axes3D(fig)

最後,調用散點圖繪製方法繪圖並顯示出來。

ax.scatter(x, y, z)

plt.show()

除開生成數據和模塊導入,實際上只用了 4 行短小的代碼就繪製出了一幅三維散點圖像。

此處輸入圖片的描述

你可以通過鼠標拖動圖像,從不同的視角查看該 3D 圖像。

2.3 三維線型圖

線形圖和散點圖相似,需要傳入 x, y, z 三個座標的數值。詳細的代碼如下。

# 載入模塊
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

# 生成數據
x = np.linspace(-6 * np.pi, 6 * np.pi, 1000)
y = np.sin(x)
z = np.cos(x)

# 創建 3D 圖形對象
fig = plt.figure()
ax = Axes3D(fig)

# 繪製線型圖
ax.plot(x, y, z)

# 顯示圖
plt.show()

此處輸入圖片的描述

2.4 三維柱狀圖

繪製完線型圖,我們繼續嘗試繪製三維柱狀圖,其實它的繪製步驟和上面同樣非常相似。

# 載入模塊
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

# 創建 3D 圖形對象
fig = plt.figure()
ax = Axes3D(fig)

# 生成數據並繪圖
x = [0, 1, 2, 3, 4, 5, 6]
for i in x:
    y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    z = abs(np.random.normal(1, 10, 10))
    ax.bar(y, z, i, zdir='y', color=['r', 'g', 'b', 'y'])

plt.show()

這裏在 ipython 終端中輸入時,注意代碼的縮進。

此處輸入圖片的描述

2.5 三維圖曲面圖

接下來需要繪製的三維曲面圖要麻煩一些,我們需要對數據進行矩陣處理。其實和畫二維等高線圖很相似,只是多增加了一個維度。

# 載入模塊
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# 創建 3D 圖形對象
fig = plt.figure()
ax = Axes3D(fig)

# 生成數據
X = np.arange(-2, 2, 0.1)
Y = np.arange(-2, 2, 0.1)
X, Y = np.meshgrid(X, Y)
Z = np.sqrt(X ** 2 + Y ** 2)

# 繪製曲面圖,並使用 cmap 着色
ax.plot_surface(X, Y, Z, cmap=plt.cm.winter)

plt.show()

cmap=plt.cm.winter 表示採用了 winter 配色方案,也就是下圖的漸變色。

此處輸入圖片的描述

2.6 混合圖繪製

混合圖就是將兩種不同類型的圖繪製在一張圖裏。繪製混合圖一般有前提條件,那就是兩種不同類型圖的範圍大致相同,否則將會出現嚴重的比例不協調,而使得混合圖失去意義。

# -*- coding: utf-8 -*
# 載入模塊
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

# 創建 3D 圖形對象
fig = plt.figure()
ax = Axes3D(fig)

# 生成數據並繪製圖 1
x1 = np.linspace(-3 * np.pi, 3 * np.pi, 500)
y1 = np.sin(x1)
ax.plot(x1, y1, zs=0, c='red')

# 生成數據並繪製圖 2
x2 = np.random.normal(0, 1, 100)
y2 = np.random.normal(0, 1, 100)
z2 = np.random.normal(0, 1, 100)
ax.scatter(x2, y2, z2)

# 顯示圖
plt.show()

此處輸入圖片的描述

2.7 子圖繪製

前面的章節已經介紹了二維子圖的繪製,其實三維情況下也是一樣的。我們可以將二維圖像和三維圖像繪製在一起,又或者將幾個三維圖像繪製在一起。

這裏我們就拿上面繪製過的線形圖和曲面圖爲例,看一看需要增刪哪些代碼。

# -*- coding: utf-8 -*
# 載入模塊
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

# 創建 1 張畫布
fig = plt.figure()

#===============

# 向畫布添加子圖 1 
ax1 = fig.add_subplot(1, 2, 1, projection='3d')

# 生成子圖 1 數據
x = np.linspace(-6 * np.pi, 6 * np.pi, 1000)
y = np.sin(x)
z = np.cos(x)

# 繪製第 1 張圖
ax1.plot(x, y, z)

#===============

# 向畫布添加子圖 2
ax2 = fig.add_subplot(1, 2, 2, projection='3d')

# 生成子圖 2 數據
X = np.arange(-2, 2, 0.1)
Y = np.arange(-2, 2, 0.1)
X, Y = np.meshgrid(X, Y)
Z = np.sqrt(X ** 2 + Y ** 2)

# 繪製第 2 張圖
ax2.plot_surface(X, Y, Z, cmap=plt.cm.winter)

# 顯示圖
plt.show()

我們可以來看一下這些代碼。由於兩張子圖是繪製在 1 張畫布上面的,所以這裏需要提前創建 1 張畫布。然後通過 .add_subplot() 添加子圖,子圖序號和二維繪圖相似,只是注意 3D 繪圖時要添加 projection='3d' 參數。

此處輸入圖片的描述

三、實驗總結

本次實驗主要是學會如果使用 Matplotlib 完成簡單的 3D 繪圖。你會發現,三維繪圖其實就是在二維繪圖上的演變。二者的區別重點在兩個方面,首先需要建一個了三維畫布,其次需要多輸入一個維度值,即 z 值。

在 Matplotlib 中,它們之間會共享一些參數。例如,當你在三維空間中繪製線型圖時,二維圖中對線的顏色、粗細、標記點的樣式等參數均可直接使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章