數(shù)據(jù)科學 IPython 筆記本 8.3 Matplotlib 可視化

8.3 Matplotlib 可視化

原文:Visualization with Matplotlib

譯者:飛龍

協(xié)議:CC BY-NC-SA 4.0

本節(jié)是《Python 數(shù)據(jù)科學手冊》(Python Data Science Handbook)的摘錄瓢谢。

我們現(xiàn)在將深入研究M atplotlib 包,以便在 Python 中進行可視化忘分。Matplotlib 是一個基于 NumPy 數(shù)組的多平臺數(shù)據(jù)可視化庫,旨在兼容更廣泛的 SciPy 技術(shù)棧。它由 John Hunter 在 2002 年構(gòu)思捐顷,最初是作為 IPython 的補丁舷暮,用于通過來自 IPython 命令行的gnuplot實現(xiàn) MATLAB 風格的交互式繪圖铲敛。

IPython 的創(chuàng)始人 Fernando Perez 當時正努力完成他的博士學位待错,并且 John 知道他幾個月都沒時間審查補丁籽孙。John 把它看做一個使自己開始的動機,之后 Matplotlib 軟件包誕生了火俄,2003 年發(fā)布了 0.1 版本。當它被用作太空望遠鏡科學研究所(哈勃望遠鏡背后的人)選擇的繪圖包時讲冠,它得到了早期的贊助瓜客,該研究所在財務(wù)上支持了 Matplotlib 的開發(fā),并極大地擴展了它的能力竿开。

Matplotlib 最重要的功能之一是谱仪,它能夠很好地兼容許多操作系統(tǒng)和圖形后端。Matplotlib 支持許多后端和輸出類型否彩,這意味著無論你使用哪種操作系統(tǒng)或你希望使用哪種輸出格式疯攒,你都可以依賴它。

這種跨平臺的通用方法是 Matplotlib 的強大優(yōu)勢之一列荔。它帶來了龐大的用戶群敬尺,這反過來又產(chǎn)生了活躍的開發(fā)人員的基礎(chǔ),和 Python 科學世界中的 Matplotlib 的威力和普遍性贴浙。

然而砂吞,近年來,Matplotlib 的界面和風格已經(jīng)有些過時崎溃。
比起 R 語言中的ggplotggvis等新工具蜻直,以及基于 D3js 和 HTML5 畫布的 Web 可視化工具包,Matplotlib 顯得笨重和陳舊袁串。盡管如此概而,我認為我們不能忽視 Matplotlib 作為經(jīng)過良好測試的跨平臺圖形引擎的優(yōu)勢。

最近的 Matplotlib 版本囱修,使得設(shè)置新的全局繪圖樣式變得相對容易(參見“自定義 Matplotlib:配置和樣式表”)赎瑰,人們一直在開發(fā)新的包,它們基于 Matplotlib 的強大內(nèi)核蔚袍,通過更清潔乡范,更現(xiàn)代的 API 驅(qū)動 Matplotlib - 例如配名,Seaborn(“可視化與 Seaborn”),[ggpy](http://yhat.github.io/ggpy /)晋辆,HoloViews渠脉,Altair,甚至 Pandas 本身都可以用作 Matplotlib API 的包裝瓶佳。

即使使用這樣的包裝器芋膘,通常也可以深入研究 Matplotlib 的語法來調(diào)整最終的繪圖輸出。出于這個原因霸饲,我相信 Matplotlib 本身为朋,仍將是數(shù)據(jù)可視化技術(shù)棧的重要組件,即使新工具意味著社區(qū)逐漸不再使用 Matplotlib API厚脉。

一般 Matplotlib 提示

在我們深入了解使用 Matplotlib 創(chuàng)建可視化的細節(jié)之前习寸,你應(yīng)該了解一些使用該軟件包的有用信息。

導入 Matplotlib

正如我們對 NumPy 使用np簡寫傻工,對 Pandas 使用pd簡寫一樣霞溪,我們將對 Matplotlib 導入使用一些標準簡寫:

import matplotlib as mpl
import matplotlib.pyplot as plt

我們將經(jīng)常使用plt接口,我們將在本章中看到中捆。

設(shè)置樣式

我們將使用plt.style指令鸯匹,為我們的圖形選擇合適的美學風格。在這里泄伪,我們將設(shè)置classic樣式殴蓬,確保我們創(chuàng)建的圖使用經(jīng)典的 Matplotlib 樣式:

plt.style.use('classic')

在本節(jié)中,我們將按需調(diào)整此樣式蟋滴。請注意染厅,此處使用的樣式表從 Matplotlib 1.5 版開始得到支持;如果你使用的是早期版本的 Matplotlib 脓杉,則只能使用默認樣式糟秘。樣式表的更多信息,請參閱“自定義 Matplotlib:配置和樣式表”球散。

show()還是不show()尿赚?如何展示你的繪圖

你看不到的可視化并沒什么用,但是你查看 Matplotlib 繪圖的方式取決于上下文蕉堰。Matplotlib 的最佳用法取決于你的使用方式凌净;粗略地說,三個適用的上下文是屋讶,在腳本冰寻,IPython 終端或 IPython 筆記本中使用 Matplotlib。

來自腳本的繪圖

如果你在腳本中使用 Matplotlib皿渗,函數(shù)plt.show()就是你的伙伴斩芭。plt.show()啟動一個事件循環(huán)轻腺,查找所有當前活動的圖形對象,并打開一個或多個顯示你的圖形的交互式窗口划乖。

因此贬养,例如,你可能有一個名為myplot.py的文件琴庵,其中包含以下內(nèi)容:

# ------- 文件:myplot.py ------
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)

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

