日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Matplotlib画各种图

發布時間:2023/12/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Matplotlib画各种图 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

版權聲明:本文為博主原創文章,未經博主允許不得轉載。?https://blog.csdn.net/kun1280437633/article/details/80841364

看本文前,請看matlplotlib使用教程?https://blog.csdn.net/kun1280437633/article/details/80370622,有基礎請忽略

Matplotlib制作動畫https://blog.csdn.net/kun1280437633/article/details/108483384

matplotlib(條形圖)

一、簡單垂直條形圖


?

案例一:直轄市GDP水平

中國的四個直轄市分別為北京市、上海市、天津市和重慶市,其2017年上半年的GDP分別為12406.8億、13908.57億、9386.87億、9143.64億。對于這樣一組數據,我們該如何使用條形圖來展示各自的GDP水平呢?

# 導入繪圖模塊 import matplotlib.pyplot as plt # 構建數據 GDP = [12406.8,13908.57,9386.87,9143.64] # 中文亂碼的處理 plt.rcParams['font.sans-serif'] =['Microsoft YaHei'] plt.rcParams['axes.unicode_minus'] = False # 繪圖 plt.bar(range(4), GDP, align = 'center',color='steelblue', alpha = 0.8) # 添加軸標簽 plt.ylabel('GDP') # 添加標題 plt.title('四個直轄市GDP大比拼') # 添加刻度標簽 plt.xticks(range(4),['北京市','上海市','天津市','重慶市']) # 設置Y軸的刻度范圍 plt.ylim([5000,15000]) # 為每個條形圖添加數值標簽 for x,y in enumerate(GDP):plt.text(x,y+100,'%s' %round(y,1),ha='center') # 顯示圖形 plt.show()

代碼解讀

  • 由于matplotlib對中文的支持并不是很友好,所以需要提前對繪圖進行字體的設置,即通過rcParams來設置字體,這里將字體設置為微軟雅黑,同時為了避免坐標軸不能正常的顯示負號,也需要進行設置;

  • bar函數指定了條形圖的x軸、y軸值,設置x軸刻度標簽為水平居中,條形圖的填充色color為鐵藍色,同時設置透明度alpha為0.8;

  • 添加y軸標簽、標題、x軸刻度標簽值,為了讓條形圖顯示各柱體之間的差異,將y軸范圍設置在5000~15000;

  • 通過循環的方式,添加條形圖的數值標簽;

二、簡單水平條形圖

?

案例二:同一本書不同平臺最低價比較

很多人在買一本書的時候,都比較喜歡貨比三家,例如《python數據分析實戰》在亞馬遜、當當網、中國圖書網、京東和天貓的最低價格分別為39.5、39.9、45.4、38.9、33.34。針對這個數據,我們也可以通過條形圖來完成,這里使用水平條形圖來顯示:

# 導入繪圖模塊 import matplotlib.pyplot as plt # 構建數據 price = [39.5,39.9,45.4,38.9,33.34] # 中文亂碼的處理 plt.rcParams['font.sans-serif'] =['Microsoft YaHei'] plt.rcParams['axes.unicode_minus'] = False # 繪圖 plt.barh(range(5), price, align = 'center',color='steelblue', alpha = 0.8) # 添加軸標簽 plt.xlabel('價格') # 添加標題 plt.title('不同平臺書的最低價比較') # 添加刻度標簽 plt.yticks(range(5),['亞馬遜','當當網','中國圖書網','京東','天貓']) # 設置Y軸的刻度范圍 plt.xlim([32,47]) # 為每個條形圖添加數值標簽 for x,y in enumerate(price):plt.text(y+0.1,x,'%s' %y,va='center') # 顯示圖形 ? ? plt.show()

代碼解讀

  • 水平條形圖的繪制與垂直條形圖的繪制步驟一致,只是調用了barh函數來完成。需要注意的是,條形圖的數值標簽設置有一些不一樣,需要將標簽垂直居中顯示,使用va參數即可。

三、水平交錯條形圖

?

以上講的簡單垂直和水平條形圖是基于一種離散變量的情況,針對兩種離散變量的條形圖我們可以使用水平交錯條形圖和堆疊條形圖,下面我們就來看看這兩種條形圖是如何繪制的。

案例三:胡潤財富榜:億萬資產超高凈值家庭數

利用水平交錯條形圖對比2016年和2017年億萬資產超高凈值家庭數(top5),其數據如下:

# 導入繪圖模塊 import matplotlib.pyplot as pltimport numpy as np # 構建數據Y2016 = [15600,12700,11300,4270,3620] Y2017 = [17400,14800,12000,5200,4020] labels = ['北京','上海','香港','深圳','廣州'] bar_width = 0.45 # 中文亂碼的處理 plt.rcParams['font.sans-serif'] =['Microsoft YaHei'] plt.rcParams['axes.unicode_minus'] = False # 繪圖 plt.bar(np.arange(5), Y2016, label = '2016', color = 'steelblue', alpha = 0.8, width = bar_width) plt.bar(np.arange(5)+bar_width, Y2017, label = '2017', color = 'indianred', alpha = 0.8, width = bar_width) # 添加軸標簽 plt.xlabel('Top5城市') plt.ylabel('家庭數量') # 添加標題 plt.title('億萬財富家庭數Top5城市分布') # 添加刻度標簽 plt.xticks(np.arange(5)+bar_width,labels) # 設置Y軸的刻度范圍 plt.ylim([2500, 19000]) # 為每個條形圖添加數值標簽 for x2016,y2016 in enumerate(Y2016):plt.text(x2016, y2016+100, '%s' %y2016)for x2017,y2017 in enumerate(Y2017):plt.text(x2017+bar_width, y2017+100, '%s' %y2017) # 顯示圖例 plt.legend() # 顯示圖形 plt.show()

代碼解讀

  • 水平交錯條形圖繪制的思想很簡單,就是在第一個條形圖繪制好的基礎上,往左移一定的距離,再去繪制第二個條形圖,所以在代碼中會出現兩個bar函數;

  • 圖例的繪制需要在bar函數中添加label參數;color和alpha參數分別代表條形圖的填充色和透明度;

  • 給條形圖添加數值標簽,同樣需要使用兩次for循環的方式實現;

四、垂直堆疊條形圖


???????

垂直堆疊條形圖的繪制思想與水平交錯條形圖一樣,只不過一個是向上偏移,一個是往左偏移,具體我們以案例說明。

案例四:2017年物流運輸量情況分布

# 導入模塊 import matplotlib.pyplot as plt import numpy as np import pandas as pd# 導入數據 data = pd.read_excel('C:\\Users\\Administrator\\Desktop\\貨運.xls')# 繪圖 plt.bar(np.arange(8), data.loc[0,:][1:], color = 'red', alpha = 0.8, label = '鐵路', align = 'center') plt.bar(np.arange(8), data.loc[1,:][1:], ?bottom = data.loc[0,:][1:], color = 'green', alpha = 0.8, label = '公路', align = 'center') plt.bar(np.arange(8), data.loc[2,:][1:], ?bottom = data.loc[0,:][1:]+data.loc[1,:][1:], color = 'm', alpha = 0.8, label = '水運', align = 'center') plt.bar(np.arange(8), data.loc[3,:][1:], ?bottom = data.loc[0,:][1:]+data.loc[1,:][1:]+data.loc[2,:][1:], color = 'black', alpha = 0.8, label = '民航', align = 'center') # 添加軸標簽 plt.xlabel('月份') plt.ylabel('貨物量(萬噸)') # 添加標題 plt.title('2017年各月份物流運輸量') # 添加刻度標簽 plt.xticks(np.arange(8),data.columns[1:]) # 設置Y軸的刻度范圍 plt.ylim([0,500000])# 為每個條形圖添加數值標簽 for x_t,y_t in enumerate(data.loc[0,:][1:]):plt.text(x_t,y_t/2,'%sW' %(round(y_t/10000,2)),ha='center', color = 'white')for x_g,y_g in enumerate(data.loc[0,:][1:]+data.loc[1,:][1:]):plt.text(x_g,y_g/2,'%sW' %(round(y_g/10000,2)),ha='center', color = 'white') for x_s,y_s in enumerate(data.loc[0,:][1:]+data.loc[1,:][1:]+data.loc[2,:][1:]):plt.text(x_s,y_s-20000,'%sW' %(round(y_s/10000,2)),ha='center', color = 'white') ? ?# 顯示圖例 plt.legend(loc='upper center', ncol=4) # 顯示圖形 ? ? plt.show()

