高效使用 Python 視覺化工具 Matplotlib

李大萌發表於2017-06-30

Matplotlib是Python中最常用的視覺化工具之一,可以非常方便地建立海量型別的2D圖表和一些基本的3D圖表。本文主要介紹了在學習Matplotlib時面臨的一些挑戰,為什麼要使用Matplotlib,並推薦了一個學習使用Matplotlib的步驟。

簡介

對於新手來說,進入Python視覺化領域有時可能會令人感到沮喪。Python有很多不同的視覺化工具,選擇一個正確的工具有時是一種挑戰。 例如,即使兩年過去了,這篇《Overview of Python Visualization Tools》是引導人們到這個網站的頂級帖子之一。 在那篇文章中,我對matplotlib留下了一些陰影,並在分析過程中不再使用。 然而,在使用諸如pandas,scikit-learn,seaborn和其他資料科學技術棧的python工具後,覺得丟棄matplotlib有點過早了。說實話,之前我不太瞭解matplotlib,也不知道如何在工作流程中有效地使用。

現在我花時間學習了其中的一些工具,以及如何使用matplotlib,已經開始將matplotlib看作是不可或缺的工具了。這篇文章將展示我是如何使用matplotlib的,併為剛入門的使用者或者沒時間學習matplotlib的使用者提供一些建議。我堅信matplotlib是python資料科學技術棧的重要組成部分,希望本文能幫助大家瞭解如何將matplotlib用於自己的視覺化。

為什麼對matplotlib都是負面評價?

在我看來,新使用者學習matplotlib之所以會面臨一定的挑戰,主要有以下幾個原因。

首先,matplotlib有兩種介面。第一種是基於MATLAB並使用基於狀態的介面。第二種是物件導向的介面。為什麼是這兩種介面不在本文討論的範圍之內,但是知道有兩種方法在使用matplotlib進行繪圖時非常重要。

兩種介面引起混淆的原因在於,在stack overflow社群和谷歌搜尋可以獲得大量資訊的情況下,新使用者對那些看起來有些相似但不一樣的問題,面對多個解決方案會感到困惑。從我自己的經歷說起。回顧一下我的舊程式碼,一堆matplotlib程式碼的混合——這對我來說非常混亂(即使是我寫的)。

關鍵點

matplotlib的新使用者應該學習使用物件導向的介面。

matplotlib的另一個歷史性挑戰是,一些預設風格選項相當沒有吸引力。 在R語言世界裡,可以用ggplot生成一些相當酷的繪圖,相比之下,matplotlib的選項看起來有點醜。令人欣慰的是matplotlib 2.0具有更美觀的樣式,以及非常便捷對視覺化的內容進行主題化的能力。

使用matplotlib我認為第三個挑戰是,當繪製某些東西時,應該單純使用matplotlib還是使用建立在其之上的類似pandas或者seaborn這樣的工具,你會感到困惑。任何時候都可以有多種方式來做事,對於新手或不常用matplotlib的使用者來講,遵循正確的路徑是具有挑戰性的。將這種困惑與兩種不同的API聯絡起來,是解決問題的祕訣。

為什麼堅持要用matplotlib?

儘管有這些問題,但是我慶幸有matplotlib,因為它非常強大。這個庫允許建立幾乎任何你可以想象的視覺化。此外,圍繞著它還有一個豐富的python工具生態系統,許多更先進的視覺化工具用matplotlib作為基礎庫。如果在python資料科學棧中進行任何工作,都將需要對如何使用matplotlib有一個基本的瞭解。這是本文的其餘部分的重點——介紹一種有效使用matplotlib的基本方法。

基本前提

如果你除了本文之外沒有任何基礎,建議用以下幾個步驟學習如何使用matplotlib:

  1. 學習基本的matplotlib術語,尤其是什麼是圖和座標軸
  2. 始終使用物件導向的介面,從一開始就養成使用它的習慣
  3. 用基礎的pandas繪圖開始你的視覺化學習
  4. 用seaborn進行更復雜的統計視覺化
  5. 用matplotlib來定製pandas或者seaborn視覺化

