matplotlib學(xué)習(xí)筆記

數(shù)據(jù)分析-可視化工具matplotlib

一、數(shù)據(jù)分析的流程

提出問題:明確想干什么;

②準(zhǔn)備數(shù)據(jù):將數(shù)據(jù)取出,進(jìn)行預(yù)處理,以獲得我們需要的數(shù)據(jù);

③分析數(shù)據(jù):使用工具、模型對(duì)數(shù)據(jù)進(jìn)行分析;

④獲得結(jié)論;

⑤結(jié)論可視化:將結(jié)論以圖的形式展現(xiàn),使分析結(jié)果清晰明了、易懂;

二、對(duì)比常用統(tǒng)計(jì)圖

(1)折線圖

以折線(線條)的上升下降來表示統(tǒng)計(jì)數(shù)量的增減變化的統(tǒng)計(jì)圖,特點(diǎn)是:能夠顯示數(shù)據(jù)的變化趨勢(shì),反映事物隨某個(gè)變量(如時(shí)間)的變化情況。簡單的折線圖如下:(源自matplotlib官網(wǎng))

圖一、折線圖示例

(2)直方圖

直方圖又稱質(zhì)量分布圖,是表示資料變化情況的重要工具。直方圖由一系列高度不同的縱向條紋或者線段表示數(shù)據(jù)的分布情況,一般用橫軸表示數(shù)據(jù)范圍,用縱軸表示分布情況。例如用直方圖表示某學(xué)校各個(gè)年齡段各有多少人。繪制直方圖需要確定組數(shù)和組距,即將數(shù)據(jù)分為多少組,相鄰兩組之間的間隔是多少,比如繪制(年齡-人數(shù))的直方圖時(shí),設(shè)置組距為5,即每一組的范圍分別為(05歲)、(610歲)....組數(shù)=(max(x)-min(x))/組距。組距的選擇十分重要,通常情況下,應(yīng)該盡量選擇合適的組距使組數(shù)為整數(shù)。

直方圖也分為頻數(shù)直方圖和頻率直方圖,即縱軸分別表示該組的數(shù)量和頻率。

特點(diǎn):繪制連續(xù)性的數(shù)據(jù),展示一組或者多組數(shù)據(jù)的分布情況。直方圖示例如下:(來自matplotlib官網(wǎng))

圖二、直方圖示例

(3)條形圖

條形圖是用來顯示各個(gè)不同的事物對(duì)于某一個(gè)共同屬性的比較情況,例如已知2019年各個(gè)城市的GDP,那么用條形圖可以很直觀的展示各個(gè)城市的GDP情況以及他們的對(duì)比關(guān)系。

特點(diǎn):繪制離散的數(shù)據(jù),能夠一眼看出各個(gè)數(shù)據(jù)的大小,比較數(shù)據(jù)之間的差別。條形圖示例如下:(來自matplotlib官網(wǎng))

圖三、條形圖示例

(4)散點(diǎn)圖

散點(diǎn)圖表示在回歸分析中,數(shù)據(jù)點(diǎn)在直角坐標(biāo)系的分布情況。繪制散點(diǎn)圖時(shí),用兩組數(shù)據(jù)構(gòu)成多個(gè)坐標(biāo)點(diǎn),考察坐標(biāo)點(diǎn)的分布,判斷兩個(gè)變量之間是否存在某種關(guān)聯(lián)或者總結(jié)坐標(biāo)點(diǎn)的分布模式、分布情況。

特點(diǎn):判斷變量之間是否存在數(shù)量關(guān)聯(lián)趨勢(shì),展示離群點(diǎn)(分布規(guī)律)散點(diǎn)圖示例如下:(來自matplotlib官網(wǎng))

圖四、散點(diǎn)圖示例

三、matplotlib繪制常用統(tǒng)計(jì)圖

(1)繪制折線圖

案例一:

假設(shè)一天中每個(gè)兩個(gè)小時(shí)的氣溫分別是:15,13,14.5,17,20,25,26,26,26,27,22,18,15;使matplotlib畫出該圖形。代碼如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

# 數(shù)據(jù)在x軸的位置,是一個(gè)可迭代對(duì)象