代碼解讀

  • 垂直條形圖的繪制不僅僅需要提供x,y軸的數值,還需要提供bottom參數,其目的就是在某個條形圖頂端的基礎上,繪制其他條形圖,以此類推可以繪制多個堆疊條形圖;

  • 圖例的位置選擇在了正上方,且設置列數為4,表面圖例以一排的形式展現;

  • 堆疊條形圖的數值標簽,任然是按照y軸方向堆疊的思想,貼上數值標簽值;

  • 由于航空運輸的貨物量非常少,導致圖中幾乎無法顯示;

?

matplotlib(餅圖)

我們用條形圖來展示離散變量的分布呈現,在常見的統計圖像中,還有一種圖像可以表示離散變量各水平占比情況,這就是我們要講解的餅圖。餅圖的繪制可以使用matplotlib庫中的pie函數,首先我們來看看這個函數的參數說明。


pie函數參數解讀

plt.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False)
  • x:指定繪圖的數據;

  • explode:指定餅圖某些部分的突出顯示,即呈現爆炸式;

  • labels:為餅圖添加標簽說明,類似于圖例說明;

  • colors:指定餅圖的填充色;

  • autopct:自動添加百分比顯示,可以采用格式化的方法顯示;

  • pctdistance:設置百分比標簽與圓心的距離;

  • shadow:是否添加餅圖的陰影效果;

  • labeldistance:設置各扇形標簽(圖例)與圓心的距離;

  • startangle:設置餅圖的初始擺放角度;

  • radius:設置餅圖的半徑大小;

  • counterclock:是否讓餅圖按逆時針順序呈現;

  • wedgeprops:設置餅圖內外邊界的屬性,如邊界線的粗細、顏色等;

  • textprops:設置餅圖中文本的屬性,如字體大小、顏色等;

  • center:指定餅圖的中心點位置,默認為原點

  • frame:是否要顯示餅圖背后的圖框,如果設置為True的話,需要同時控制圖框x軸、y軸的范圍和餅圖的中心位置;

    ?


餅圖的繪制

案例:芝麻信用失信用戶分析

關于pie函數的參數我們講了這么多,光講不練假把式,我們接下來通過案例,來繪制一個個性化的餅圖。關于繪圖數據,我們借用芝麻信用近300萬失信人群的樣本統計數據,該數據顯示,從受教育水平上來看,中專占比25.15%,大專占比37.24%,本科占比33.36%,碩士占比3.68%,剩余的其他學歷占比0.57%。對于這樣一組數據,我們該如何使用餅圖來呈現呢?

# 導入第三方模塊 import matplotlib.pyplot as plt# 設置繪圖的主題風格(不妨使用R中的ggplot分隔) plt.style.use('ggplot')# 構造數據 edu = [0.2515,0.3724,0.3336,0.0368,0.0057] labels = ['中專','大專','本科','碩士','其他']explode = [0,0.1,0,0,0] ?# 用于突出顯示大專學歷人群 colors=['#9999ff','#ff9999','#7777aa','#2442aa','#dd5555'] # 自定義顏色# 中文亂碼和坐標軸負號的處理 plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] plt.rcParams['axes.unicode_minus'] = False# 將橫、縱坐標軸標準化處理,保證餅圖是一個正圓,否則為橢圓 plt.axes(aspect='equal')# 控制x軸和y軸的范圍 plt.xlim(0,4) plt.ylim(0,4)# 繪制餅圖 plt.pie(x = edu, # 繪圖數據explode=explode, # 突出顯示大專人群labels=labels, # 添加教育水平標簽colors=colors, # 設置餅圖的自定義填充色autopct='%.1f%%', # 設置百分比的格式,這里保留一位小數pctdistance=0.8, ?# 設置百分比標簽與圓心的距離labeldistance = 1.15, # 設置教育水平標簽與圓心的距離startangle = 180, # 設置餅圖的初始角度radius = 1.5, # 設置餅圖的半徑counterclock = False, # 是否逆時針,這里設置為順時針方向wedgeprops = {'linewidth': 1.5, 'edgecolor':'green'},# 設置餅圖內外邊界的屬性值textprops = {'fontsize':12, 'color':'k'}, # 設置文本標簽的屬性值center = (1.8,1.8), # 設置餅圖的原點frame = 1 )# 是否顯示餅圖的圖框,這里設置顯示# 刪除x軸和y軸的刻度 plt.xticks(()) plt.yticks(()) # 添加圖標題 plt.title('芝麻信用失信用戶教育水平分布')# 顯示圖形 plt.show()

?

matplotlib(箱線圖)

針對離散變量我們可以使用常見的條形圖和餅圖完成數據的可視化工作,那么,針對數值型變量,我們也有很多可視化的方法,例如箱線圖、直方圖、折線圖、面積圖、散點圖等等。這一期,我們就先來介紹一下數值型變量的箱線圖繪制。箱線圖一般用來展現數據的分布(如上下四分位值、中位數等),同時,也可以用箱線圖來反映數據的異常情況。

boxplot函數的參數解讀

繪圖之前,我們先來講解一下matplotlib包中boxplot函數的參數含義及使用方法:

plt.boxplot(x, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, patch_artist=None, meanline=None, showmeans=None, showcaps=None, showbox=None, showfliers=None, boxprops=None, labels=None, flierprops=None, medianprops=None, meanprops=None, capprops=None, whiskerprops=None)
  • x:指定要繪制箱線圖的數據;

  • notch:是否是凹口的形式展現箱線圖,默認非凹口;

  • sym:指定異常點的形狀,默認為+號顯示;

  • vert:是否需要將箱線圖垂直擺放,默認垂直擺放;

  • whis:指定上下須與上下四分位的距離,默認為1.5倍的四分位差;

  • positions:指定箱線圖的位置,默認為[0,1,2…];

  • widths:指定箱線圖的寬度,默認為0.5;

  • patch_artist:是否填充箱體的顏色;

  • meanline:是否用線的形式表示均值,默認用點來表示;

  • showmeans:是否顯示均值,默認不顯示;

  • showcaps:是否顯示箱線圖頂端和末端的兩條線,默認顯示;

  • showbox:是否顯示箱線圖的箱體,默認顯示;

  • showfliers:是否顯示異常值,默認顯示;

  • boxprops:設置箱體的屬性,如邊框色,填充色等;

  • labels:為箱線圖添加標簽,類似于圖例的作用;

  • filerprops:設置異常值的屬性,如異常點的形狀、大小、填充色等;

  • medianprops:設置中位數的屬性,如線的類型、粗細等;

  • meanprops:設置均值的屬性,如點的大小、顏色等;

  • capprops:設置箱線圖頂端和末端線條的屬性,如顏色、粗細等;

  • whiskerprops:設置須的屬性,如顏色、粗細、線的類型等;