這幅來自matplotlib faq的圖非常經典,方便了解一幅圖的不同術語。

高效使用 Python 視覺化工具 Matplotlib

大多數術語都非常直接,但要記住的要點是,Figure是最終的影象,可能包含一個或多個座標軸。座標軸代表一個單獨的劃分。一旦你瞭解這些內容,以及如何通過物件導向的API訪問它們,下面的步驟才能開始進行。

這些術語知識有另一個好處,當你在網上看某些東西時,就有了一個起點。如果你花時間瞭解了這一點,才會理解matplotlib API的其餘部分。此外,許多python的高階軟體包,如seaborn和ggplot都依賴於matplotlib。因此,瞭解這些基礎知識後再學那些功能更強大的框架會容易一些。

最後,我不是說你應該避免選擇例如ggplot(aka ggpy),bokeh,plotly或者altair等其他更好的工具。我只是認為你需要從對matplotlib + pandas + seaborn 有一個基本瞭解開始。一旦理解了基本的視覺化技術,就可以探索其他工具,並根據自己的需要做出明智的選擇。

入門

本文的其餘部分將作為一個入門教程,介紹如何在pandas中進行基本的視覺化建立,並使用matplotlib自定義最常用的專案。一旦你瞭解了基本過程,進一步的定製化建立就相對比較簡單。

重點講一下我遇到的最常見的繪圖任務,如標記軸,調整限制,更新繪圖示題,儲存圖片和調整圖例。如果你想跟著繼續學習,在連結https://github.com/chris1610/pbpython/blob/master/notebooks/Effectively-Using-Matplotlib.ipynb 中包含附加細節的筆記,應該非常有用。

準備開始,我先引入庫並讀入一些資料:

account number name sku quantity unit price ext price date
0 740150 Barton LLC B1-20000 39 86.69 3380.91 2014-01-01 07:21:51
1 714466 Trantow-Barrows S2-77896 -1 63.16 -63.16 2014-01-01 10:00:47
2 218895 Kulas Inc B1-69924 23 90.70 2086.10 2014-01-01 13:24:58
3 307599 Kassulke, Ondricka and Metz S1-65481 41 21.05 863.05 2014-01-01 15:05:22
4 412290 Jerde-Hilpert S2-34077 6 83.21 499.26 2014-01-01 23:26:55

這是2014年的銷售交易資料。為了使這些資料簡短一些,我將對資料進行聚合,以便我們可以看到前十名客戶的總購買量和總銷售額。為了清楚我還會在繪圖中重新命名列。

下面是資料的處理結果。

Name Purchases Sales
0 Kulas Inc 94 137351.96
1 White-Trantow 86 135841.99
2 Trantow-Barrows 94 123381.38
3 Jerde-Hilpert 89 112591.43
4 Fritsch, Russel and Anderson 81 112214.71
5 Barton LLC 82 109438.50
6 Will LLC 74 104437.60
7 Koepp Ltd 82 103660.54
8 Frami, Hills and Schmidt 72 103569.59
9 Keeling LLC 74 100934.30

現在,資料被格式化成一個簡單的表格,我們來看如何將這些結果繪製成條形圖。

如前所述,matplotlib有許多不同的樣式可用於渲染繪圖,可以用plt.style.available檢視系統中有哪些可用的樣式。

這樣簡單使用一個樣式:

我鼓勵大家嘗試不同的風格,看看你喜歡哪些。

現在我們準備好了一個更美觀的樣式,第一步是使用標準的pandas繪圖功能繪製資料:

高效使用 Python 視覺化工具 Matplotlib

我推薦先使用pandas繪圖,是因為它是一種快速簡便構建視覺化的方法。 由於大多數人可能已經在pandas中進行過一些資料處理/分析,所以請先從基本的繪圖開始。

定製化繪圖

假設你對這個繪圖的要點很滿意,下一步就是定製它。使用pandas繪圖功能定製(如新增標題和標籤)非常簡單。但是,你可能會發現自己的需求在某種程度上超越該功能。這就是我建議養成這樣做的習慣的原因:

得到的圖看起來與原始圖看起來相同,但是我們向plt.subplots() 新增了一個額外的呼叫,並將ax傳遞給繪圖函式。為什麼要這樣做? 記得當我說在matplotlib中要訪問座標軸和數字至關重要嗎?這就是我們在這裡完成的工作。將來任何定製化都將通過ax或fig物件完成。

我們得益於pandas快速繪圖,獲得了訪問matplotlib的所有許可權。我們現在可以做什麼呢?用一個例子來展示。另外,通過命名約定,可以非常簡單地把別人的解決方案改成適合自己獨特需求的方案。

假設我們要調整x限制並更改一些座標軸的標籤?現在座標軸儲存在ax變數中,我們有很多的控制權:

高效使用 Python 視覺化工具 Matplotlib

下面是一個快捷方式,可以用來更改標題和兩個標籤:

高效使用 Python 視覺化工具 Matplotlib

為了進一步驗證這種方法,還可以調整影象的大小。通過plt.subplots() 函式,可以用英寸定義figsize。也可以用ax.legend().set_visible(False)來刪除圖例。

高效使用 Python 視覺化工具 Matplotlib

基於很多原因你可能想要調整一下這個圖。看著最彆扭的地方是總收入數字的格式。 Matplotlib可以通過FuncFormatter來幫我們實現。這個功能可以將使用者定義的函式應用於值,並返回一個格式整齊的字串放置在座標軸上。

下面是一個貨幣格式化函式,可以優雅地處理幾十萬範圍內的美元格式:

現在我們有一個格式化函式,需要定義它並將其應用到x軸。以下是完整的程式碼:

高效使用 Python 視覺化工具 Matplotlib

這樣更美觀,也是一個很好的例子,展示如何靈活地定義自己的問題解決方案。

我們最後要去探索的一個自定義功能是通過新增註釋到繪圖。繪製一條垂直線,可以用ax.axvline()。新增自定義文字,可以用ax.text()。

在這個例子中,我們將繪製一條平均線,並顯示三個新客戶的標籤。 下面是完整的程式碼和註釋,把它們放在一起。

高效使用 Python 視覺化工具 Matplotlib

雖然這可能不是讓人感到興奮(眼前一亮)的繪圖方式,但它展示了你在用這種方法時有多大許可權。

圖形和影象

到目前為止,我們所做的所有改變都是單個圖形。幸運的是,我們也有能力在圖上新增多個圖形,並使用各種選項儲存整個影象。

如果決定要把兩幅圖放在同一個影象上,我們應對如何做到這一點有基本瞭解。 首先,建立圖形,然後建立座標軸,然後將其全部繪製在一起。我們可以用plt.subplots()來完成:

 

在這個例子中,用nrows和ncols來指定大小,這樣對新使用者來說比較清晰。在示例程式碼中,經常看到像1,2這樣的變數。我覺得使用命名的引數,之後在檢視程式碼時更容易理解。

 

用sharey = True這個引數,以便yaxis共享相同的標籤。

這個例子也很好,因為各個座標軸被解壓縮到ax0和ax1。有這些座標軸軸,你可以像上面的例子一樣繪製圖形,但是在ax0和ax1上各放一個圖。

高效使用 Python 視覺化工具 Matplotlib

到目前為止,我一直用jupyter notebook,藉助%matplotlib內聯指令來顯示圖形。但是很多時候,需要以特定格式儲存數字,和其他內容一起展示。

Matplotlib支援許多不同格式檔案的儲存。 你可以用fig.canvas.get_supported_filetypes()檢視系統支援的格式:

由於我們有fig物件,我們可以用多個選項來儲存影象:

上面的程式碼把影象儲存為背景不透明的png。還指定了解析度dpi和bbox_inches =“tight”來儘量減少多餘的空格。

結論

希望這個過程有助於你瞭解如何在日常的資料分析中更有效地使用matplotlib。 如果在做分析時養成使用這種方法的習慣,你應該可以快速定製出任何你需要的影象。

作為最後的福利,我引入一個快速指南來總結所有的概念。希望這有助於把這篇文章聯絡起來,併為今後使用參考提供方便。

高效使用 Python 視覺化工具 Matplotlib

相關文章