x =range(2, 26, 2)

y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15]

plt.plot(x, y)

plt.show()

運(yùn)行之后結(jié)果如下圖:

圖五、折線圖案例一結(jié)果

在上圖中,我們通過對(duì)函數(shù)plt.plot()傳入兩個(gè)列表參數(shù)x, y,便可以繪制折線圖,然后調(diào)用函數(shù)plt.show()將繪制結(jié)果顯示出來。但是通過觀察上圖,發(fā)現(xiàn)還存在一下問題:

①圖片大小不夠

②圖片沒有描述信息

③x,y軸的刻度顯示不明確(刻度間距不合適)

④線條樣式可能不合適

針對(duì)上述問題,修改代碼如下所示:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

# 設(shè)置圖片大小,以及dpi

plt.figure(figsize=(10, 8), dpi=80)

# 設(shè)置字體顯示為指定的文件(windows路徑為:)適用于各種操作系統(tǒng)

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

# 數(shù)據(jù)在x軸的位置,是一個(gè)可迭代對(duì)象

x =range(2, 26, 2)

y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15]

plt.plot(x, y)

# 設(shè)置x軸的刻度 可以傳一個(gè)range(),也可以傳一個(gè)列表, 列表元素為坐標(biāo)軸各點(diǎn)的值

plt.xticks(x)

# plt.xticks(range(2, 25))

# 設(shè)置y軸的刻度

plt.yticks(range(min(y), max(y)+1))

# 設(shè)置x,y軸的標(biāo)簽以及圖片標(biāo)題

plt.xlabel("時(shí)間", fontproperties=my_font)

plt.ylabel("溫度(℃)", fontproperties=my_font)

plt.title("一天中氣溫變化情況(每隔兩小時(shí))", fontproperties=my_font)

# 保存圖片在繪制之后

# 可以保存為.svg這種矢量圖格式,放大之后不會(huì)有鋸齒

plt.savefig("./p1.png")

plt.show()

運(yùn)行結(jié)果如下:

圖六、折線圖案例一改良結(jié)果

案例二:

如果列表a表示十點(diǎn)到十一點(diǎn)兩個(gè)小時(shí)之間每一分鐘氣溫的變化,繪圖表示。

代碼如下:


from matplotlib import pyplot as plt

from matplotlib import font_manager

import random

# 設(shè)置圖片大小,以及dpi

plt.figure(figsize=(10, 8), dpi=80)

# 設(shè)置字體顯示為指定的文件(windows路徑為:)適用于各種操作系統(tǒng)my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

x = range(0, 120)

y = [random.randint(25, 30)for i in range(120)]

plt.plot(x, y)

# 調(diào)整x軸的刻度_x = list(x)  # 只有列表才能取步長,所以進(jìn)行強(qiáng)制轉(zhuǎn)換_xtick_labels = ["10點(diǎn){}分".format(i)for i in range(60)]

_xtick_labels += ["11點(diǎn){}分".format(i)for i in range(60)]

plt.xticks(_x[::5], _xtick_labels[::5], rotation=45, fontproperties=my_font)  # 取步長為5,旋轉(zhuǎn)270度,rotation表示旋轉(zhuǎn)的度數(shù)# 添加描述信息plt.xlabel("時(shí)間", fontproperties=my_font)

plt.ylabel("溫度 單位(℃)", fontproperties=my_font)

plt.title("10點(diǎn)到12點(diǎn)每分鐘的氣溫變化情況", fontproperties=my_font)

plt.show()

結(jié)果如下圖:

圖七、折線圖案例二結(jié)果

案例三:

假設(shè)大家在30歲的時(shí)候,根據(jù)自己的實(shí)際情況統(tǒng)計(jì)出來了11歲到30歲每年交的男女朋友的數(shù)量如列表[1,0,1,1,3,4,3,2,3,4,4,5,6,5,4,3,3,1,1,1] ,以及某位朋友的上述情況列表[0,2,3,5,2,1, 1,0,3,4,6,3,1,1,0,2,1,1,3,2]。請(qǐng)繪制出該數(shù)據(jù)的折線圖,以便分析每年交男女朋友的數(shù)量走勢(shì)。