plt.show()

然后误算,你可以從命令行運行此腳本,這將打開一個窗口并顯示你的圖形:

$ python myplot.py

plt.show()命令做了很多工作迷殿,因為它必須與系統(tǒng)的交互式圖形后端進行交互儿礼。此操作的細節(jié)可能因不同系統(tǒng),甚至安裝而異庆寺,但 matplotlib 會盡力對你隱藏所有這些細節(jié)蚊夫。

有一點需要注意:plt.show()命令應(yīng)該在每個 Python 會話中只使用一次,并且最常見于腳本的最后止邮。多個show()命令可能產(chǎn)生不可預測的后端依賴的行為这橙,并且多數(shù)情況下應(yīng)該避免。

來自 IPython shell 的繪圖

在 IPython shell 中以交互方式使用 Matplotlib 非常方便(參見“IPython:不只是普通的 Python”)导披。如果指定 Matplotlib 模式,IPython 可以很好地配合 Matplotlib埃唯。要啟用此模式撩匕,可以在啟動ipython后使用%matplotlib魔術(shù)命令:

In [1]: %matplotlib
Using matplotlib backend: TkAgg

In [2]: import matplotlib.pyplot as plt

此時,任何plt繪圖命令都會打開一個圖形窗口墨叛,可以運行更多命令來更新繪圖止毕。一些更改(例如修改已繪制的直線的屬性)將不會自動繪制:要強制更新,請使用plt.draw()漠趁。不需要在 Matplotlib 模式下使用plt.show()扁凛。

來自 IPython 筆記本的繪圖

IPython 筆記本是一個基于瀏覽器的,交互式數(shù)據(jù)分析工具闯传,可以將敘述谨朝,代碼,圖形甥绿,HTML 元素等組合到一個可執(zhí)行文檔中(參見“IPython:不只是普通的 Python”)字币。

IPython 筆記本中的交互式繪圖,可以使用%matplotlib命令完成共缕,其工作方式與 IPython shell 類似洗出。在 IPython 筆記本中,你還可以選擇直接在筆記本中嵌入圖形图谷,有兩種可能的選擇:

  • %matplotlib notebook將產(chǎn)生嵌入在筆記本中的交互式繪圖
  • %matplotlib inline將產(chǎn)生嵌入在筆記本中的繪圖的靜態(tài)圖像

對于本書翩活,我們通常會選擇%matplotlib inline

%matplotlib inline

運行此命令后(每個內(nèi)核/會話只需執(zhí)行一次)阱洪,筆記本中創(chuàng)建繪圖的任何單元格,都將嵌入所得圖形的 PNG 圖像:

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

fig = plt.figure()
plt.plot(x, np.sin(x), '-')
plt.plot(x, np.cos(x), '--');
png

將圖形保存到文件

Matplotlib 的一個很好的功能菠镇,是以各種格式保存圖形的能力冗荸。保存圖形可以使用savefig()命令完成。例如辟犀,要將上一個圖形保存為 PNG 文件俏竞,可以運行以下命令:

fig.savefig('my_figure.png')

在當前工作目錄中,我們現(xiàn)在有一個名為my_figure.png的文件:

!ls -lh my_figure.png

# -rw-r--r--  1 jakevdp  staff    16K Aug 11 10:59 my_figure.png

為了確認它包含我們認為它包含的內(nèi)容堂竟,讓我們使用 IPython Image對象來顯示該文件的內(nèi)容:

from IPython.display import Image
Image('my_figure.png')
png

