當前位置:
首頁 > 知識 > 高效使用 Python 可視化工具 Matplotlib

高效使用 Python 可視化工具 Matplotlib

(點擊

上方藍字

,快速關注我們)




編譯:伯樂在線 - 李大萌


如有好文章投稿,請點擊 → 這裡了解詳情




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的圖非常經典,方便了解一幅圖的不同術語。







大多數術語都非常直接,但要記住的要點是,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 中包含附加細節的筆記,應該非常有用。




準備開始,我先引入庫並讀入一些數據:




import

pandas

as

pd


import

matplotlib

.

pyplot

as

plt


from

matplotlib

.

ticker

import

FuncFormatter



df

=

pd

.

read_excel

(

"https://github.com/chris1610/pbpython/blob/master/data/sample-salesv3.xlsx?raw=true"

)


df

.

head

()







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





top_10

=

(

df

.

groupby

(

"name"

)[

"ext price"

,

"quantity"

].

agg

({

"ext price"

:

"sum"

,

"quantity"

:

"count"

})


.

sort_values

(

by

=

"ext price"

,

ascending

=

False

))[

:

10

].

reset_index

()


top_10

.

rename

(

columns

=

{

"name"

:

"Name"

,

"ext price"

:

"Sales"

,

"quantity"

:

"Purchases"

},

inplace

=

True

)




下面是數據的處理結果。







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




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





plt.style.available





[

"seaborn-dark"

,


"seaborn-dark-palette"

,


"fivethirtyeight"

,


"seaborn-whitegrid"

,


"seaborn-darkgrid"

,


"seaborn"

,


"bmh"

,


"classic"

,


"seaborn-colorblind"

,


"seaborn-muted"

,


"seaborn-white"

,


"seaborn-talk"

,


"grayscale"

,


"dark_background"

,


"seaborn-deep"

,


"seaborn-bright"

,


"ggplot"

,


"seaborn-paper"

,


"seaborn-notebook"

,


"seaborn-poster"

,


"seaborn-ticks"

,


"seaborn-pastel"

]




這樣簡單使用一個樣式:





plt.style.use("ggplot")




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




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





top_10.plot(kind="barh", y="Sales", x="Name")







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




定製化繪圖




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





fig

,

ax

=

plt

.

subplots

()


top_10

.

plot

(

kind

=

"barh"

,

y

=

"Sales"

,

x

=

"Name"

,

ax

=

ax

)




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




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




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





fig

,

ax

=

plt

.

subplots

()


top_10

.

plot

(

kind

=

"barh"

,

y

=

"Sales"

,

x

=

"Name"

,

ax

=

ax

)


ax

.

set_xlim

([

-

10000

,

140000

])


ax

.

set_xlabel

(

"Total Revenue"

)


ax

.

set_ylabel

(

"Customer"

);







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





fig

,

ax

=

plt

.

subplots

()


top_10

.

plot

(

kind

=

"barh"

,

y

=

"Sales"

,

x

=

"Name"

,

ax

=

ax

)


ax

.

set_xlim

([

-

10000

,

140000

])


ax

.

set

(

title

=

"2014 Revenue"

,

xlabel

=

"Total Revenue"

,

ylabel

=

"Customer"

)







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





fig

,

ax

=

plt

.

subplots

(

figsize

=

(

5

,

6

))


top_10

.

plot

(

kind

=

"barh"

,

y

=

"Sales"

,

x

=

"Name"

,

ax

=

ax

)


ax

.

set_xlim

([

-

10000

,

140000

])


ax

.

set

(

title

=

"2014 Revenue"

,

xlabel

=

"Total Revenue"

)


ax

.

legend

().

set_visible

(

False

)







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




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





def

currency

(

x

,

pos

)

:


"The two args are the value and tick position"


if

x

>=

1000000

:


return

"${:1.1f}M"

.

format

(

x

*

1e

-

6

)


return

"${:1.0f}K"

.

format

(

x

*

1e

-

3

)




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





fig

,

ax

=

plt

.

subplots

()


top_10

.

plot

(

kind

=

"barh"

,

y

=

"Sales"

,

x

=

"Name"

,

ax

=

ax

)


ax

.

set_xlim

([

-

10000

,

140000

])


ax

.

set

(

title

=

"2014 Revenue"

,

xlabel

=

"Total Revenue"

,

ylabel

=

"Customer"

)


formatter

=

FuncFormatter

(

currency

)


ax

.

xaxis

.

set_major_formatter

(

formatter

)


ax

.

legend

().

set_visible

(

False

)







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




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




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





# Create the figure and the axes


fig

,

ax

=

plt

.

subplots

()



# Plot the data and get the averaged


top_10

.

plot

(

kind

=

"barh"

,

y

=

"Sales"

,

x

=

"Name"

,

ax

=

ax

)


avg

=

top_10

[

"Sales"

].

mean

()



# Set limits and labels


ax

.

set_xlim

([

-

10000

,

140000

])


ax

.

set

(

title

=

"2014 Revenue"

,

xlabel

=

"Total Revenue"

,

ylabel

=

"Customer"

)



# Add a line for the average


ax

.

axvline

