來源 | 「Practical Python Data Visualization A Fast Track Approach To Learning Data Visualization With Python」
作者 | Ashwin Pajankar
譯者 | Liangchu
校對 | gongyouliu
編輯 | auroral-L
全文共4220字,預計閱讀時間20分鐘。
一、圖像可視化
二、操作圖像
三、三維(3D)可視化
❤總結
在第五章 「使用NumPy和Matplotlib進行數據可視化」中,我們開始使用Python 3中的Matplotlib庫進行可視化。在本章中,我們將繼續學習Matplotlib和NumPy來可視化圖像和三維形狀(3D shape)。本章將學習以下內容繼續探索數據可視化:
本章結束後,你將能夠處理圖像和三維形狀。
一、圖像可視化在本節中,我們將學習如何可視化圖像。首先,我們為本章創建一個新筆記本。Matplotlib的函數imread()可以讀取.png文件格式的圖像,要使它能夠讀取其他格式的文件,我們必須安裝另一個名為pillow的圖像處理庫。通過在筆記本單元格中運行以下命令進行安裝:
!pip3 install pillow
使用我們在第5章中學習的命令使筆記本能夠內聯顯示Matplotlib可視化輸出:
%matplotlib inline
使用以下命令導入Matplotlib的Pyplot模塊:
import matplotlib.pyplot as plt
現在,讓我們使用函數imread()將圖像讀入,以作為變量,如下所示:
img1 = plt.imread('D:\\Dataset\\4.1.02.tiff')
如果你使用的是Linux、Unix或MacOS計算機,則需要改變一下文件路徑,使用以下約定:
img1 = plt.imread('/home/pi/book/dataset/4.1.02.tiff')
你使用的路徑必須是絕對路徑。如果該圖像文件與程序位於同一目錄中,則僅寫文件名就可以了。
此函數讀取圖像並將其作為數值矩陣存儲在NumPy ndarray中。我們可以通過運行以下代碼行來驗證這一點:
print(type(img1))
輸出如下:
<class 'numpy.ndarray'>
這證實了科學Python庫將圖像處理為NumPy ndarray的形式。
我們可以使用Matplotlib的imshow()函數顯示該ndarray對應的圖像,然後使用show()函數將其顯示為圖形進行輸出,如下所示:
plt.imshow(img1)plt.show()
輸出如圖(6-1)所示:
可以按如下方式關閉軸:
plt.imshow(img1)
plt.axis(False)
plt.show()
注意:我用於演示的所有圖像都是從
http://www.imageprocessingplace.com/rootfilesV3/image_databases.htm中下載的。
讓我們讀一個灰度圖像(grayscale image)(灰度數字圖像是每個像素只有一個採樣顏色的圖像。這類圖像通常顯示為從最暗黑色到最亮的白色的灰度。灰度圖像與黑白圖像不同,在計算機圖像領域中黑白圖像只有黑白兩種顏色,灰度圖像把白色與黑色之間按對數關係分為若干等級,稱為灰度。灰度分為256階。),如下所示:
img2 = plt.imread('D:\\Dataset\\5.3.01.tiff')
我們可以使用以下代碼顯示它:
plt.imshow(img2)
plt.axis(False)
plt.show()
如圖(6-2)顯示了輸出:
如你所見,顏色看起來有點奇怪——這根本不是一個彩色圖像!Matplotlib使用默認顏色映射(color map)顯示灰度圖像。我們可以顯式地指定灰度圖來正確地可視化此圖像,如下所示:
plt.imshow(img2, cmap=plt.cm.gray)
plt.axis(False)
plt.show()
結果如圖(6-3)所示:
我們還可以按以下方式指示顏色映射:
plt.imshow(img2, cmap='gray')
plt.axis(False)
plt.show()
接下來我們將討論在圖像上的基本操作。
二、操作圖像我們可以使用NumPy對圖像執行基本操作,並使用Matplotlib進行可視化輸出。首先讓我們了解一些算術運算,我們需要兩幅尺寸相同的圖像來進行算術運算。讓我們讀取另一個彩色圖像,代碼如下:
img3 = plt.imread('D:\\Dataset\\4.1.03.tiff')
我們可以將其可視化如下:
plt.imshow(img3)plt.axis(False)plt.show()
如圖(6-4)顯示了輸出:
我們可以將兩幅圖片相加,並且將它們可視化,代碼如下:
add = img1+img3
plt.imshow(add)
plt.axis(False)
plt.show()
如圖(6-5)顯示了輸出:
加法運算是一種可交換(排列次序不影響結果)的算術運算,這意味著如果我們改變操作數的順序,它將不會影響輸出:
add1 = img3+img1
plt.imshow(add)
plt.axis(False)
plt.show()
再來試試減法運算:
sub1= img1-img3
plt.imshow(sub1)
plt.axis(False)
plt.show()
如圖(6-6)顯示了輸出:
我們知道減法運算是不可交換的,這意味著如果我們改變操作數的順序,那麼結果就不同了。讓我們試一下:
sub1 = img3-img1
plt.imshow(sub1)
plt.axis(False)
plt.show()
因此,如下圖(6-7)所示的輸出與上圖(6-6)的輸出不同:
我們知道圖像在SciPy中表示為NumPy ndarray。彩色圖像和灰度圖像的區別在於彩色圖像是由多個通道(channel)組成的,這些通道本身就是ndarrays。利用NumPy中的索引技術,我們可以對彩色圖像進行分割,並對組成通道分別進行可視化。彩色圖像的紅色、綠色和藍色各有一個通道。可以使用NumPy索引拆分圖像,如下所示:
r = img3[:, :, 0]
g = img3[:, :, 1]
b = img3[:, :, 2]
讓我們使用Matplotlib中的子圖(subplot)可視化原始圖像和顏色通道:
plt.subplots_adjust(hspace=0.4, wspace=0.1)
plt.subplot(2, 2, 1)
plt.title('Original')
plt.imshow(img3)
plt.subplot(2, 2, 2)
plt.title('Red')
plt.imshow(r, cmap='gray')
plt.subplot(2, 2, 3)
plt.title('Green')
plt.imshow(g, cmap='gray')
plt.subplot(2, 2, 4)
plt.title('Blue')
plt.imshow(b, cmap='gray')
plt.show()
讓我們檢查一下前面的代碼。你正在使用函數subplot()創建一個2×2的網格。函數subplots_adjust()被用於調整可視化之間的距離。2×2網格中的左上角位置為1,它在同一行中的相鄰位置為2,依此類推。右下角的位置是第四個位置。在函數subplot()之前使用imshow()或plot(),我們可以決定可視化的絕對位置。輸出如圖(6-8)所示:
顏色通道本身就是2D矩陣,對於彩色圖像的8位無符號整數表示格式來說,其成員的值從0到256不等。當它們組合在一起時,Matplotlib將它們解釋為彩色圖像。我們可以使用適當的顏色映射將其可視化,如下所示:
plt.subplots_adjust(hspace=0.4, wspace=0.1)
plt.subplot(2, 2, 1)
plt.title('Original')plt.imshow(img3)
plt.subplot(2, 2, 2)
plt.title('Red')
plt.imshow(r, cmap='Reds')
plt.subplot(2, 2, 3)
plt.title('Green')
plt.imshow(g, cmap='Greens')
plt.subplot(2, 2, 4)
plt.title('Blue')
plt.imshow(b, cmap='Blues')
plt.show()
輸出如圖(6-9)所示:
我們可以使用以下代碼來組合組成通道以形成原始圖像:
import numpy as npimg4 = np.dstack((r, g, b))
我們正在使用NumPy庫中的函數dstack(),我們可以用一般的代碼將輸出可視化:
plt.imshow(img4)
plt.axis(False)plt.show()
上面講了如何執行非常基本的圖像處理操作,比起我們上面所學的,還有更多更複雜的圖像處理操作,如果要進行進一步的演示與學習,就需要使用一本單獨的書來講解了。
三、三維(3D)可視化在本節中,我們將研究Python 3的三維可視化。到目前為止,我們一直在筆記本本中展示可視化效果,這個過程很適合二維(2D)可視化,然而,在三維可視化的情況下,它只能以固定的角度來顯示。因此,我們必須使用另一種方法來進行三維可視化,最好的方法是使用另一個特別神奇的命令,在單獨的Qt窗口中顯示可視化效果,如下所示:
%matplotlib qt
我們已經在前面的單元格中導入了Matplotlib和NumPy中的pyplot模塊(假設你在整個章節中使用的是相同的筆記本)。我們必須使用以下語句導入更多功能:
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d import axes3d
讓我們按照從易到難的順序學習三維可視化。我們已經了解了如何繪製簡單的繪圖,所以現在我們將在3D中執行相同的操作。從簡單的參數曲線開始。首先定義圖形和軸:
fig = plt.figure()
ax = fig.gca(projection='3d')
對於三維可視化,我們使用參數和參數對projection='3D'啟用了三維投影。接下來定義數據,需要數據點的x、y和z坐標。首先定義數據點的極坐標如下:
theta = np.linspace(-3 * np.pi, 3 * np.pi, 200)
z = np.linspace(-3, 3, 200)
r = z**3 + 1
現在,計算x和y坐標如下:
x = r * np.sin(theta)
y = r * np.cos(theta)
我們使用NumPy庫中的三角函數來計算x和y。最後,讓我們繪製如下:
ax.plot(x, y, z, label='Parametric Curve')
ax.legend()
plt.show()
如圖(6-10)所示,輸出將顯示在一個單獨的窗口中,它將以一種我們能夠改變視角的方式進行交互:
注意:如果沒有彈出單獨的輸出窗口,並且瀏覽器本身顯示了三維可視化效果,則必須重新啟動Jupyter內核並重新執行相關單元格。在這種情況下,不要執行包含%matplotlib inline的單元格。
接下來,讓我們創建一個三維條形圖。現在計算數據如下:
x = np.arange(4)
y = np.arange(4)
xx, yy = np.meshgrid(x, y)
print(xx);print(yy)
函數meshgrid()根據坐標向量創建並返回坐標矩陣,如下所示:
[[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]
[[0 0 0 0]
[1 1 1 1]
[2 2 2 2]
[3 3 3 3]]
然後使用函數ravel()將兩個矩陣展平,如下所示:
X, Y = xx.ravel(), yy.ravel()
print(X); print(Y);
這將產生以下輸出:
[0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3]
[0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3]
現在,計算更多值:
top = X + Y
bottom = np.zeros_like(top)
width = depth = 1
接下來,創建一個圖形和軸,並創建條形圖,如下所示:
fig = plt.figure(figsize=(8, 3))
ax1 = fig.add_subplot(121, projection='3d')
ax2 = fig.add_subplot(122, projection='3d')
ax1.bar3d(X, Y, bottom, width, depth, top, shade=True)
ax1.set_title('Shaded')
ax2.bar3d(X, Y, bottom, width, depth, top, shade=False)
ax2.set_title('Not Shaded')plt.show()
這將產生如圖(6-11)所示的條形圖:
接下來讓我們將線框可視化如下:
fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y, Z = axes3d.get_test_data(delta=0.1)
ax.plot_wireframe(X, Y, Z)
plt.show()
在這個代碼段中,我們首先在三維模式下創建一個圖形和一個軸,然後,內置函數get_test_data()返回測試數據,接下來我們使用函數plot_wireframe()來繪製線框模型。輸出如圖(6-12)所示:
最後,讓我們計算並可視化一個曲面。首先,計算x和y坐標,然後計算網格:
x = np.arange(-3, 3, 0.09)
y = np.arange(-3, 3, 0.09)
X, Y = np.meshgrid(x, y)
print(X); print(Y)
輸出如下所示:
[[-3. -2.91 -2.82 ... 2.76 2.85 2.94]
[-3. -2.91 -2.82 ... 2.76 2.85 2.94]
[-3. -2.91 -2.82 ... 2.76 2.85 2.94]
...
[-3. -2.91 -2.82 ... 2.76 2.85 2.94]
[-3. -2.91 -2.82 ... 2.76 2.85 2.94]
[-3. -2.91 -2.82 ... 2.76 2.85 2.94]]
[[-3. -3. -3. ... -3. -3. -3. ]
[-2.91 -2.91 -2.91 ... -2.91 -2.91 -2.91]
[-2.82 -2.82 -2.82 ... -2.82 -2.82 -2.82]
...
[ 2.76 2.76 2.76 ... 2.76 2.76 2.76]
[ 2.85 2.85 2.85 ... 2.85 2.85 2.85]
[ 2.94 2.94 2.94 ... 2.94 2.94 2.94]]
接下來,計算z坐標,如下所示:
R = np.sqrt(X**2 + Y**2)
Z = np.cos(R)
print(Z)
最後,創建圖形和軸,並可視化三維曲面:
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, Z,
cmap=plt.cm.cool,
linewidth=0,
antialiased=False)
plt.show()
這將產生如圖(6-13)所示的輸出:
在本章中,你學習並演示了圖像可視化,你還了解並演示了圖像的基本操作,如算術運算和將彩色圖像拆分為組成通道。我們還討論了如何編寫三維可視化程序,包括曲線、條形圖、線框和網格。
下一章將探討如何可視化網絡和圖形數據結構。