savefig()中魂毁,文件格式是從給定文件名的擴展名推斷出來的。根據(jù)你安裝的后端出嘹,可以使用許多不同的文件格式席楚。通過使用圖形畫布對象的以下方法,可以找到系統(tǒng)支持的文件類型列表:

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'}
'''

請注意税稼,在保存圖形時烦秩,不必使用前面討論過的plt.show()或相關(guān)命令。

一個功能的兩個接口

Matplotlib 的一個可能令人困惑的特性是它的兩個接口:一個是方便的 MATLAB 風格的郎仆,基于狀態(tài)的接口只祠,以及一個更強大的面向?qū)ο蟮慕涌凇N覀儗⒃谶@里快速強調(diào)兩者之間的差異扰肌。

MATLAB 風格的接口

Matplotlib 最初編寫為 MATLAB 用戶的 Python 替代品抛寝,其大部分語法都反映了這一事實。MATLAB 風格的工具包含在pyplotplt)接口中曙旭。例如盗舰,以下代碼可能對 MATLAB 用戶來說非常熟悉:

plt.figure()  # 創(chuàng)建繪圖圖形

# 創(chuàng)建兩個面板的第一個并設(shè)置當前軸
plt.subplot(2, 1, 1) # 行,列桂躏,面板號
plt.plot(x, np.sin(x))

# 創(chuàng)建第二個面板并設(shè)置當前軸
plt.subplot(2, 1, 2)
plt.plot(x, np.cos(x));
png

重要的是要注意這個接口是有狀態(tài)的:它跟蹤“當前”圖形和軸域钻趋,這是所有plt命令都適用的地方。你可以使用plt.gcf()(獲取當前圖形)和plt.gca()(獲取當前軸域)例程來獲取這些引用剂习。

雖然這種狀態(tài)接口對于簡單的繪圖來說既快速又方便蛮位,但很容易遇到問題。例如进倍,一旦創(chuàng)建了第二個面板土至,我們?nèi)绾畏祷夭⑾虻谝粋€面板添加內(nèi)容?這在 MATLAB 風格的接口中是可能的猾昆,但有點笨拙陶因。幸運的是,有一種更好的方法垂蜗。

面向?qū)ο蟮慕涌?/h4>

面向?qū)ο蟮慕涌诳捎糜谶@些更復雜的情況楷扬,以及需要對圖形進行更多控制的時候解幽。在面向?qū)ο蟮慕缑嬷校L圖函數(shù)并不依賴于“活動”圖形或軸域的某些概念烘苹,而是顯式“圖形”和“軸域”對象的方法躲株。要使用此風格的繪圖重新創(chuàng)建上一個繪圖,你可以執(zhí)行以下操作:

# 首先創(chuàng)建繪圖網(wǎng)格
# ax will be an array of two Axes objects
fig, ax = plt.subplots(2)

# 在對應(yīng)對象上調(diào)用 plot() 方法
ax[0].plot(x, np.sin(x))
ax[1].plot(x, np.cos(x));
png

對于更簡單的圖镣衡,選擇使用哪種樣式在很大程度上取決于偏好霜定,但隨著變得更復雜,面向?qū)ο蟮姆椒赡艹蔀楸匾扰浮T诒菊轮型疲覀儗⒏鶕?jù)最方便的方式,在 MATLAB風 格和面向?qū)ο蟮慕缑嬷g切換惰说。在大多數(shù)情況下磨德,差異就像切換plt.plot()ax.plot()一樣小,但是在下面的章節(jié)中我們會強調(diào)一些問題吆视。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末典挑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子啦吧,更是在濱河造成了極大的恐慌您觉,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件授滓,死亡現(xiàn)場離奇詭異顾犹,居然都是意外死亡,警方通過查閱死者的電腦和手機褒墨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擎宝,“玉大人郁妈,你說我怎么就攤上這事∩苌辏” “怎么了噩咪?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長极阅。 經(jīng)常有香客問我胃碾,道長,這世上最難降的妖魔是什么筋搏? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任仆百,我火速辦了婚禮,結(jié)果婚禮上奔脐,老公的妹妹穿的比我還像新娘俄周。我一直安慰自己吁讨,他們只是感情好,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布峦朗。 她就那樣靜靜地躺著建丧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪波势。 梳的紋絲不亂的頭發(fā)上翎朱,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音尺铣,去河邊找鬼拴曲。 笑死,一個胖子當著我的面吹牛迄埃,可吹牛的內(nèi)容都是我干的疗韵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼侄非,長吁一口氣:“原來是場噩夢啊……” “哼蕉汪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起逞怨,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤者疤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后叠赦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體驹马,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年除秀,在試婚紗的時候發(fā)現(xiàn)自己被綠了糯累。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡册踩,死狀恐怖泳姐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情暂吉,我是刑警寧澤胖秒,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站慕的,受9級特大地震影響阎肝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肮街,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一风题、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦俯邓、人聲如沸骡楼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸟整。三九已至,卻和暖如春朦蕴,著一層夾襖步出監(jiān)牢的瞬間篮条,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工吩抓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留涉茧,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓疹娶,卻偏偏與公主長得像伴栓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子雨饺,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容