代碼如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

# 設(shè)置字體

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

# 設(shè)置圖的大小

plt.figure(figsize=(14, 7), dpi=80)

x =range(11, 31)

y = [1, 0, 1, 1, 3, 4, 3, 2, 3, 4, 4, 5, 6, 5, 4, 3, 3, 1, 1, 1]

y1 = [0, 2, 3, 5, 2, 1, 1, 0, 3, 4, 6, 3, 1, 1, 0, 2, 1, 1, 3, 2]

plt.plot(x, y, label="自己", color="orange", linestyle=":")

plt.plot(x, y1, label="同桌", color="cyan", linestyle="--")

# 設(shè)置x軸顯示信息

x_labels = ["{}歲".format(i)for i in range(11, 31)]

_x =list(x)

plt.xticks(_x, x_labels, fontproperties=my_font)

plt.yticks(range(min(y), max(y)+2))

# 繪制網(wǎng)格

plt.grid(alpha=0.5)# alpha 表示透明度

# 添加描述信息

plt.xlabel("年齡(歲)", fontproperties=my_font)

plt.ylabel("男(女)朋友數(shù)量(個(gè))", fontproperties=my_font)

plt.title("11歲到30歲每年所處對(duì)象的數(shù)量走勢(shì)圖", fontproperties=my_font)

# 添加圖例

# 調(diào)用此方法之后,程序會(huì)結(jié)合plt.plot()方法中的label參數(shù)顯示出圖例

# 此方法接收字體的參數(shù)為prop

plt.legend(prop=my_font)

plt.show()

結(jié)果如下:

圖八、折線圖案例三結(jié)果

plt.plot()方法的參數(shù):

@ label: 用來在plt.legend()方法調(diào)用時(shí)設(shè)置圖例

@ color: 設(shè)置線條顏色

@ linestyle: 設(shè)置線條風(fēng)格

@ linewidth: 設(shè)置線條粗細(xì)

matplotlib折線圖總結(jié):

·繪制折線圖(plt.plot()方法)

·設(shè)置圖片大小和分辨率(plt.figure()方法)

·實(shí)現(xiàn)圖片保存(plt.savefig()方法)

·設(shè)置xy軸的刻度和字符串(plt.xticks())

·解決刻度稀疏或者密集的問題(plt.xticks()方法)

·設(shè)置標(biāo)題、xy軸的label(title,xlabel,ylabel)

·設(shè)置字體(font_manager類,結(jié)合fontproperties參數(shù))

·添加圖例(plt.plot(label=”xx”),plt.legend()方法)

(2)繪制散點(diǎn)圖

案例:

假設(shè)你通過爬蟲獲取到了北京2016年3,10月份每天白天的最高氣溫(分別位于列表a,b)那么此時(shí)如何尋找出氣溫隨時(shí)間變化的某種規(guī)律?

代碼如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

# 設(shè)置圖片大小,設(shè)置分辨率

plt.figure(figsize=(14, 9), dpi=80)

y_3 = [11, 17, 16, 11, 12, 11, 6, 6, 7, 8, 9, 12, 15, 14, 17, 18

    ,21, 16, 17, 20, 14, 15, 15, 15, 19, 21, 22, 22, 22, 23, 21]

y_10 = [26, 26, 28, 19, 21, 17, 16, 19, 18, 20, 20, 19, 22, 23, 17,

    20, 21, 20, 22, 15, 11, 15, 5, 13, 17, 10, 11, 13, 12, 13, 6]

x_3 =range(1, 32)

x_10 =range(40, 71)

# 繪制

plt.scatter(x_3, y_3, label="三月")

plt.scatter(x_10, y_10, label="十月")

# 調(diào)整x軸刻度

_x =list(x_3) +list(x_10)

_xticks_labels = ["3月{}日".format(i)for i in x_3]

_xticks_labels += ["10月{}日".format(i)for i in x_10]

plt.xticks(_x[::3], _xticks_labels[::3], fontproperties=my_font, rotation=45, fontsize=12)

# 設(shè)置附加信息

plt.xlabel("時(shí)間", fontproperties=my_font, fontsize=14)

