Matplotlib 數(shù)據(jù)可視化

之前斷斷續(xù)續(xù)的看了不少關(guān)于 Matplotlib 的教程嗅绰,也做了一些練習(xí),但時常被不同演示中繁雜且各異的命令所迷惑败徊。今天剛好看到了 Chris Moffitt 的這篇文章 Effective Matplotlib尿这,覺得有必要結(jié)合官網(wǎng)從更高的視角了解 Matplotlib 的工作機制,在此更新這個筆記蝙斜。

首先,在 Matplotlib 中 figure 結(jié)合了 canvas 和 axes 構(gòu)成了我們看到的最終的圖像本身白翻,其中一個 figure 中可以包含一個或多個 axes乍炉,而每一個 axes 則是一系列 artists 如坐標(biāo)軸 axis绢片,標(biāo)簽 label滤馍,標(biāo)題 title,圖例 legend 的集合底循。在程序中 figure 常用 fig 變量來指代巢株,而 axes 常用 ax 變量來指代,鑒于各個對象間的層級結(jié)構(gòu)關(guān)系熙涤,在使用中獲取了 fig 和 ax 的控制權(quán)就可以對其中的元素進行修改阁苞。

Tree diagram of different artists in matplotlib

其次,Matplotlib 的首選輸入是列表和 Numpy 中的數(shù)組祠挫,任何其他類型的輸入包括 Pandas 的數(shù)據(jù)類型那槽,如 np.matrix 等都應(yīng)該轉(zhuǎn)化成數(shù)組,否則 Matplotlib 會內(nèi)部自動轉(zhuǎn)化等舔,但由于轉(zhuǎn)換的形式不一定是我們想要的骚灸,因此最終生成的圖像可能不是預(yù)期的樣式。

約定引用方式:

import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
# this very last line ask the backend to generate higher resolution figures

應(yīng)用實例

折線圖

plt.plot() 的輸入為待可視的橫慌植、縱坐標(biāo)值甚牲,并可以指定線型义郑,寬度,顏色等:

input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]
plt.plot(input_values, squares, linewidth=3)

圖形的標(biāo)題丈钙,橫縱坐標(biāo)的標(biāo)簽和都可以分別通過 plt.title(), plt.xlabel(), plt.ylabel() 指定:

plt.title("Square Numbers", fontsize=20)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)
plt.tick_params(axis='both', labelsize=14)
plt.show()
square numbers plot

plt.plot() 第一次使用時會自動創(chuàng)建相應(yīng)的 figure 和 axes 來完成圖表的繪制非驮,后續(xù)添加的 plt.plot() 命令會在之前的 axes 上繼續(xù)增加新的 artists 內(nèi)容:

# code adopted from matplotlib website
x = np.linspace(0, 2, 100)

plt.plot(x, x, label='linear')
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')
# plt.axis() takes a list of [xmin, xmax, ymin, ymax]
plt.axis([1, 2, 1, 8])

plt.xlabel('x label')
plt.ylabel('y label')

plt.title("Simple Plot")

plt.legend()

plt.show()
multiple plot( ) calls

在一個 figure 上繪制多個 axes 需要采用 plt.subplot() 命令:

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

# subplot() command specifies numrows, numcols, fignum
# where fignum ranges from 1 to numrows*numcols
plt.subplot(211) # the same as plt.subplot(2, 1, 1)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')

plt.show()
subplot with functions, from matplotlib

在一個 figure 中繪制多個 axes 時有兩個函數(shù):plt.subplot()plt.subplots(),后者返回 figure 和 一個或多個 axes 雏赦,此后對于圖像中元素的操作都是基于 ax.method() 而無需采用采用 plt.method() 的形式劫笙,其使用方法為:

# Get the figure and the axes
fig, (ax0, ax1) = plt.subplots(nrows=1, ncols=2, sharey=True, figsize=(10,4))

# Build the first plot
top_10.plot(kind='barh', x='Name', y='Sales', ax=ax0)
ax0.set(title='Revenue', xlabel='Total revenue', ylabel='Customers')
formatter = FuncFormatter(currency)
ax0.xaxis.set_major_formatter(formatter)

# Add average line to the first plot
revenue_average = top_10['Sales'].mean()
ax0.axvline(x=revenue_average, color='b', label='Average', linestyle='--', linewidth=1)

# Build the second plot
top_10.plot(kind='barh', x='Name', y='Purchases', ax=ax1)
ax1.set(title='Units', xlabel='Total units', ylabel='')

# Add average line to the second plot
purchases_average = top_10['Purchases'].mean()
ax1.axvline(x=purchases_average, color='b', label='Average', linestyle='--', linewidth=1)

# Title the figure
fig.suptitle('2014 Sales Analysis', fontsize=14, fontweight='bold')