餅圖的繪制

案例:titanic:不同等級倉位的年齡箱線圖

?

  • 整體乘客的年齡箱線圖

# 導入第三方模塊 import pandas as pd import matplotlib.pyplot as plt# 讀取Titanic數據集 titanic = pd.read_csv('titanic_train.csv') # 檢查年齡是否有缺失 any(titanic.Age.isnull()) # 不妨刪除含有缺失年齡的觀察 titanic.dropna(subset=['Age'], inplace=True)# 設置圖形的顯示風格 plt.style.use('ggplot')# 設置中文和負號正常顯示 plt.rcParams['font.sans-serif'] = 'Microsoft YaHei' plt.rcParams['axes.unicode_minus'] = False# 繪圖:整體乘客的年齡箱線圖 plt.boxplot(x = titanic.Age, # 指定繪圖數據patch_artist=True, # 要求用自定義顏色填充盒形圖,默認白色填充showmeans=True, # 以點的形式顯示均值boxprops = {'color':'black','facecolor':'#9999ff'}, # 設置箱體屬性,填充色和邊框色flierprops = {'marker':'o','markerfacecolor':'red','color':'black'}, # 設置異常值屬性,點的形狀、填充色和邊框色meanprops = {'marker':'D','markerfacecolor':'indianred'}, # 設置均值點的屬性,點的形狀、填充色medianprops = {'linestyle':'--','color':'orange'}) # 設置中位數線的屬性,線的類型和顏色 # 設置y軸的范圍 plt.ylim(0,85)# 去除箱線圖的上邊框與右邊框的刻度標簽 plt.tick_params(top='off', right='off') # 顯示圖形 plt.show()

對于所有乘客而言,從圖中容易發現,乘客的平均年齡在30歲,有四分之一的人低于20歲,另有四分之一的人超過38歲,換句話說,有一半的人,年齡落在20~38歲之間;從均值(紅色的菱形)略高于中位數(黃色虛線)來看,說明年齡是有偏的,并且是右偏;同時,我們也會發現一些紅色的異常值,這些異常值的年齡均在64歲以上

  • 不同等級倉的年齡箱線圖

# 按艙級排序,為了后面正常顯示分組盒形圖的順序 titanic.sort_values(by = 'Pclass', inplace=True)# 通過for循環將不同倉位的年齡人群分別存儲到列表Age變量中 Age = [] Levels = titanic.Pclass.unique() for Pclass in Levels:Age.append(titanic.loc[titanic.Pclass==Pclass,'Age'])# 繪圖 plt.boxplot(x = Age, patch_artist=True,labels = ['一等艙','二等艙','三等艙'], # 添加具體的標簽名稱showmeans=True, boxprops = {'color':'black','facecolor':'#9999ff'}, flierprops = {'marker':'o','markerfacecolor':'red','color':'black'},meanprops = {'marker':'D','markerfacecolor':'indianred'},medianprops = {'linestyle':'--','color':'orange'})# 顯示圖形 plt.show()

如果對人群的年齡按不同的艙位來看,我們會發現一個明顯的趨勢,就是艙位等級越高的乘客,他們的年齡越高,三種艙位的平均年齡為38、30和25,說明年齡越是偏大一點,他們的經濟能力會越強一些,所買的艙位等級可能就會越高一些。同時,在二等艙和三等艙內,乘客的年齡上存在一些異常用戶。

matplotlib(直方圖)

我們仔細的講解了如何繪制數值型變量的箱線圖,展現數據的分布,我們還可以使用直方圖來說明,同過圖形的長相,就可以快速的判斷數據是否近似服從正態分布。之所以我們很關心數據的分布,是因為在統計學中,很多假設條件都會包括正態分布,故使用直方圖來定性的判定數據的分布情況,尤其顯得重要。這期我們就來介紹Python中如何繪制一個直方圖。

hist函數的參數解讀


????????繪圖之前,我們先來講解一下matplotlib包中hist函數的參數含義及使用方法:

plt.hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False)
  • x:指定要繪制直方圖的數據;

  • bins:指定直方圖條形的個數;

  • range:指定直方圖數據的上下界,默認包含繪圖數據的最大值和最小值;

  • normed:是否將直方圖的頻數轉換成頻率;

  • weights:該參數可為每一個數據點設置權重;

  • cumulative:是否需要計算累計頻數或頻率;

  • bottom:可以為直方圖的每個條形添加基準線,默認為0;

  • histtype:指定直方圖的類型,默認為bar,除此還有’barstacked’, ‘step’, ?‘stepfilled’;

  • align:設置條形邊界值的對其方式,默認為mid,除此還有’left’和’right’;

  • orientation:設置直方圖的擺放方向,默認為垂直方向;

  • rwidth:設置直方圖條形寬度的百分比;

  • log:是否需要對繪圖數據進行log變換;

  • color:設置直方圖的填充色;

  • label:設置直方圖的標簽,可通過legend展示其圖例;

  • stacked:當有多個數據時,是否需要將直方圖呈堆疊擺放,默認水平擺放;

一元直方圖的繪制


案例:titanic數據集

  • 整體乘客的年齡直方圖

# 導入第三方包 import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.mlab as mlab# 中文和負號的正常顯示 plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] plt.rcParams['axes.unicode_minus'] = False# 讀取Titanic數據集 titanic = pd.read_csv('titanic_train.csv') # 檢查年齡是否有缺失any(titanic.Age.isnull()) # 不妨刪除含有缺失年齡的觀察 titanic.dropna(subset=['Age'], inplace=True)# 設置圖形的顯示風格 plt.style.use('ggplot') # 繪圖:乘客年齡的頻數直方圖 plt.hist(titanic.Age, # 繪圖數據bins = 20, # 指定直方圖的條形數為20個color = 'steelblue', # 指定填充色edgecolor = 'k', # 指定直方圖的邊界色label = '直方圖' )# 為直方圖呈現標簽# 去除圖形頂部邊界和右邊界的刻度 plt.tick_params(top='off', right='off') # 顯示圖例 plt.legend() # 顯示圖形 plt.show()

上圖繪制的是年齡的頻數直方圖,從整體的分布來看,有點像正態分布,兩邊低中間高的倒鐘形狀。除此,我們還可以繪制累計頻率直方圖,并且設置5歲為組距,如下代碼可以表示成:

# 繪圖:乘客年齡的累計頻率直方圖 plt.hist(titanic.Age, # 繪圖數據bins = np.arange(titanic.Age.min(),titanic.Age.max(),5), # 指定直方圖的組距normed = True, # 設置為頻率直方圖cumulative = True, # 積累直方圖color = 'steelblue', # 指定填充色edgecolor = 'k', # 指定直方圖的邊界色label = '直方圖' )# 為直方圖呈現標簽# 設置坐標軸標簽和標題 plt.title('乘客年齡的頻率累計直方圖') plt.xlabel('年齡') plt.ylabel('累計頻率')# 去除圖形頂部邊界和右邊界的刻度 plt.tick_params(top='off', right='off')# 顯示圖例 plt.legend(loc = 'best') # 顯示圖形 plt.show()

