有些情況下,我們需要在二維圖表中使用輪廓或顏色區域來展示三維的數據(可以設想等高線地圖或溫度分布圖)。Matplotlib 提供了三個有用的函數來處理這項任務:plt.contour
繪制輪廓圖,plt.contourf
來繪制填充區域顏色的圖表以及plt.imshow
來展示圖像。本節會介紹幾個使用它們的例子。當然我們還是首先從將需要使用的包導入 notebook 和初始化工作開始:
import matplotlib.pyplot as plt plt.style.use('seaborn-white') import numpy as np
三維可視化函數
我們首先使用一個簡單的函數 繪制一個輪廓圖來進行說明,我們用來作為數組廣播運算的例子:
def f(x, y): return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
輪廓圖可以使用plt.contour
函數進行創建。它接收三個參數:x參數代表三維網格的平面橫軸坐標,y參數代表三維網格的平面縱軸坐標,而z參數代表三維網格的高度坐標。最容易用來准備這種網格數據的是np.meshgrid
函數,可以將兩個一維的數組構造成一個二維的網格:
x = np.linspace(0, 5, 50) y = np.linspace(0, 5, 40) X, Y = np.meshgrid(x, y) Z = f(X, Y)
下面我們可以繪制標准的輪廓線圖表:
plt.contour(X, Y, Z, colors='black');
總代碼如下:
import matplotlib.pyplot as plt plt.style.use('seaborn-white') import numpy as np def f(x, y): return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x) x = np.linspace(0, 5, 50) y = np.linspace(0, 5, 40) X, Y = np.meshgrid(x, y) Z = f(X, Y) plt.contour(X, Y, Z, colors='black'); plt.show()
圖中值得注意的是,當使用單色繪制輪廓圖時,虛線代表的是負數的數值,而實線代表的是正數。而輪廓線可以通過指定cmap
參數來設置線條的色圖。下例中展示了使用色圖且繪制了更多的輪廓線的例子,會在整個數據范圍區域內等距分布有 20 條輪廓線:
plt.contour(X, Y, Z, 20, cmap='RdGy');
上例中我們選擇了RdGy
(Red-Gray的縮寫)色圖,這對於聚集的數據來說是一個不錯的選擇。Matplotlib 有大量的顏色圖可供使用,你可以通過在 IPython 中對plt.cm
模塊使用 TAB 自動補全方法就可以看到:
plt.cm.<TAB>
上面的圖看起來比第一幅圖好多了,但是線條之間的空隙還是有點讓人混淆。我們可以將上面的圖改為填充輪廓圖來解決這個問題,使用plt.contourf()
函數(注意函數名最后有個 f,代表填充 fill),這個函數的語法基本上與plt.contour()
保持一致。
並且我們加上了plt.colorbar()
函數,這個函數會在圖表邊上創建一個顏色圖例用以展示顏色所表示的數值區域:
有了圖例,很容易可以看出黑色區域代表着“峰”,而紅色區域代表這“谷”。
上圖有一個缺點,那就是圖中顏色的階梯是離散的而不是連續的,這通常不是我們想要的。我們可以通過設置很高的輪廓線數量來改善,但是這會導致繪制圖表的性能降低:Matplotlib 必須在每個顏色階梯上繪制一條新的輪廓多邊形。更好的辦法是使用plt.imshow()
函數,它會將一個二維的網格圖表轉換為一張圖像。
下面的例子展示了該方法:
plt.imshow(Z, extent=[0, 5, 0, 5], origin='lower', cmap='RdGy') plt.colorbar() #plt.axis(aspect='image');
然而,在使用imshow()
的時候也有一些坑:
plt.imshow()
不接受 x 和 y 網格值作為參數,因此你需要手動指定extent參數[xmin, xmax, ymin, ymax]來設置圖表的數據范圍。plt.imshow()
使用的是默認的圖像坐標,即左上角坐標點是原點,而不是通常圖表的左下角坐標點。這可以通過設置origin
參數來設置。plt.imshow()
會自動根據輸入數據調整坐標軸的比例;這可以通過參數來設置,例如,plt.axis(aspect='image')
能讓 x 和 y 軸的單位一致。
最后,有時可能需要將輪廓圖和圖像結合起來。例如,下例中我們使用了半透明的背景圖像(通過alpha
參數設置透明度),然后在背景圖層之上繪制了輪廓圖,並帶有每個輪廓的數值標簽(使用plt.clabel()
函數繪制標簽):
contours = plt.contour(X, Y, Z, 3, colors='black') plt.clabel(contours, inline=True, fontsize=8) plt.imshow(Z, extent=[0, 5, 0, 5], origin='lower', cmap='RdGy', alpha=0.5) plt.colorbar();
通過組合使用plt.contour
、plt.contourf
和plt.imshow
這三個函數,基本可以滿足我們繪制所有這種在二維圖標上的三維數據的需求。需要了解更多函數的參數信息,參考它們的文檔字符串。如果你對於使用三維圖表展示這種數據感興趣,參見[在 matplotlib 中創建三維圖表]。