# Hide the plot legends
ax0.legend().set_visible(False)
ax1.legend().set_visible(False)
Image from pbpython

注意:上面這一段代碼和圖片來自于Effective Matplotlib,版權(quán)歸屬于 Chris Moffitt 本人喉誊。

如果在繪制多個 axes 時想指定不同 axes 的位置邀摆,則需要顯式的使用 axes([left, bottom, width, height]) 來指定位置,注意參數(shù)提供的是相對于坐標(biāo)軸的比例值伍茄,而非絕對值:

dt = 0.001
t = np.arange(0.0, 10.0, dt)
r = np.exp(-t[:1000]/0.05) # impulse response
x = np.random.randn(len(t))
s = np.convolve(x, r)[:len(x)]*dt # colored noise

# the main axes is subplot(111) by default
plt.plot(t, s)
plt.axis([0, 1, 1.1*np.amin(s), 2*np.amax(s)])
plt.xlabel('time (s)')
plt.ylabel('current (nA)')
plt.title('Gaussian colored noise')

# this is an inset axes over the main axes
a = plt.axes([.65, .6, .2, .2], facecolor='y')
n, bins, patches = plt.hist(s, 400, normed=1)
plt.title('Probability')
plt.xticks([])
plt.yticks([])

# this is another inset axes over the main axes
a = plt.axes([0.2, 0.6, .2, .2], facecolor='y')
plt.plot(t[:len(r)], r)
plt.title('Impulse response')
plt.xlim(0, 0.2)
plt.xticks([])
plt.yticks([])

plt.show()
Multiple axes with manually set axes location, from matplotlib

散點圖

上述手動輸入的 list 作為數(shù)據(jù)源僅僅是為了便于展示栋盹,在日常的使用中,更多的是根據(jù)已有的數(shù)據(jù)生成圖形敷矫。在散點圖中可以通過參數(shù) c 來指定顏色例获,其輸入的值可以是 str, (R, G, B), 也可以是逐點改變的數(shù)值來顯示漸變;s 指定單個圓點的大胁苷獭柏锄;默認(rèn)情況下在圓點的外周會有一個黑色的邊框,可以通過edgecolor='none'來取消邊框或通過其他值來改變顏色滔以。

x = list(range(1, 1001))
y = [e*e for e in x]

# 第一行顏色指定為紅色蝗锥,第二行顏色為(R, G, B)值
# 第三行通過引用 cmp( color map)關(guān)鍵詞引入漸變
#plt.scatter(x, y, c='red', edgecolor='none', s=20) 
#plt.scatter(x, y, c=(0, 0, 0.8), edgecolor='none', s=5)
plt.scatter(x, y, c=y, cmap=plt.cm.Blues, edgecolor='none', s=5)

# Set chart title and label axes
plt.title("Square Numbers", fontsize=20)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)

# Set size of tick labels
plt.tick_params(axis='both', which='major', labelsize=14)

# Set the range for each axis
plt.axis([0, 1100, 0, 1100000])
plt.show()
gradient color

參考閱讀

  1. Matplotlib website - The Matplotlib FAQ

  2. Matplotlib website - pyplot tutorial

  3. Chris Moffitt - Effective matplotlib

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市轨蛤,隨后出現(xiàn)的幾起案子蜜宪,更是在濱河造成了極大的恐慌,老刑警劉巖祥山,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件圃验,死亡現(xiàn)場離奇詭異,居然都是意外死亡缝呕,警方通過查閱死者的電腦和手機澳窑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來供常,“玉大人摊聋,你說我怎么就攤上這事≌幌荆” “怎么了麻裁?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我悲立,道長鹿寨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任薪夕,我火速辦了婚禮脚草,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘原献。我一直安慰自己馏慨,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布姑隅。 她就那樣靜靜地躺著写隶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪讲仰。 梳的紋絲不亂的頭發(fā)上慕趴,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天,我揣著相機與錄音鄙陡,去河邊找鬼冕房。 笑死,一個胖子當(dāng)著我的面吹牛趁矾,可吹牛的內(nèi)容都是我干的耙册。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼毫捣,長吁一口氣:“原來是場噩夢啊……” “哼详拙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蔓同,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤饶辙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后牌柄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畸悬,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡侧甫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年珊佣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片披粟。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡咒锻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出守屉,到底是詐尸還是另有隱情惑艇,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站滨巴,受9級特大地震影響思灌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恭取,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一泰偿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蜈垮,春花似錦耗跛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至惠猿,卻和暖如春羔砾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背偶妖。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工蜒茄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人餐屎。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓檀葛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親腹缩。 傳聞我的和親對象是個殘疾皇子屿聋,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,969評論 2 355

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