通過累計頻率直方圖就可以快速的發現什么年齡段的人數占了多少比重,例如35歲以下的乘客占了7成,這種圖的解讀有點像帕累托圖。為了測試數據集是否近似服從正態分布,需要在直方圖的基礎上再繪制兩條線,一條表示理論的正態分布曲線,另一條為核密度曲線,目的就是比較兩條曲線的吻合度,越吻合就說明數據越近似于正態分布。接下來我們就在直方圖的基礎上再添加兩條曲線:

# 正太分布圖 plt.hist(titanic.Age, # 繪圖數據bins = np.arange(titanic.Age.min(),titanic.Age.max(),5), # 指定直方圖的組距normed = True, # 設置為頻率直方圖color = 'steelblue', # 指定填充色edgecolor = 'k') # 指定直方圖的邊界色# 設置坐標軸標簽和標題 plt.title('乘客年齡直方圖') plt.xlabel('年齡') plt.ylabel('頻率')# 生成正態曲線的數據 x1 = np.linspace(titanic.Age.min(), titanic.Age.max(), 1000) normal = mlab.normpdf(x1, titanic.Age.mean(), titanic.Age.std()) # 繪制正態分布曲線 line1, = plt.plot(x1,normal,'r-', linewidth = 2) # 生成核密度曲線的數據 kde = mlab.GaussianKDE(titanic.Age) x2 = np.linspace(titanic.Age.min(), titanic.Age.max(), 1000) # 繪制 line2, = plt.plot(x2,kde(x2),'g-', linewidth = 2)# 去除圖形頂部邊界和右邊界的刻度 plt.tick_params(top='off', right='off')# 顯示圖例 plt.legend([line1, line2],['正態分布曲線','核密度曲線'],loc='best') # 顯示圖形 plt.show()

從直方圖的展現來看,乘客的年齡分布與理論正態分布曲線存在一些差異,說明不服從正態分布,而且從圖中也能看見,年齡呈現右偏的特征

二元直方圖的繪制

???????上面繪制的直方圖都是基于所有乘客的年齡,如果想對比男女乘客的年齡直方圖的話,我們可以通過兩個hist將不同性別的直方圖繪制到一張圖內,具體代碼如下:

# 提取不同性別的年齡數據 age_female = titanic.Age[titanic.Sex == 'female'] age_male = titanic.Age[titanic.Sex == 'male']# 設置直方圖的組距 bins = np.arange(titanic.Age.min(), titanic.Age.max(), 2) # 男性乘客年齡直方圖 plt.hist(age_male, bins = bins, label = '男性', color = 'steelblue', alpha = 0.7) # 女性乘客年齡直方圖plt.hist(age_female, bins = bins, label = '女性', alpha = 0.6)# 設置坐標軸標簽和標題 plt.title('乘客年齡直方圖') plt.xlabel('年齡') plt.ylabel('人數')# 去除圖形頂部邊界和右邊界的刻度 plt.tick_params(top='off', right='off')# 顯示圖例 plt.legend() # 顯示圖形 plt.show()

圖中結果反映了,不同年齡組內幾乎都是男性乘客比女性乘客要多;同時,也說明男女性別的年齡組分布幾乎一致

?

?

matplotlib(折線圖)

講解一下關于折線圖的繪制,折線圖一般是用來表示某個數值變量隨著時間的推移而形成的趨勢,這種圖還是比較常見的,如經濟走勢圖、銷售波動圖、PV監控圖等。在Python的matplotlib模塊中,我們可以調用plot函數就能實現折線圖的繪制了,先來看看這個函數的一些參數含義。

plot函數的參數解讀


???????matplotlib模塊中plot函數語法及參數含義:

plt.hist(x,y,linestyle,linewidth,color,marker,markersize,markeredgecolor,markerfactcolor,label,alpha)
  • x:指定折線圖的x軸數據;

  • y:指定折線圖的y軸數據;

  • linestyle:指定折線的類型,可以是實線、虛線、點虛線、點點線等,默認文實線;

  • linewidth:指定折線的寬度

  • marker:可以為折線圖添加點,該參數是設置點的形狀;

  • markersize:設置點的大小;

  • markeredgecolor:設置點的邊框色;

  • markerfactcolor:設置點的填充色;

  • label:為折線圖添加標簽,類似于圖例的作用;

?

一元折線圖的繪制


案例:每天進步一點點2015公眾號文章閱讀人數

# 導入模塊 import pandas as pd import matplotlib.pyplot as plt# 設置繪圖風格 plt.style.use('ggplot') # 設置中文編碼和負號的正常顯示 plt.rcParams['font.sans-serif'] = 'Microsoft YaHei' plt.rcParams['axes.unicode_minus'] = False# 讀取需要繪圖的數據 article_reading = pd.read_excel('wechart.xlsx') # 取出8月份至9月28日的數據 sub_data = article_reading.loc[article_reading.date >= '2017-08-01' ,:]# 設置圖框的大小 fig = plt.figure(figsize=(10,6)) # 繪圖 plt.plot(sub_data.date, # x軸數據sub_data.article_reading_cnts, # y軸數據linestyle = '-', # 折線類型linewidth = 2, # 折線寬度color = 'steelblue', # 折線顏色marker = 'o', # 點的形狀markersize = 6, # 點的大小markeredgecolor='black', # 點的邊框色markerfacecolor='brown') # 點的填充色# 添加標題和坐標軸標簽 plt.title('公眾號每天閱讀人數趨勢圖') plt.xlabel('日期') plt.ylabel('人數')# 剔除圖框上邊界和右邊界的刻度 plt.tick_params(top = 'off', right = 'off')# 為了避免x軸日期刻度標簽的重疊,設置x軸刻度自動展現,并且45度傾斜 fig.autofmt_xdate(rotation = 45)# 顯示圖形 plt.show()

???????由于x軸是日期型數據,當數據量一多的時候,就會導致刻度標簽的重疊或擁擠,為了防止重疊的產生,我們需要讓日期型的x軸刻度標簽自動展現,從而避免重疊的現象。下面兩幅圖是對比自動刻度標簽的前后變化:

?

?

???????可能你并不滿足這樣的刻度標簽展現形式,你想以個性化的展現方式,如“YYYY-MM-DD”的顯示方式,同時又想以固定的幾天作為間隔,這樣的設置又該如何實現?其實非常的簡單,只需要在上面代碼的基礎上添加幾行代碼就可以輕松搞定。

一元折線圖的繪制—圖形優化


# 導入模塊 import matplotlib as mpl# 設置圖框的大小 fig = plt.figure(figsize=(10,6)) # 繪圖 plt.plot(sub_data.date, # x軸數據sub_data.article_reading_cnts, # y軸數據linestyle = '-', # 折線類型linewidth = 2, # 折線寬度color = 'steelblue', # 折線顏色marker = 'o', # 點的形狀markersize = 6, # 點的大小markeredgecolor='black', # 點的邊框色markerfacecolor='steelblue') # 點的填充色# 添加標題和坐標軸標簽 plt.title('公眾號每天閱讀人數趨勢圖') plt.xlabel('日期') plt.ylabel('人數')# 剔除圖框上邊界和右邊界的刻度 plt.tick_params(top = 'off', right = 'off')# 獲取圖的坐標信息 ax = plt.gca() # 設置日期的顯示格式 ? date_format = mpl.dates.DateFormatter("%Y-%m-%d") ? ax.xaxis.set_major_formatter(date_format) # 設置x軸顯示多少個日期刻度 #xlocator = mpl.ticker.LinearLocator(10) # 設置x軸每個刻度的間隔天數 xlocator = mpl.ticker.MultipleLocator(5) ax.xaxis.set_major_locator(xlocator)# 為了避免x軸日期刻度標簽的重疊,設置x軸刻度自動展現,并且45度傾斜 fig.autofmt_xdate(rotation = 45)# 顯示圖形 plt.show()