(

x

=

avg

,

color

=

"b"

,

label

=

"Average"

,

linestyle

=

"--"

,

linewidth

=

1

)



# Annotate the new customers


for

cust

in

[

3

,

5

,

8

]

:


ax

.

text

(

115000

,

cust

,

"New Customer"

)



# Format the currency


formatter

=

FuncFormatter

(

currency

)


ax

.

xaxis

.

set_major_formatter

(

formatter

)



# Hide the legend


ax

.

legend

().

set_visible

(

False

)







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




圖形和圖像




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




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





fig, (ax0, ax1) = plt.subplots(nrows=1, ncols=2, sharey=True, figsize=(7, 4))




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




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




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





# Get the figure and the axes


fig

,

(

ax0

,

ax1

)

=

plt

.

subplots

(

nrows

=

1

,

ncols

=

2

,

sharey

=

True

,

figsize

=

(

7

,

4

))


top_10

.

plot

(

kind

=

"barh"

,

y

=

"Sales"

,

x

=

"Name"

,

ax

=

ax0

)


ax0

.

set_xlim

([

-

10000

,

140000

])


ax0

.

set

(

title

=

"Revenue"

,

xlabel

=

"Total Revenue"

,

ylabel

=

"Customers"

)



# Plot the average as a vertical line


avg

=

top_10

[

"Sales"

].

mean

()


ax0

.

axvline

(

x

=

avg

,

color

=

"b"

,

label

=

"Average"

,

linestyle

=

"--"

,

linewidth

=

1

)



# Repeat for the unit plot


top_10

.

plot

(

kind

=

"barh"

,

y

=

"Purchases"

,

x

=

"Name"

,

ax

=

ax1

)


avg

=

top_10

[

"Purchases"

].

mean

()


ax1

.

set

(

title

=

"Units"

,

xlabel

=

"Total Units"

,

ylabel

=

""

)


ax1

.

axvline

(

x

=

avg

,

color

=

"b"

,

label

=

"Average"

,

linestyle

=

"--"

,

linewidth

=

1

)



# Title the figure


fig

.

suptitle

(

"2014 Sales Analysis"

,

fontsize

=

14

,

fontweight

=

"bold"

);



# Hide the legends


ax1

.

legend

().

set_visible

(

False

)


ax0

.

legend

().

set_visible

(

False

)







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




Matplotlib支持許多不同格式文件的保存。 你可以用fig.canvas.get_supported_filetypes()查看系統支持的格式:





fig.canvas.get_supported_filetypes()





{

"eps"

:

"Encapsulated Postscript"

,


"jpeg"

:

"Joint Photographic Experts Group"

,


"jpg"

:

"Joint Photographic Experts Group"

,


"pdf"

:

"Portable Document Format"

,


"pgf"

:

"PGF code for LaTeX"

,


"png"

:

"Portable Network Graphics"

,


"ps"

:

"Postscript"

,


"raw"

:

"Raw RGBA bitmap"

,


"rgba"

:

"Raw RGBA bitmap"

,


"svg"

:

"Scalable Vector Graphics"

,


"svgz"

:

"Scalable Vector Graphics"

,


"tif"

:

"Tagged Image File Format"

,


"tiff"

:

"Tagged Image File Format"

}




由於我們有fig對象,我們可以用多個選項來保存圖像:





fig.savefig("sales.png", transparent=False, dpi=80, bbox_inches="tight")




上面的代碼把圖像保存為背景不透明的png。還指定了解析度dpi和bbox_inches =「tight」來盡量減少多餘的空格。




結論




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




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







看完本文有收穫?請轉

發分享給更多人


關注「P

ython開發者」,提升Python技能


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

Python 調用 C 模塊以及性能分析
代碼這樣寫更優雅,15篇 Python 技術熱文
如何用Python從海量文本抽取主題?
使用Python自动提取内容摘要
Python Virtualenv 介紹

TAG:Python |

您可能感興趣

HiddenLayer:可視化PyTorch、TensorFlow神經網路圖的輕量級工具!
Cytoscape:強大的pathway分析可視化工具
資源 | HiddenLayer:可視化PyTorch、TensorFlow神經網路圖的輕量級工具!
教程 | 5種快速易用的Python Matplotlib數據可視化方法
Python 數據可視化神器分享:pyecharts
3ds Max+Stingray 可視化VR
Python可視化神器——pyecharts的超詳細使用指南!
Plotly Dash數據可視化
比Excel製圖更強大,Python可視化工具Altair入門教程
用於可視化人工神經網路的 Python庫——ANN Visualizer
sqlitestudio可視化操作sqlite資料庫
CreativeDrive收購三維可視化和AR創業公司Decora
互動式數據可視化處理工具Microsoft Power BI簡介
Datalore:用於機器學習可視化的新Web方案!
Tensorflow可視化教程
scrapydweb:實現 Scrapyd 集群管理,Scrapy 日誌分析和可視化
linux-快速安裝可視化面板grafana
房地產沉浸式可視化服務商Matterport收購AI創企Arraiy
這5小段代碼輕鬆實現數據可視化(Python+Matplotlib)
Wandb用起來,一行Python代碼實現Keras模型可視化