首頁>技術>

導讀:Matplotlib是建立在NumPy陣列上的一個多平臺資料視覺化庫。在2002年,約翰·亨特(John Hunter)提出Matplotlib,最初的構思是設計為IPython的一個補丁,以便能夠從命令列啟用互動式MATLAB樣式繪圖。

近幾年,更新、更炫酷的工具(例如,R語言中的ggplot和ggvis)層出不窮,最終取代了Matplotlib,可是Matplotlib仍然是一個經過良好測試的、非常重要的跨平臺圖形引擎。

01 匯入Matplotlib

如果你安裝了完整的Python Anaconda,那麼你已經安裝了Matplotlib,可以開始了。否則,你可能要訪問官網獲取安裝說明。

http://matplotlib.org

就像我們用縮寫np來表示NumPy一樣,我們也會用一些標準的縮寫來表示Matplotlib匯入:

import matplotlib as mplimport matplotlib.pyplot as plt

plt是我們最常用的一個介面。

02 生成一個簡單的圖形

言歸正傳,讓我們建立第一個圖形。

假設我們要繪製正弦函式sin(x)的一個簡單線圖。我們希望函式求x軸(0≤x≤10)上的所有值。我們將使用NumPy的linspace函式在x軸上建立一個線性空間,x值從0到10,共100個樣本點:

import numpy as npx = np.linspace(0, 10, 100)

我們可以使用NumPy的sin函式求sin函式的所有x值,並透過呼叫plt的plot函式視覺化結果:

plt.plot(x, np.sin(x))

你親自試過了嗎?發生什麼了?有什麼發現嗎?

問題是,這取決於你在何處執行這個指令碼,你可能什麼都看不到。以下是可以考慮的可能性:

1. 從.py指令碼繪圖

如果你正從一個指令碼執行matplotlib,那麼你只需要呼叫plt,如下所示:

plt.show()

呼叫後,圖形就會顯示出來!

2. 從IPython shell繪圖

這實際上是以互動方式執行matplotlib的最便捷的方式之一。要顯示繪圖,你需要在啟動IPython之後,呼叫%matplotlib魔術命令:

%matplotlibUsing matplotlib backend: Qt5Agg
import matplotlib.pyplot as plt

然後,所有圖都會自動顯示出來,不必每次都呼叫plt.show()。

3. 從Jupyter Notebook繪圖

如果你從基於瀏覽器的Jupyter Notebook上檢視這段程式碼,你需要使用同樣的%matplotlib魔術命令。可是,你還可以選擇將圖形直接嵌入notebook中,這有兩種可能的結果:

%matplotlib notebook將生成的互動式圖嵌入notebook中。%matplotlib inline將生成的靜態圖嵌入notebook中。

我們通常會選擇內聯選項:

%matplotlib inline

現在,讓我們再試一次:

plt.plot(x, np.sin(x))

上述命令給出的輸出如圖2-4所示。

▲圖2-4 應用內聯選項生成的圖

稍後,如果你想儲存圖表,可以直接從IPython或Jupyter Notebook的選項中儲存:

plt.savefig('figures/02.03-sine.png')

只要保證使用所支援的檔案字尾即可,例如.jpg、.png、.tif、.svg、.eps或者.pdf。

在匯入matplotlib之後,執行plt.style.use(style_name),你可以更改繪圖的樣式。在plt.style.available中列出了所有可用的樣式。例如,試試plt.style.use('fivethirtyeight')、plt.style.use('ggplot')或者plt.style.use('seaborn-dark')。為了增加樂趣,可以執行plt.xkcd(),再嘗試繪製其他內容。

03 視覺化外部資料集的資料

作為本文的最後一個測試,讓我們視覺化一些來自外部資料集的資料,例如scikit-learn的digits資料集。

具體來說,我們將需要3個視覺化工具:

用於實際資料的scikit-learn用於資料處理的NumPyMatplotlib

首先,讓我們匯入所有這些視覺化工具:

import numpy as npfrom sklearn import datasetsimport matplotlib.pyplot as plt%matplotlib inline

第一步是實際載入資料:

digits = datasets.load_digits()

如果我們沒有記錯的話,digits應該有2個不同的欄位:一個是data欄位,包含實際的影象資料;另一個是target欄位,包含影象標籤。

與其相信我們的記憶,不如讓我們研究一下digits物件。這透過輸入欄位名稱、新增句點、再按下Tab鍵—digits.<TAB>來實現。這會顯示出digits物件還包含了一些其他欄位,例如一個名為images的欄位。images和data這2個欄位似乎只是形狀不同:

print(digits.data.shape)print(digits.images.shape)

輸出結果:

(1797, 64)(1797, 8, 8)

在這兩個例子中,第一維都對應於資料集中的影象數。但是data將所有畫素排列在一個大的向量中,而images則保留了每個影象的8×8空間排列。

因此,如果我們想繪製單張影象,images欄位可能更合適。首先,使用NumPy的陣列切割,從資料集中抓取一張影象:

img = digits.images[0, :, :]

這裡,我們說想要抓取長為1797項的陣列中的第一行,以及所有對應的8×8=64個畫素。然後,我們可以使用plt的imshow函式繪製圖像:

plt.imshow(img, cmap='gray')plt.savefig('figures/02.04-digit0.png')

上述命令給出的輸出如圖2-5所示。請注意,影象是模糊的,因為我們將該影象調整到了更大的尺寸。原始影象的大小隻有8×8。

▲圖2-5 生成單張影象的示例結果

此外,我們還可以使用cmap引數指定一個彩圖。在預設情況下,Matplotlib使用MATLAB的預設彩圖jet。可是,對於灰度影象,gray彩圖更有意義。

最後,我們可以利用plt的subplot函式繪製一組數字樣本。subplot函式與在MATLAB中一樣,我們指定行數、列數以及當前子圖的索引(從1開始)。我們將使用一個for迴圈遍歷資料集中的前10個影象,每個影象都有自己的子圖:

plt.figure(figsize=(14, 4))for image_index in range(10):    # images are 0-indexed, subplots are 1-indexed    subplot_index = image_index + 1    plt.subplot(2, 5, subplot_index)    plt.imshow(digits.images[image_index, :, :], cmap='gray')

生成的輸出如圖2-6所示。

▲圖2-6 生成包含10個數字的一組子圖

對於各種資料集,另一個很好的資源是本書作者邁克爾·貝耶勒的母校加州大學歐文分校的機器學習資源庫:

http://archive.ics.uci.edu/ml/index.php

維什韋什·拉維·什裡馬利(Vishwesh Ravi Shrimali),於2018年畢業於彼拉尼博拉理工學院(BITS Pilani)機械工程專業。此後一直在BigVision LLC從事深度學習和計算機視覺方面的工作,還參與了官方OpenCV課程的建立。

邁克爾·貝耶勒(Michael Beyeler),是華盛頓大學神經工程和資料科學的博士後研究員,致力於仿生視覺的計算模型研究,以為盲人植入人工視網膜(仿生眼睛),改善盲人的感知體驗。他的工作屬於神經科學、計算機工程、計算機視覺和機器學習的交叉領域。

本文摘編自《機器學習:使用OpenCV、Python和scikit-learn進行智慧影象處理(原書第2版)》,經出版方授權釋出。

延伸閱讀《機器學習:使用OpenCV、Python和scikit-learn進行智慧影象處理(原書第2版》

推薦語:保姆級OpenCV入門實戰手冊——“蝴蝶書”全新升級!透過具體的程式設計實踐案例,介紹最新OpenCV 4版本所提供的大量新特性和平臺改進。透過書中提供的用例程式碼,你可以快速熟悉並掌握機器學習領域的相關知識,掌握使用OpenCV 4構建智慧計算機視覺應用程式所需要的機器學習技能。

16
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Guava30.1釋出,Google的Java 核心工具庫