多元折線圖的繪制


???????如果你需要在一張圖形中畫上兩條折線圖,也很簡單,只需要在代碼中寫入兩次plot函數即可,其他都不需要改動了。具體可以參考下面的代碼邏輯:

# 設置圖框的大小 fig = plt.figure(figsize=(10,6))# 繪圖--閱讀人數趨勢 plt.plot(sub_data.date, # x軸數據sub_data.article_reading_cnts, # y軸數據linestyle = '-', # 折線類型linewidth = 2, # 折線寬度color = 'steelblue', # 折線顏色marker = 'o', # 點的形狀markersize = 6, # 點的大小markeredgecolor='black', # 點的邊框色markerfacecolor='steelblue', # 點的填充色label = '閱讀人數') # 添加標簽# 繪圖--閱讀人次趨勢 plt.plot(sub_data.date, # x軸數據sub_data.article_reading_times, # y軸數據linestyle = '-', # 折線類型linewidth = 2, # 折線寬度color = '#ff9999', # 折線顏色marker = 'o', # 點的形狀markersize = 6, # 點的大小markeredgecolor='black', # 點的邊框色markerfacecolor='#ff9999', # 點的填充色label = '閱讀人次') # 添加標簽# 添加標題和坐標軸標簽 plt.title('公眾號每天閱讀人數和人次趨勢圖') plt.xlabel('日期') plt.ylabel('人數')# 剔除圖框上邊界和右邊界的刻度 plt.tick_params(top = 'off', right = 'off')# 獲取圖的坐標信息 ax = plt.gca() # 設置日期的顯示格式 ? date_format = mpl.dates.DateFormatter('%m-%d') ? ax.xaxis.set_major_formatter(date_format) # 設置x軸顯示多少個日期刻度 #xlocator = mpl.ticker.LinearLocator(10) # 設置x軸每個刻度的間隔天數 xlocator = mpl.ticker.MultipleLocator(3) ax.xaxis.set_major_locator(xlocator)# 為了避免x軸日期刻度標簽的重疊,設置x軸刻度自動展現,并且45度傾斜 fig.autofmt_xdate(rotation = 45)# 顯示圖例 plt.legend() # 顯示圖形 plt.show()

兩條折線圖很完美的展現在一張圖中,公眾號的閱讀人數與人次趨勢完全一致,而且具有一定的周期性,即過幾天就會有一個大幅上升的波動,這個主要是由于雙休日的時候,時間比較空閑,就可以更新并推送文章了。

matplotlib(散點圖)

我們通過折線圖可以快速的發現時間序列的趨勢圖,當然他不僅僅只能用在時間序列中,也可以和其他圖形配合使用,正如本期要介紹的,可以將折線圖繪制到散點圖中。散點圖可以反映兩個變量間的相關關系,即如果存在相關關系的話,它們之間是正向的線性關系還是反向的線性關系?甚至于是非線性關系?在繪制散點圖之前,我們任然老規矩,先來介紹一下matplotlib包中的scatter函數用法及參數含義。

scatter函數的參數解讀


???????matplotlib模塊中scatter函數語法及參數含義:

plt.scatter(x, y, s=20, c=None, marker='o', cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, edgecolors=None)
  • x:指定散點圖的x軸數據;

  • y:指定散點圖的y軸數據;

  • s:指定散點圖點的大小,默認為20,通過傳入新的變量,實現氣泡圖的繪制;

  • c:指定散點圖點的顏色,默認為藍色;

  • marker:指定散點圖點的形狀,默認為圓形;

  • cmap:指定色圖,只有當c參數是一個浮點型的數組的時候才起作用;

  • norm:設置數據亮度,標準化到0~1之間,使用該參數仍需要c為浮點型的數組;

  • vmin、vmax:亮度設置,與norm類似,如果使用了norm則該參數無效;

  • alpha:設置散點的透明度;

  • linewidths:設置散點邊界線的寬度;

  • edgecolors:設置散點邊界線的顏色;

?

一般散點圖的繪制


案例:汽車速度與剎車距離的關系

# 導入模塊 import pandas as pd import matplotlib.pyplot as plt# 設置繪圖風格 plt.style.use('ggplot') # 設置中文編碼和負號的正常顯示 plt.rcParams['font.sans-serif'] = 'Microsoft YaHei' plt.rcParams['axes.unicode_minus'] = False# 讀入數據cars = pd.read_csv('cars.csv') # 繪圖 plt.scatter(cars.speed, # x軸數據為汽車速度cars.dist, # y軸數據為汽車的剎車距離s = 30, # 設置點的大小 c = 'steelblue', # 設置點的顏色marker = 's', # 設置點的形狀alpha = 0.9, # 設置點的透明度linewidths = 0.3, # 設置散點邊界的粗細edgecolors = 'red' # 設置散點邊界的顏色)# 添加軸標簽和標題plt.title('汽車速度與剎車距離的關系') plt.xlabel('汽車速度') plt.ylabel('剎車距離')# 去除圖邊框的頂部刻度和右邊刻度 plt.tick_params(top = 'off', right = 'off')# 顯示圖形plt.show()

這樣一張簡單的散點圖就呈現出來了,很明顯的發現,汽車的剎車速度與剎車距離存在正相關關系,即隨著速度的增加,剎車距離也在增加。其實這個常識不用繪圖都能夠發現,關鍵是通過這個簡單的案例,讓大家學會如何通過python繪制一個散點圖。如果你需要畫的散點圖,是根據不同的類別進行繪制,如按不同的性別,將散點圖區分開來等。這樣的散點圖該如何繪制呢?

分組散點圖的繪制


案例:iris數據集

# 讀取數據 iris = pd.read_csv('iris.csv')# 自定義顏色 colors = ['steelblue', '#9999ff', '#ff9999']# 三種不同的花品種S pecies = iris.Species.unique()# 通過循環的方式,完成分組散點圖的繪制 for i in range(len(Species)):plt.scatter(iris.loc[iris.Species == Species[i], 'Petal.Length'], iris.loc[iris.Species == Species[i], 'Petal.Width'], s = 35, c = colors[i], label = Species[i])# 添加軸標簽和標題 plt.title('花瓣長度與寬度的關系') plt.xlabel('花瓣長度') plt.ylabel('花瓣寬度')# 去除圖邊框的頂部刻度和右邊刻度 plt.tick_params(top = 'off', right = 'off') # 添加圖例 plt.legend(loc = 'upper left') # 顯示圖形 plt.show()

繪制這樣的分組散點圖是不是也非常的簡單呀,而且關于圖的屬性,可以想怎么設置就怎么設置。從圖中可以發現,三種花的花瓣長度與寬度之間都存在正向的關系,只不過品種setasa的體型比較小,數據點比較聚集。

氣泡圖的繪制


案例:大區銷售數據

# 導入第三方包 import numpy as np# 讀取數據 sales = pd.read_excel('sales.xlsx')# 繪制氣泡圖 plt.scatter(sales.finish_ratio, sales.profit_ratio, c = 'steelblue',s = sales.tot_target/30,edgecolor = 'black')# 改變軸刻度的顯示方式(百分比形式) plt.xticks(np.arange(0,1,0.1), [str(i*100)+'%' for i in np.arange(0,1,0.1)]) plt.yticks(np.arange(0,1,0.1), [str(i*100)+'%' for i in np.arange(0,1,0.1)])# 設置x軸和y軸的數值范圍 plt.xlim(0.2, 0.7) plt.ylim(0.25, 0.85)# 添加軸標簽和標題 plt.title('完成率與利潤率的關系') plt.xlabel('完成率') plt.ylabel('利潤率')# 去除圖邊框的頂部刻度和右邊刻度 plt.tick_params(top = 'off', right = 'off') # 顯示圖形 plt.show()

