python如何用matplotlib創(chuàng)建三維圖表
Matplotlib 最開(kāi)始被設(shè)計(jì)為僅支持二維的圖表。到 1.0 版本發(fā)布左右,一些三維圖表的工具在二維展示的基礎(chǔ)上被創(chuàng)建了出來(lái),結(jié)果就是 Matplotlib 提供了一個(gè)方便的(同時(shí)也是有限的)的可用于三維數(shù)據(jù)可視化的一套工具。三維圖表可以使用載入mplot3d工具包來(lái)激活,這個(gè)包會(huì)隨著 Matplotlib 自動(dòng)安裝:
from mpl_toolkits import mplot3d
一旦模塊被導(dǎo)入,三維 axes 就可以像其他普通 axes 一樣通過(guò)關(guān)鍵字參數(shù)projection='3d'來(lái)創(chuàng)建:
import numpy as np import matplotlib.pyplot as plt
fig = plt.figure() ax = plt.axes(projection='3d') plt.show()
三維 axes 激活后,我們可以在上面繪制不同的三維圖表類型。三維圖表在 notebook 中使用交互式圖表展示會(huì)優(yōu)于使用靜態(tài)展示;回憶我們前面介紹過(guò),你可以使用%matplotlib notebook而不是%matplotlib inline來(lái)激活交互式展示模式。
三維的點(diǎn)和線
三維圖表中最基礎(chǔ)的是使用(x, y, z)坐標(biāo)定義的一根線或散點(diǎn)的集合。前面介紹過(guò)普通的二維圖表,作為類比,使用ax.plot3D和ax.scatter3D函數(shù)可以創(chuàng)建三維折線和散點(diǎn)圖。這兩個(gè)函數(shù)的簽名與二維的版本基本一致,你可以參考[簡(jiǎn)單折線圖]和[簡(jiǎn)單散點(diǎn)圖]來(lái)復(fù)習(xí)一下這部分的內(nèi)容。下面我們繪制一個(gè)三維中的三角螺旋,在線的附近在繪制一些隨機(jī)的點(diǎn):
ax = plt.axes(projection='3d') # 三維螺旋線的數(shù)據(jù) zline = np.linspace(0, 15, 1000) xline = np.sin(zline) yline = np.cos(zline) ax.plot3D(xline, yline, zline, 'gray') # 三維散點(diǎn)的數(shù)據(jù) zdata = 15 * np.random.random(100) xdata = np.sin(zdata) + 0.1 * np.random.randn(100) ydata = np.cos(zdata) + 0.1 * np.random.randn(100) ax.scatter3D(xdata, ydata, zdata, c=zdata, cmap='Greens');
注意默認(rèn)情況下,圖中的散點(diǎn)會(huì)有透明度的區(qū)別,用于體現(xiàn)在圖中散點(diǎn)的深度。雖然三維效果在靜態(tài)圖像中難以顯示,你可以使用交互式的視圖來(lái)獲得更佳的三維直觀效果。
三維輪廓圖
類似于我們?cè)赱密度和輪廓圖]中介紹的內(nèi)容,mplot3d也包含著能夠創(chuàng)建三維浮雕圖像的工具。就像二維的ax.contour圖表,ax.contour3D要求輸入數(shù)據(jù)的格式是二維普通網(wǎng)格上計(jì)算得到的 Z 軸的數(shù)據(jù)值。下面我們展示一個(gè)三維的正弦函數(shù)輪廓圖:
def f(x, y): return np.sin(np.sqrt(x ** 2 + y ** 2)) x = np.linspace(-6, 6, 30) y = np.linspace(-6, 6, 30) X, Y = np.meshgrid(x, y) Z = f(X, Y)
fig = plt.figure() ax = plt.axes(projection='3d') ax.contour3D(X, Y, Z, 50, cmap='binary') ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z');
有時(shí)候默認(rèn)的視角角度不是最理想的,在這種情況下我們可以使用view_init函數(shù)來(lái)設(shè)置水平角和方位角。在下面的例子中,我們使用的是 60° 的水平角(即以 60° 俯視 x-y 平面)和 35° 的方位角(即將 z 軸逆時(shí)針旋轉(zhuǎn) 35°):
ax.view_init(60, 35) fig
同樣,注意到當(dāng)使用 Matplotlib 交互式展示是,這樣的旋轉(zhuǎn)可以通過(guò)鼠標(biāo)點(diǎn)擊和拖拽來(lái)實(shí)現(xiàn)。
框線圖和表面圖
使用網(wǎng)格數(shù)據(jù)生成的三維圖表還有框線圖和表面圖。這兩種圖表將網(wǎng)格數(shù)據(jù)投射到特定的三維表面,能夠使得結(jié)果圖像非常直觀和具有說(shuō)服力。下面是一個(gè)框線圖的例子:
fig = plt.figure() ax = plt.axes(projection='3d') ax.plot_wireframe(X, Y, Z, color='black') ax.set_title('wireframe');
表面圖類似框線圖,區(qū)別在于每個(gè)框線構(gòu)成的多邊形都使用顏色進(jìn)行了填充。添加色圖用于填充多邊形能夠讓圖形表面展示出來(lái):
ax = plt.axes(projection='3d') ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis', edgecolor='none') ax.set_title('surface');
注意雖然每個(gè)顏色填充的表面都是二維的,但是表面的邊緣不需要是直線構(gòu)成的。下面的例子使用surface3D繪制了一個(gè)部分極坐標(biāo)網(wǎng)格,能夠讓我們切入到函數(shù)內(nèi)部觀察效果:
r = np.linspace(0, 6, 20) theta = np.linspace(-0.9 * np.pi, 0.8 * np.pi, 40) r, theta = np.meshgrid(r, theta) X = r * np.sin(theta) Y = r * np.cos(theta) Z = f(X, Y) ax = plt.axes(projection='3d') ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis', edgecolor='none');
表面三角剖分
在一些應(yīng)用場(chǎng)合中,上面的這種均勻網(wǎng)格繪制的圖表方式太過(guò)于局限和不方便。在這些情況下,三角剖分的圖表可以派上用場(chǎng)。如果我們并不是使用笛卡爾坐標(biāo)系或極坐標(biāo)系的網(wǎng)格來(lái)繪制三維圖表,而是使用一組隨機(jī)的點(diǎn)來(lái)繪制三維圖表呢?
theta = 2 * np.pi * np.random.random(1000) r = 6 * np.random.random(1000) x = np.ravel(r * np.sin(theta)) y = np.ravel(r * np.cos(theta)) z = f(x, y)
ax = plt.axes(projection='3d') ax.scatter(x, y, z, c=z, cmap='viridis', linewidth=0.5);
上圖并未形象的表示出表面情況。這種情況下我們可以使用ax.plot_trisurf函數(shù),它能首先根據(jù)我們的數(shù)據(jù)輸入找到各點(diǎn)內(nèi)在的三角函數(shù)形式,然后繪制表面(注意的是這里的 x,y,z 是一維的數(shù)組):
ax = plt.axes(projection='3d') ax.plot_trisurf(x, y, z, cmap='viridis', edgecolor='none');
上圖的結(jié)果很顯然沒(méi)有使用網(wǎng)格繪制表面圖那么清晰,但是對(duì)于我們并不是使用函數(shù)構(gòu)建數(shù)據(jù)樣本(數(shù)據(jù)樣本通常來(lái)自真實(shí)世界的采樣)的情況下,這能提供很大的幫助。例如我們下面會(huì)看到,能使用這種方法繪制一條三維的莫比烏斯環(huán)。
例子:繪制莫比烏斯環(huán)
theta = np.linspace(0, 2 * np.pi, 30) w = np.linspace(-0.25, 0.25, 8) w, theta = np.meshgrid(w, theta)
phi = 0.5 * theta
現(xiàn)在我們已經(jīng)有了所有需要獲得三維坐標(biāo)值的參數(shù)了。我們定義 為每個(gè)坐標(biāo)點(diǎn)距離環(huán)形中間的位置,使用它來(lái)計(jì)算最終(x,y,z) 三維坐標(biāo)系的坐標(biāo)值:
# r是坐標(biāo)點(diǎn)距離環(huán)形中心的距離值 r = 1 + w * np.cos(phi) # 利用簡(jiǎn)單的三角函數(shù)知識(shí)算得x,y,z坐標(biāo)值 x = np.ravel(r * np.cos(theta)) y = np.ravel(r * np.sin(theta)) z = np.ravel(w * np.sin(phi))
最后,為了繪制對(duì)象,我們必須保證三角剖分是正確的。實(shí)現(xiàn)這個(gè)最好的方法是在底層的參數(shù)上面實(shí)現(xiàn)三角剖分,最后讓 Matplotlib 將這個(gè)三角剖分投射到三維空間中形成莫比烏斯環(huán)。下面的代碼最終繪制圖形:
# 在底層參數(shù)的基礎(chǔ)上進(jìn)行三角剖分 from matplotlib.tri import Triangulation tri = Triangulation(np.ravel(w), np.ravel(theta)) ax = plt.axes(projection='3d') ax.plot_trisurf(x, y, z, triangles=tri.triangles, cmap='viridis', linewidths=0.2); ax.set_xlim(-1, 1); ax.set_ylim(-1, 1); ax.set_zlim(-1, 1);
結(jié)合這些技巧,能夠?yàn)槟闾峁┰?Matplotlib 創(chuàng)建和展現(xiàn)大量三維對(duì)象和模式的能力。
以上就是python如何用matplotlib創(chuàng)建三維圖表的詳細(xì)內(nèi)容,更多關(guān)于python用matplotlib創(chuàng)建三維圖表的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python如何將LabelMe生成的JSON格式轉(zhuǎn)換成YOLOv8支持的TXT格式
標(biāo)注工具 LabelMe 生成的標(biāo)注文件為JSON格式,而YOLOv8中支持的為TXT文件格式,下面給大家分享Python如何將LabelMe生成的JSON格式轉(zhuǎn)換成YOLOv8支持的TXT格式,感興趣的朋友跟隨小編一起看看吧2024-05-05Python3中FuzzyWuzzy庫(kù)實(shí)例用法
在本篇文章中小編給各位整理了關(guān)于Python3z中FuzzyWuzzy庫(kù)實(shí)例用法及相關(guān)代碼,有興趣的朋友們可以參考下。2020-11-11tensorflow實(shí)現(xiàn)將ckpt轉(zhuǎn)pb文件的方法
這篇文章主要介紹了tensorflow實(shí)現(xiàn)將ckpt轉(zhuǎn)pb文件的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04Python 列表中的修改、添加和刪除元素的實(shí)現(xiàn)
這篇文章主要介紹了Python 列表中的修改、添加和刪除元素的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06python opencv 二值化 計(jì)算白色像素點(diǎn)的實(shí)例
今天小編就為大家分享一篇python opencv 二值化 計(jì)算白色像素點(diǎn)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07分享Python開(kāi)發(fā)中要注意的十個(gè)小貼士
不管是python開(kāi)發(fā)還是其他什么語(yǔ)言的開(kāi)發(fā),如果在開(kāi)發(fā)中我們能掌握一些有用的貼士和技巧,那么肯定會(huì)大大提高我們的開(kāi)發(fā)效率,今天小編和大家分享的就是python開(kāi)發(fā)中,一些初學(xué)這門語(yǔ)言常常會(huì)犯的錯(cuò)誤,一起來(lái)看看吧。2016-08-08Python使用asyncio包處理并發(fā)的實(shí)現(xiàn)代碼
這篇文章主要介紹了Python使用asyncio包處理并發(fā),asyncio包使用事件循環(huán)驅(qū)動(dòng)的協(xié)程實(shí)現(xiàn)并發(fā),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì)對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12