reading Foundations for Analysis with Python Day 8

本系列的第八篇筆記進(jìn)入可視化的內(nèi)容??梢暬彩菙?shù)據(jù)分析重要的階段,這是成果的輸出部分,畢竟“千言萬語不如一張圖”,對于數(shù)據(jù)分析師來說,“好的可視化是會講故事的”,還有就是探索性數(shù)據(jù)分析也會用到數(shù)據(jù)可視化。書中第6章 圖與圖表部分會有兩篇筆記,這一篇是關(guān)于matplotlib庫的,我會實踐條形圖、折線圖、散點圖、箱線圖等。
目錄
- matplotlib入門框架
- 條形圖
- 直方圖
- 折線圖
- 散點圖
- 箱線圖
Python 提供了若干種用于繪圖的擴(kuò)展包,包括 matplotlib、pandas、ggplot 和 seaborn。因為 matplotlib 是最基礎(chǔ)的擴(kuò)展包,它為 pandas 和 seaborn 提供了一些基礎(chǔ)的繪圖概念和語法,所以這里先介紹 matplotlib。然后,我們通過一些示例,看看其他擴(kuò)展包如何提供更簡潔的繪圖語法,或者提供一些額外的功能。
matplotlib入門框架
一個簡單的用matplotlib畫圖的框架如下,在jupyter中可以加入 %matplotlib inline 這一句,如果是寫成.py的腳本,就移除這一句,在畫圖后寫plt.show(),通過plt.savefig()可以保存圖片到本地。
def matplotlibFrame():
import matplotlib.pyplot as plt #引入pyplot庫
%matplotlib inline
#%matplotlib inline是jupyter自帶的方式,允許圖表在cell中輸出,不需要再寫plt.show()
plt.style.use('ggplot') #使用R語言中的ggplot2配色作為繪圖風(fēng)格,純粹為了好看。
sale_amounts = [127, 90, 201, 111, 232]
fig = plt.figure() #創(chuàng)建一個基礎(chǔ)圖,然后在基礎(chǔ)圖中創(chuàng)建一個或多個子圖
ax1 = fig.add_subplot(1,1,1)
ax1.bar(range(len(sale_amounts)), sale_amounts, align='center', color='darkblue')
#plt.savefig('bar_plot.png', dpi=400, bbox_inches='tight')
#通過plt.savefig()可以保存圖片到本地
matplotlibFrame()
輸出:

需要注意的是 pyplot并不默認(rèn)支持中文顯示,需要rcParams修改字體實現(xiàn),或者在有中文輸出的地方,增加一個屬性:
fontproperties eg:plt.ylebel(“時間(s)”,fontproperties=”SimHei”,fontsize=20)
matplotlib的pyplot子庫提供了很多類型的基礎(chǔ)圖形:
- plt.boxplot (data,notch,position) #繪制箱形圖#
- plt.bar(left,height,width,bottom) #繪制條形圖#
- plt.barh(width,bottom,left,height) #繪制橫向條形圖#
- plt.polar(theta, r) #繪制極坐標(biāo)圖#
- plt.pie(data, explode) #繪制餅圖#
- plt.hist() #繪制直方圖#
條形圖
下面我們增加一些代碼畫元素更豐富的條形圖。
#條形圖
def basicBarPlot():
import matplotlib.pyplot as plt
plt.style.use('ggplot')
customers = ['Alice', 'Bob', 'Carol', 'Dave', 'Eve'] #橫軸標(biāo)簽,某類樹洞的梗
customers_index = range(len(customers))
sale_amounts = [127, 90, 201, 111, 232] #條形圖的高度,數(shù)據(jù)高度
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax1.bar(customers_index, sale_amounts, align='center', color='darkblue') #align設(shè)置條形與標(biāo)簽中間對齊。color設(shè)置條形的顏色。
ax1.xaxis.set_ticks_position('bottom') #設(shè)置刻度線位置在 x 軸底部和 y 軸左側(cè)
ax1.yaxis.set_ticks_position('left')
plt.xticks(customers_index, customers, rotation=0, fontsize='small')
#fontsize='small' 將刻度標(biāo)簽的字體設(shè)為小字體。
plt.xlabel('Customer Name')
plt.ylabel('Sale Amount')
plt.title('Sale Amount per Customer')
#plt.savefig('bar_plot.png', dpi=400, bbox_inches='tight')
plt.show() #display
basicBarPlot()
輸出:

直方圖
常用的直方圖包括頻率分布、頻率密度分布、概率分布和概率密度分布。
#頻率直方圖
def histogram():
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
mu1, mu2, sigma = 100, 130, 15
x1 = mu1 + sigma*np.random.randn(10000)
x2 = mu2 + sigma*np.random.randn(10000)
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
n, bins, patches = ax1.hist(x1, bins=50, normed=False, color='darkgreen')
n, bins, patches = ax1.hist(x2, bins=50, normed=False, color='orange', alpha=0.5)
#上面分別畫兩個直方圖
ax1.xaxis.set_ticks_position('bottom')
ax1.yaxis.set_ticks_position('left')
plt.xlabel('Bins')
plt.ylabel('Number of Values in Bin')
fig.suptitle('Histograms', fontsize=14, fontweight='bold') #為基礎(chǔ)圖添加一個居中的標(biāo)題
ax1.set_title('Two Frequency Distributions')
#plt.savefig('histogram.png', dpi=400, bbox_inches='tight')
plt.show()
histogram()
輸出:

折線圖
折線圖中的數(shù)值點在一條折線上。它通常用來表示數(shù)據(jù)隨著時間發(fā)生的變化。
#折線圖
def linePlot():
from numpy.random import randn
import matplotlib.pyplot as plt
plt.style.use('ggplot')
plot_data1 = randn(30).cumsum() #生成隨機(jī)數(shù)據(jù)
plot_data2 = randn(30).cumsum()
plot_data3 = randn(30).cumsum()
plot_data4 = randn(30).cumsum()
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax1.plot(plot_data1, marker=r'o', color=u'blue', linestyle='-', label='Blue Solid')
ax1.plot(plot_data2, marker=r'+', color=u'red', linestyle='--', label='Red Dashed')
ax1.plot(plot_data3, marker=r'*', color=u'green', linestyle='-.', label='Green Dash Dot')
ax1.plot(plot_data4, marker=r's', color=u'orange', linestyle=':', label='Orange Dotted')
#分別建立4條不同的折線到同一個圖中
ax1.xaxis.set_ticks_position('bottom')
ax1.yaxis.set_ticks_position('left')
ax1.set_title('Line Plots: Markers, Colors, and Linestyles')
plt.xlabel('Draw')
plt.ylabel('Random Number')
plt.legend(loc='best')
plt.show()
linePlot()
輸出:

散點圖
散點圖非常適合展示兩個數(shù)值變量之間的關(guān)系,因為可以直接看到數(shù)據(jù)的原始分布,當(dāng)然主要是針對二維數(shù)據(jù),如果是高維數(shù)據(jù),需要降維。這兩個變量分別位于兩個數(shù)軸上。散點圖有助于識別出變量之間是否具有正相關(guān)(圖中的點集中于某個具體參數(shù))或負(fù)相關(guān)(圖中的點像云一樣發(fā)散)。 numpy 的 polyfit 函數(shù)可以對二維數(shù)組進(jìn)行擬合。
#散點圖
def scatterPlot():
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
x = np.arange(start=1., stop=15., step=1.)
y_linear = x + 5. * np.random.randn(14) #同樣用到隨機(jī)數(shù)據(jù)
y_quadratic = x**2 + 10. * np.random.randn(14)
fn_linear = np.poly1d(np.polyfit(x, y_linear, deg=1)) #擬合
fn_quadratic = np.poly1d(np.polyfit(x, y_quadratic, deg=2))
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax1.plot(x, y_linear, 'bo', x, y_quadratic, 'go',x, fn_linear(x), 'b-', x, fn_quadratic(x), 'g-', linewidth=2.)
#'bo' 表示 (x, y_linear)點是藍(lán)色圓圈,'go' 表示 (x, y_quadratic) 點是綠色圓圈。同樣,'b-' 表示 (x, y_linear) 點之間的線是
#一條藍(lán)色實線,'g-' 表示 (x, y_quadratic) 點之間的線是一條綠色實線。通過 linewidth可設(shè)置線的寬度。
ax1.xaxis.set_ticks_position('bottom')
ax1.yaxis.set_ticks_position('left')
ax1.set_title('Scatter Plots with Best Fit Lines')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.xlim((min(x)-1., max(x)+1.))
plt.ylim((min(y_quadratic)-10., max(y_quadratic)+10.))
plt.savefig('scatter_plot.png', dpi=400, bbox_inches='tight')
plt.show()
scatterPlot()
輸出:

箱線圖
箱線圖在探索性數(shù)據(jù)分析中經(jīng)常用到,能表達(dá)的信息很多。箱線圖可以表示出數(shù)據(jù)的最小值、第一四分位數(shù)、中位數(shù)、第三四分位數(shù)和最大值。箱體的下部和上部邊緣線分別表示第一四分位數(shù)和第三四分位數(shù),箱體中間的直線表示中位數(shù)。箱體上下兩端延伸出去的直線(whisker,亦稱為“須” )表示非離群點的最小值和最大值,在直線(須)之外的點表示離群點。
#箱線圖
def basicBoxPlot():
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
N = 500
normal = np.random.normal(loc=0.0, scale=1.0, size=N)
lognormal = np.random.lognormal(mean=0.0, sigma=1.0, size=N)
index_value = np.random.randint(low=0, high=N-1, size=N)
normal_sample = normal[index_value]
lognormal_sample = lognormal[index_value]
box_plot_data = [normal,normal_sample,lognormal,lognormal_sample]
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
box_labels = ['normal','normal_sample','lognormal','lognormal_sample']
ax1.boxplot(box_plot_data, notch=False, sym='.', vert=True, whis=1.5,showmeans=True, labels=box_labels)
#畫箱線圖
ax1.xaxis.set_ticks_position('bottom')
ax1.yaxis.set_ticks_position('left')
ax1.set_title('Box Plots: Resampling of Two Distributions')
ax1.set_xlabel('Distribution')
ax1.set_ylabel('Value')
#plt.savefig('box_plot.png', dpi=400, bbox_inches='tight')
plt.show()
basicBoxPlot()
輸出:

這篇筆記因為有比較多的圖表,我感覺挺賞心悅目的,matplotlib繪圖也不是很難,效果和可定制性都很好,matplotlib庫還有很多強(qiáng)大和細(xì)致的功能,需要深入學(xué)習(xí)可以參考官方文檔。Python里面還有其他很有特色的可視化庫,例如ggplot、plotnine和seaborn,下一篇筆記會介紹這些可視化庫。
ps:書中沒有講到地理數(shù)據(jù)可視化,地理數(shù)據(jù)可視化也是非常有用和美妙的。
本篇筆記的GitHub同步項目于readingForDS。關(guān)于本系列筆記有任何建議歡迎留言討論。