這樣一個氣泡圖,也非常容易的展現出來了,圖中的圓越大,代表總任務量就越大。一般來說氣泡圖可以展現3維或4維數據,利潤本圖就展現了3維數據,如果再加上顏色表示不同的大區,就可以反映4維數據。

???????在絕大多數情況下,我們會看見散點圖和線性回歸線繪制在一起,一方面可以反映變量間的相關關系,另一反面,也可以定量的找到一根直線來反映這個相關趨勢。接下來,我們就來實現一下散點圖+回歸線的繪制,這里回歸線的繪制數據需要加載sklearn這個機器學習的模塊,通過這個模塊來生成一個線性模型。關于sklearn模塊的知識分享,后期我也會以系列的形式呈現。

散點圖+線性回歸線


汽車速度與剎車距離的關系

???????從我們的第一案例就認識到了汽車的剎車速度與剎車距離之間存在正相關的關系,如果需要定量的模型來反映這個關系,就可以利用線性回歸模型來刻畫即可,接下來我們就來實現一下這個散點圖與回歸圖的結合:

# 導入第三方模塊 from sklearn.linear_model import LinearRegression# 散點圖 plt.scatter(cars.speed, # x軸數據為汽車速度cars.dist, # y軸數據為汽車的剎車距離s = 30, # 設置點的大小 c = 'black', # 設置點的顏色marker = 'o', # 設置點的形狀alpha = 0.9, # 設置點的透明度linewidths = 0.3, # 設置散點邊界的粗細label = '觀測點')# 建模 reg = LinearRegression().fit(cars.speed.reshape(-1,1), cars.dist) # 回歸預測值 pred = reg.predict(cars.speed.reshape(-1,1))# 繪制回歸線 plt.plot(cars.speed, pred, linewidth = 2, label = '回歸線')# 添加軸標簽和標題 plt.title('汽車速度與剎車距離的關系') plt.xlabel('汽車速度') plt.ylabel('剎車距離')# 去除圖邊框的頂部刻度和右邊刻度 plt.tick_params(top = 'off', right = 'off') # 顯示圖例 plt.legend(loc = 'upper left') # 顯示圖形 plt.show()

?

matplotlib(雷達圖)

如何借用Python繪制雷達圖(或蛛網圖),雷達圖可以很好刻畫出某些指標的橫向或縱向的對比關系,例如近三年營業額、客單價、新客招募等指標的同比情況對比,完全就可以通過雷達圖讓數據一目了然。很不幸的是,matplotlib模塊中并沒有特制雷達圖的封裝函數,我們只能換一只思路來實現了。

雷達圖的繪制


# 導入第三方模塊 import numpy as np import matplotlib.pyplot as plt# 中文和負號的正常顯示 plt.rcParams['font.sans-serif'] = 'Microsoft YaHei' plt.rcParams['axes.unicode_minus'] = False# 使用ggplot的繪圖風格 plt.style.use('ggplot')# 構造數據 values = [3.2,2.1,3.5,2.8,3] feature = ['個人能力','QC知識','解決問題能力','服務質量意識','團隊精神']N = len(values) # 設置雷達圖的角度,用于平分切開一個圓面 angles=np.linspace(0, 2*np.pi, N, endpoint=False)# 為了使雷達圖一圈封閉起來,需要下面的步驟 values=np.concatenate((values,[values[0]])) angles=np.concatenate((angles,[angles[0]]))# 繪圖 fig=plt.figure() # 這里一定要設置為極坐標格式 ax = fig.add_subplot(111, polar=True) # 繪制折線圖 ax.plot(angles, values, 'o-', linewidth=2) # 填充顏色 ax.fill(angles, values, alpha=0.25) # 添加每個特征的標簽 ax.set_thetagrids(angles * 180/np.pi, feature) # 設置雷達圖的范圍 ax.set_ylim(0,5) # 添加標題 plt.title('活動前后員工狀態表現') # 添加網格線 ax.grid(True) # 顯示圖形 plt.show()

?

非常簡單吧,一張雷達圖就這么造出來了。其思想也非常簡單,即先把常見的二維坐標變換成極坐標,然后在極坐標的基礎上繪制折線圖,如果需要填充顏色的話就是要fill方法。一般而言這樣的雷達圖沒有什么意義,因為我們用雷達圖通常是要實現多個對象的對比,所以,該如何繪制多條線的雷達圖呢?可以參考下面的代碼:

# 導入第三方模塊 import numpy as np import matplotlib.pyplot as plt# 中文和負號的正常顯示 plt.rcParams['font.sans-serif'] = 'Microsoft YaHei' plt.rcParams['axes.unicode_minus'] = False# 使用ggplot的繪圖風格 plt.style.use('ggplot')# 構造數據 values = [3.2,2.1,3.5,2.8,3] values2 = [4,4.1,4.5,4,4.1] feature = ['個人能力','QC知識','解決問題能力','服務質量意識','團隊精神']N = len(values) # 設置雷達圖的角度,用于平分切開一個圓面 angles=np.linspace(0, 2*np.pi, N, endpoint=False) # 為了使雷達圖一圈封閉起來,需要下面的步驟 values=np.concatenate((values,[values[0]])) values2=np.concatenate((values2,[values2[0]])) angles=np.concatenate((angles,[angles[0]]))# 繪圖 fig=plt.figure() ax = fig.add_subplot(111, polar=True) # 繪制折線圖 ax.plot(angles, values, 'o-', linewidth=2, label = '活動前') # 填充顏色 ax.fill(angles, values, alpha=0.25) # 繪制第二條折線圖 ax.plot(angles, values2, 'o-', linewidth=2, label = '活動后') ax.fill(angles, values2, alpha=0.25)# 添加每個特征的標簽 ax.set_thetagrids(angles * 180/np.pi, feature) # 設置雷達圖的范圍 ax.set_ylim(0,5) # 添加標題 plt.title('活動前后員工狀態表現')# 添加網格線 ax.grid(True) # 設置圖例 plt.legend(loc = 'best') # 顯示圖形 plt.show()

?