plt.ylabel("溫度(℃)", fontproperties=my_font, fontsize=14)

plt.title("三月與十月的最高氣溫趨勢(shì)圖", fontproperties=my_font, fontsize=14)

# 添加圖例

plt.legend(prop=my_font)

plt.show()

結(jié)果如下:

圖九、散點(diǎn)圖案例結(jié)果

(3)繪制條形圖

案例一:

假設(shè)你獲取到了2017年內(nèi)地電影票房前20的電影列表a和電影票房數(shù)據(jù)列表b,那么如何更加直觀的展示該數(shù)據(jù)?

代碼如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

a = ["戰(zhàn)狼2", "速度與激情8", "功夫瑜伽", "西游伏妖篇", "變形金剛", "最后的騎士",

    "摔跤吧爸爸", "加勒比海盜5:死無對(duì)證", "金剛:骷髏島", "極限特工:終極回歸",

    "生化危機(jī)6:終章", "乘風(fēng)破浪", "神偷奶爸3", "智取威虎山", "大鬧天竺", "金剛狼3:殊死一戰(zhàn)",

    "蜘蛛俠:英雄歸來", "悟空傳", "銀河護(hù)衛(wèi)隊(duì)", "情圣"]

b = [56.01, 26.94, 17.53, 16.49, 15.45, 12.96, 11.8, 11.61, 11.28, 11.12,

10.49, 10.3, 8.75, 7.55, 7.32, 6.99, 6.88, 6.86, 6.58, 6.32]

plt.figure(figsize=(15, 10), dpi=80)

# 豎著的條形圖# plt.bar(range(len(a)), b)

# plt.xticks(range(len(a)), a, fontproperties=my_font, rotation=90)

# 橫著的條形圖# 某些情況下橫著的條形圖比豎著的好看plt.barh(range(len(a)), b, height=0.3)

# 設(shè)置附加信息plt.xlabel("票房 單位(億)", fontproperties=my_font)

# y軸刻度信息plt.yticks(range(len(a)), a, fontproperties=my_font)

plt.grid(alpha=0.3)

plt.show()

結(jié)果如下:

圖十、條形圖案例一結(jié)果

案例二:

假設(shè)你知道了列表a中電影分別在2017-09-14(b_14),2017-09-15(b_15),2017-09-16三天的票房,為了展示列表中電影本身的票房以及同其他電影數(shù)據(jù)的對(duì)比情況,應(yīng)該如何更加直觀的呈現(xiàn)該數(shù)據(jù)?

代碼如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

plt.figure(figsize=(14, 9), dpi=80)

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

a = ["星球崛起3", "敦刻爾克", "蜘蛛俠", "戰(zhàn)狼2"]

b_16 = [15746, 312, 4497, 319]

b_15 = [12357, 156, 2045, 168]

b_14 = [2358, 399, 2358, 362]

x_14 =list(range(len(a)))

x_15 = [i +0.3 for i in x_14]

x_16 = [i +0.3*2 for i in x_14]

print(len(x_14))

plt.bar(x_14, b_14, width=0.3, label="2017-09-14")

plt.bar(x_15, b_15, width=0.3, label="2017-09-15")

plt.bar(x_16, b_16, width=0.3, label="2017-09-16")

# 設(shè)置x軸的刻度

plt.xticks(list(x_15), a, fontproperties=my_font, fontsize=12)

# 設(shè)置圖例

plt.legend()

plt.show()

注意:為了使條形圖不重疊,應(yīng)當(dāng)使每個(gè)條形的位置向右偏移一定距離,并且滿足:

條形寬度*條形數(shù)量<1,比如上述代碼中的x_14,x_15,x_16的設(shè)置。

結(jié)果如下:

圖十一、條形圖案例二結(jié)果

(4)繪制直方圖

直方圖的應(yīng)用場(chǎng)景:

·用戶的年齡狀態(tài)

·一段時(shí)間內(nèi)用戶點(diǎn)擊次數(shù)的分布狀態(tài)

·用戶活躍時(shí)間的分布狀態(tài)

案例一:

頻數(shù)分布直方圖,假設(shè)你獲取了250部電影的時(shí)長列表a,希望統(tǒng)計(jì)出這些電影時(shí)長的分布狀態(tài)(比如時(shí)長為100分鐘到120分鐘的電影的數(shù)量,出現(xiàn)的頻率)等信息,你應(yīng)該如何呈現(xiàn)這些數(shù)據(jù)?(ps: 由于數(shù)據(jù)量比較大,因此使用隨機(jī)數(shù)模擬上述數(shù)據(jù))

代碼如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

import random

# 設(shè)置組距為5,設(shè)置組距的時(shí)候應(yīng)該注意盡量使(max(a)-min(a))能夠整除組距

dis =5

a = [random.randint(80, 150)for i in range(251)]

# 組數(shù)

num_bin = (max(a)-min(a))//dis

plt.hist(a, num_bin)# 參數(shù)normed=1表示畫出的圖形是頻率分布直方圖

# 設(shè)置x軸的刻度

plt.xticks(range(min(a), max(a)+dis, dis))

plt.grid()

plt.show()

注:在組數(shù)為正整數(shù)的情況下,圖形能正確繪制,當(dāng)實(shí)際組數(shù)為小數(shù)時(shí)(即(max(a)-min(a))/dis為小數(shù)),獲得的圖形會(huì)有一定的偏移(如圖十四,組數(shù)實(shí)際為小數(shù))。解決方法為調(diào)整組距,使組數(shù)為正整數(shù)。

結(jié)果為:

圖十二、直方圖案例一結(jié)果
圖十三、直方圖案例一異常情況

案例二:

在美國 2004的人口普查發(fā)現(xiàn)有124million的人在離家較遠(yuǎn)的地方工作。根據(jù)他們從家里到上班地點(diǎn)所需要的時(shí)間,通過抽樣統(tǒng)計(jì)列出了下表的數(shù)據(jù),這些數(shù)據(jù)能夠繪制成直方圖嗎?

interval = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 60, 90] (表示各個(gè)區(qū)間)

width = [5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 30, 60] (表示區(qū)間寬度)

quantity = [836, 2737, 3723, 3926, 3596, 1438, 3273, 642, 824, 613, 215, 47] (各區(qū)間頻數(shù))

分析:由于數(shù)據(jù)以及被統(tǒng)計(jì)好了,因此不能直接使用直方圖畫圖函數(shù)plt.hist(),該函數(shù)會(huì)在使用時(shí)分析一遍各個(gè)區(qū)間的頻數(shù)。(但是理論上如果用隨機(jī)數(shù)來模擬原始數(shù)據(jù),應(yīng)該可以用直方圖畫圖函數(shù)來繪制出圖形)。由于數(shù)據(jù)已經(jīng)統(tǒng)計(jì)好,因此直接使用條形圖,使條形圖的線條寬度占滿x軸的一個(gè)區(qū)間,即圖形直觀上是直方圖。

代碼如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

import random

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

# 只需要設(shè)置條形圖的寬度為1即可

plt.figure(figsize=(12, 8), dpi=80)

interval = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 60, 90]

width = [5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 30, 60]

quantity = [836, 2737, 3723, 3926, 3596, 1438, 3273, 642, 824, 613, 215, 47]

plt.bar(range(12), quantity, width=1)

_x = [i -0.5 for iin range(13)]

_xlabels = interval + [150]

plt.xticks(_x, _xlabels)

plt.ylabel("人數(shù)", fontproperties=my_font, fontsize=12)

plt.xlabel("時(shí)間", fontproperties=my_font, fontsize=12)

plt.grid()

plt.show()

圖十四、直方圖案例二結(jié)果

四、總結(jié)

matplotlib使用流程:

·明確問題

·選擇圖形的呈現(xiàn)形式

·準(zhǔn)備數(shù)據(jù)

·繪圖和圖形完善

matplotlib更多圖形樣式:

百度echart(前端應(yīng)用,使用js)。

plotly:可視化工具,兼容matplotlib和pandas。(需要付費(fèi))

<本文檔記錄個(gè)人學(xué)習(xí)matplotlib繪圖工具過程的總結(jié)!若有不當(dāng)之處歡迎指正! >

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容