發現了吧,如果要繪制多個對象的雷達圖,只需多執行幾個繪制折線圖的語句即可。總體來說,這張圖繪制的還算可以,但總是覺得有點擁擠,不自在。其實在matplotlib官網中,也提供了繪制雷達圖的API,只不過代碼量非常大,感興趣的話,可以前去查看(http://matplotlib.org/gallery/api/radar_chart.html#sphx-glr-gallery-api-radar-chart-py)。

???????雖然matplotlib模塊沒有封裝好的雷達圖命令,但pygal模塊則提供了更加簡單的雷達圖函數,我們也嘗試著借助這個模塊實現雷達圖的繪制。

# 導入第三方模塊 import pygal# 調用Radar這個類,并設置雷達圖的填充,及數據范圍 radar_chart = pygal.Radar(fill = True, range=(0,5)) # 添加雷達圖的標題 radar_chart.title = '活動前后員工狀態表現' # 添加雷達圖各頂點的含義 radar_chart.x_labels = ['個人能力','QC知識','解決問題能力','服務質量意識','團隊精神']# 繪制兩條雷達圖區域 radar_chart.add('活動前', [3.2,2.1,3.5,2.8,3]) radar_chart.add('活動后', [4,4.1,4.5,4,4.1])# 保存圖像 radar_chart.render_to_file('radar_chart.svg')

matplotlib(面積圖)

一般來說,折線圖表達的思想是研究某個時間序列的趨勢。往往一條折線圖可以根據某個分組變量進行拆分,比如今年的銷售額可以拆分成各個事業線的貢獻;流量可以拆分為各個渠道;物流總量可以拆分為公路運輸、鐵路運輸、海運和空運。按照這個思路可以將一條折線圖拆分成多條折線圖,直觀的發現各個折線圖的趨勢,但遺憾的是不能得知總量的趨勢。為了解決這個問題,我們可以借助matplotlib中的stackplot函數繪制面積圖來直觀表達分組趨勢和總量趨勢。

stackplot函數語法及參數含義


stackplot(x,*args,**kargs)

  • x指定面積圖的x軸數據

  • *args為可變參數,可以接受任意多的y軸數據,即各個拆分的數據對象

  • **kargs為關鍵字參數,可以通過傳遞其他參數來修飾面積圖,如標簽、顏色

可用的關鍵字參數:

labels:以列表的形式傳遞每一塊面積圖包含的標簽,通過圖例展現

colors:設置不同的顏色填充面積圖

?

案例分享


???????以我國2017年的物流運輸量為例,來對比繪制折線圖和面積圖。這里將物流運輸量拆分成公路運輸、鐵路運輸和水路運輸,繪圖的對比代碼見下方所示:

# ========== Python3 + Jupyter ========== # # 導入第三方模塊 import pandas as pd import numpy as np import matplotlib.pyplot as plt# 設置圖形的顯示風格 plt.style.use('ggplot') # 設置中文和負號正常顯示 plt.rcParams['font.sans-serif'] = 'Microsoft YaHei' plt.rcParams['axes.unicode_minus'] = False# 讀取數據 transport = pd.read_excel('transport.xls') # 窺探數據框的前5行 transport.head()# 折線圖的x變量值,即Jan(一月份)到Aug(八月份)8個值 N = np.arange(transport.shape[1]-1)# 繪制拆分的折線圖 labels = transport.Index channel = transport.columns[1:]for i in range(transport.shape[0]):plt.plot(N, # x坐標transport.loc[i,'Jan':'Aug'], # y坐標label = labels[i], # 添加標簽marker = 'o', # 給折線圖添加圓形點linewidth = 2 # 設置線的寬度)# 添加標題和坐標軸標簽 plt.title('2017年各運輸渠道的運輸量') plt.ylabel('運輸量(萬噸)') # 修改x軸的刻度標簽 plt.xticks(N,channel)# 剔除圖框上邊界和右邊界的刻度 plt.tick_params(top = 'off', right = 'off')# 顯示圖例(即顯示label的效果) ? plt.legend(loc = 'best') ? # 顯示圖形 plt.show()

?

這就是繪制分組的折線圖思想,雖然折線圖能夠反映各個渠道的運輸量隨月份的波動趨勢,但無法觀察到1月份到8月份的各自總量。接下來我們看看面積圖的展現。

?

x = N # 將鐵路運輸、公路運輸和水路運輸各月的值提取出來,存儲到y1~y3 # 千萬千萬記得,提取出數據框的一列時,需要將序列的數據類型進行強制轉換,否則會報錯 y1 = transport.loc[0,'Jan':'Aug'].astype('int') y2 = transport.loc[1,'Jan':'Aug'].astype('int') y3 = transport.loc[2,'Jan':'Aug'].astype('int')# 定義各區塊面積的含義 colors = ['#ff9999','#9999ff','#cc1234']# 繪制面積圖 plt.stackplot(x, # x軸y1,y2,y3, # 可變參數,接受多個ylabels = labels, # 定義各區塊面積的含義colors = colors # 設置各區塊的填充色)# 添加標題和坐標軸標簽 plt.title('2017年各運輸渠道的運輸量') plt.ylabel('累積運輸量(萬噸)')# 修改x軸的刻度 plt.xticks(N,channel)# 剔除圖框上邊界和右邊界的刻度 plt.tick_params(top = 'off', right = 'off')# 顯示圖例(即顯示labels的效果) ? plt.legend(loc = 'upper left') # 顯示圖形 plt.show()

一個stackplot函數就能解決問題,而且具有很強的定制化。從上面的面積圖就可以清晰的發現兩個方面的信息,一個是各渠道運輸量的趨勢,另一個是則可以看見各月份的總量趨勢。所以,我們在可視化的過程中要盡可能的為閱讀者輸出簡單而信息量豐富的圖形

matplotlib(熱力圖)

如何繪制填充表格熱力圖的知識點,先給大家看一下效果圖。


???????從效果圖里我們可以發現,所謂的填充表格熱力圖就是將原本為數字表(數組)的單元格以顏色來填充,顏色的深淺表示數值的大小。我想,對于這樣的圖來說,總比直接看密密麻麻的數值表要輕松的多吧,畢竟顏色感官比數字感官要直接,要具有更強的沖擊。除了填充表格熱力圖,還有更為常見的地圖熱力圖等。那填充表格熱力圖是如何應用Python來實現的呢?就讓我們手把手的進行講解吧~

數據采集—氣溫數據


???????在繪圖之前,需要說明一下繪圖的數據源,案例中的數據是通過爬蟲獲取的,用的是上海9月份每天的最高氣溫,即生成兩列數據(日期和最高氣溫)。在有了原始數據的基礎上,還需要對數據進行清洗和整理,關于這部分是做任何數據分析或可視化都必經的坎。詳細可以通過下面的代碼來了解:

  • 步驟一:數據采集

# ========== Python3 + Jupyter ========== # # 導入所需的第三方包 import datetime import calendar import requests from bs4 import BeautifulSoup import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns# 采集數據 # 上海2017年9月份歷史氣溫數據 url = 'http://lishi.tianqi.com/shanghai/201709.html'# 發送爬蟲請求 response = requests.get(url).text # 解析源代碼 soup = BeautifulSoup(response, 'html.parser') # 根據HTML標記語言,查詢目標標記下的數據 datas = soup.findAll('div',{'class':'tqtongji2'})[0].findAll('ul')[1:]# 抓取日期數據 date = [i.findAll('li')[0].text for i in datas] # 抓取最高溫數據 high = [i.findAll('li')[1].text for i in datas]# 創建數據框 df = pd.DataFrame({'date':date, 'high':high}) # 變量類型 df.dtypes

?

  • 步驟二:數據整理

# 將date變量轉換為日期類型 df.date = pd.to_datetime(df.date) # 將high變量轉換成數值型 df.high = df.high.astype('int')# 數據處理 # 由日期型數據衍生出weekday df['weekday'] = df.date.apply(pd.datetime.weekday)# 由日期型數據計算week_of_month,即當前日期在本月中是第幾周 # 由于沒有現成的函數,這里自定義一個函數來計算week_of_month def week_of_month(tgtdate):# 由日期型參數tgtdate計算該月的天數days_this_month = calendar.mdays[tgtdate.month] ? ?# 通過循環當月的所有天數,找出第二周的第一個日期for i in range(1, days_this_month + 1):d = datetime.datetime(tgtdate.year, tgtdate.month, i) ? ? ? ?if d.day - d.weekday() > 0:startdate = d ? ? ? ? ? ?break# 返回日期所屬月份的第一周return (tgtdate - startdate).days //7 + 1df['week_of_month'] = df.date.apply(week_of_month) df.head()

到此為止,我們就完成了數據的采集和清洗過程,接下來我們就可以借助該數據完成填充熱力(日歷)圖的繪制。

填充熱力圖的繪制


基于matplotlib繪制熱力圖

???????其實,我需要繪制的是一個數據表,只不過把表中的每一個單元格用顏色填充起來。而表的結構是:列代表周一到周日,行代表9月份第一周到第五周。很顯然,我們剛剛完成的數據并不符合這樣的結構,故需要通過pandas模塊中的pivot_table函數制作一個透視表,然后才可以繪圖。關于熱力圖,我們可以使用matplotlib模塊中的pcolor函數,具體我們可以看下方的繪圖語句:

# ==================繪圖前的數據整理===================== # 構建數據表(日歷) target = pd.pivot_table(data = df.iloc[:,1:],values = 'high', index = 'week_of_month', columns = 'weekday') target# 缺失值填充(不填充的話pcolor函數無法繪制) target.fillna(0,inplace=True) # 刪除表格的索引名稱 target.index.name = None # 對索引排序(為了讓“第一周”到“第五周”的刻度從y軸的高到底顯示) target.sort_index(ascending=False, inplace=True)# ======================開始繪圖========================= # 設置中文和負號正常顯示 plt.rcParams['font.sans-serif'] = 'Microsoft YaHei' plt.rcParams['axes.unicode_minus'] = Falseplt.pcolor(target, # 指定繪圖數據cmap=plt.cm.Blues, # 指定填充色edgecolors = 'white' # 指點單元格之間的邊框色)# 添加x軸和y軸刻度標簽(加0.5是為了讓刻度標簽居中顯示) plt.xticks(np.arange(7)+0.5,['周一','周二','周三','周四','周五','周六','周日']) plt.yticks(np.arange(5)+0.5,['第五周','第四周','第三周','第二周','第一周'])# 消除圖框頂部和右部的刻度線 plt.tick_params(top='off', right = 'off') # 添加標題 plt.title('上海市2017年9月份每日最高氣溫分布圖') # 顯示圖形 plt.show()

繪圖數據的表結構

熱力圖展現

OK,一張填充表格熱力圖就奇跡般的顯示了,而且看上去還蠻舒服的。從圖框看,9月份的第一天是周五,之后的每一天都有對應的顏色顯示。但我在繪圖過程中發現幾個問題

1)繪圖用的數據,不能包含缺失值,否則填充圖是繪制不出來的,所有需要對缺失值做填充處理;

2)最終的圖例無法實現,即顏色的深淺,代表了具體的數值范圍是什么?

3)不方便將具體的溫度值顯示在每個單元格內;

???????為解決上面的三個問題,我們借助于seaborn模塊中的heatmap函數重新繪制一下熱力圖,而且這些問題在heatmap函數看來根本不算問題。

基于seaborn繪制熱力圖

# 通過透視圖函數形成繪圖數據 target = pd.pivot_table(data = df.iloc[:,1:],values = 'high', index = 'week_of_month', columns = 'weekday')# 繪圖 ax = sns.heatmap(target, # 指定繪圖數據cmap=plt.cm.Blues, # 指定填充色linewidths=.1, # 設置每個單元方塊的間隔annot=True # 顯示數值)# 添加x軸刻度標簽(加0.5是為了讓刻度標簽居中顯示) plt.xticks(np.arange(7)+0.5,['周一','周二','周三','周四','周五','周六','周日']) # 可以將刻度標簽置于頂部顯示 # ax.xaxis.tick_top()# 添加y軸刻度標簽 plt.yticks(np.arange(5)+0.5,['第一周','第二周','第三周','第四周','第五周']) # 旋轉y刻度0度,即水平顯示 plt.yticks(rotation = 0)# 設置標題和坐標軸標簽 ax.set_title('上海市2017年9月份每日最高氣溫分布圖') ax.set_xlabel('') ax.set_ylabel('')# 顯示圖形 plt.show()

完美熱力圖的繪制太簡單了!不需要做任何的特殊處理,只需要將繪圖數據扔給heatmap函數即可。想想是不是有點小激動啊~激動過后,還得跟著步驟操作一表哦~

matplotlib(樹地圖)

? 用可視化的方法來表達離散變量的數值情況,不僅僅可以使用條形圖、餅圖、熱力圖,我們還可以借助于樹地圖來完成。樹地圖的思想就是通過方塊的面積來表示,面積越大,其代表的值就越大,反之亦然。今天要跟大家分享的就是如何通過Ptyhon這個工具,完成樹地圖的繪制。

函數語法及參數


???????在Python中,可以借助于squarify包來繪制,即squarify.plot函數。首先,我們來看一下這個函數的語法及參數含義

squarify.plot(sizes, norm_x=100, norm_y=100, color=None, label=None, value=None, alpha,**kwargs)
  • sizes:指定離散變量各水平對應的數值,即反映樹地圖子塊的面積大小

  • norm_x:默認將x軸的范圍限定在0-100之內;

  • norm_y:默認將y軸的范圍限定在0-100之內;

  • color:自定義設置樹地圖子塊的填充色

  • label:為每個子塊指定標簽

  • value:為每個子塊添加數值大小的標簽

  • alpha:設置填充色的透明度

  • **kwargs:關鍵字參數,與條形圖的關鍵字參數類似,如設置邊框色、邊框粗細等;

    ?

???????介紹完了繪圖所需要的函數,先來拋一個樹地圖的效果圖,該圖反映的是2017年8月中央財政收入的主要來源情況:

樹地圖的繪制


???????圖中的數據來自《中華人民共和國財政部》官網,具體可以從2017年8月財政收支情況(http://gks.mof.gov.cn/zhengfuxinxi/tongjishuju/201709/t20170911_2695830.html)查看。

# 導入第三方包 import matplotlib.pyplot as plt import squarify#中文及負號處理辦法 plt.rcParams['font.sans-serif'] = 'Microsoft YaHei' plt.rcParams['axes.unicode_minus'] = False# 創建數據 name = ['國內增值稅','國內消費稅','企業所得稅','個人所得稅','進口增值稅、消費稅','出口退稅','城市維護建設稅','車輛購置稅','印花稅','資源稅','土地和房稅','車船稅煙葉稅等'] income = [3908,856,801,868,1361,1042,320,291,175,111,414,63]# 繪圖 colors = ['steelblue','#9999ff','red','indianred','green','yellow','orange']plot = squarify.plot(sizes = income, # 指定繪圖數據label = name, # 指定標簽color = colors, # 指定自定義顏色alpha = 0.6, # 指定透明度value = income, # 添加數值標簽edgecolor = 'white', # 設置邊界框為白色linewidth =3 # 設置邊框寬度為3)# 設置標簽大小 plt.rc('font', size=8) # 設置標題大小 plot.set_title('2017年8月中央財政收支情況',fontdict = {'fontsize':15})# 去除坐標軸 plt.axis('off') # 去除上邊框和右邊框刻度 plt.tick_params(top = 'off', right = 'off') # 顯示圖形 plt.show()

???????通過上面的這些繪圖語句和美化語句,就可以得到一個形象不錯的樹地圖了。是不是很簡單呢,如果你的工作中需要繪制離散變量的可視化,也可以考慮考慮這張圖呢~簡單明了形象佳!

?

?

總結

以上是生活随笔為你收集整理的Matplotlib画各种图的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。