你瞭解matplotlib嗎?對稱條形圖和發散型條形圖篇

前兩篇文章介紹了幾種常見的條形圖,實際上看起來簡單的條形圖可探索的設置還有很多!在體育賽事中,經常出現一種對稱條形圖,比如對比兩個熱門選手或者隊伍在各方面的打分情況等,這也是在普通橫向條形圖的基礎上繪製出來的,作爲無所不能的python,當然也是可以繪製這種圖形的!

閒話少敘,直接上代碼吧!

df = pd.read_excel(r"D:\data\football\曼城vs利物浦.xlsx")
df

這是從英超歷年球隊積分的數據中截取出來的曼城和利物浦兩支球隊的數據,製作一個對稱條形圖,查看這兩隻球隊在2010–2019年的積分表現。

vs

這是原數據,單看錶格對比不是很明顯,來畫一個對稱條形圖試試看:

plt.figure(figsize=(10,6))

ax = plt.gca()  #獲取座標軸對象
ax.spines['right'].set_color('none') #把右邊的邊框顏色設置爲無色,隱藏右邊框
ax.spines['top'].set_color('none')  #把上邊的邊框顏色設置爲無色,隱藏上邊框
ax.spines['bottom'].set_color('none')  #把上邊的邊框顏色設置爲無色,隱藏上邊框

ax.yaxis.set_ticks_position('left')  #指定左邊的邊爲 y 軸
ax.spines['left'].set_position(('data', 0))  #指定 data  設置的left(也就是指定的y軸)綁定到x軸的0這個點上 

plt.xticks([])  #去掉x軸刻度
plt.yticks(df.iloc[:,0].tolist()) #設置y軸刻度爲年份

 #繪製利物浦隊的條形圖,顏色用默認的藍色            
plt.barh(df.iloc[:,0],df.iloc[:,1], height=0.5,label = "利物浦") 

 #繪製曼城隊的條形圖,需要在y軸的兩側顯示條形,所以曼城隊的數據取負數,設置顏色爲粉色
plt.barh(df.iloc[:,0],-df.iloc[:,2],height=0.5,label = "曼城",color = "pink") 

 #通過循環爲曼城隊的每個橫向條形加標籤,標籤位置在對應條形的頂端,內容爲球隊當年的積分
for i,j in zip(range(len(df)),[2010,2011,2012,2013,2014,2015,2016,2017,2018,2019]):
    plt.text(-df.iloc[:,2][i]-5,j,df.iloc[:,2][i])

 #通過循環爲利物浦隊的每個橫向條形加標籤,標籤位置在對應條形的頂端,內容爲球隊當年的積分    
for i,j in zip(range(len(df)),[2010,2011,2012,2013,2014,2015,2016,2017,2018,2019]):
    plt.text(df.iloc[:,1][i]+1,j,df.iloc[:,1][i])
             
plt.legend(loc = 4);  #顯示圖例,loc參數指定圖例位置在右下角

請看效果圖:

barh

​ 是不是比看上邊的表格要清晰和容易多了,一眼就能看出每一年兩個球隊的積分對比情況,整體看來曼城隊是強於利物浦隊的,至於那個異常的2019年數據,不是全年的數據,所以和其他年份數據差異很大。

發散型條形圖

​ 對稱條形圖一般只能對比兩個個體之間的各項指標數據,如果涉及多個個體,對稱條形圖就不怎麼好用了。有另一種圖可以同時展示多個個體的情況,就是發散型條形圖!但是它本身也是有限制的,發散型條形圖只能展示在某一個指標上多個個體的不同,而對稱條形圖是展示兩個個體在多個指標上的對比,所以在實際應用中需要區分好需要實現的是什麼。

到底是什麼樣的情況,我們還是直接上代碼看圖片吧:

df_yc = pd.read_excel(r"D:\data\football\球隊排名比分2019.xlsx")
df_yc.head(10) #查看前十條數據

這是英超2019年個球隊的積分數據:

yc_data2019

​ 這是所有球隊中在2019年積分排名前十的球隊信息,繪圖的時候所有球隊的數據都會包含。

​ 雖然發散型條形圖形式和對稱條形圖類似,條形都是像兩個互爲相反的方向延申,然而兩者還是有一些不同,對稱條形圖直接在其中一類數據直接取負數,而發散型條形圖是在所有數據上都減掉了整體數據的均值,這樣大於均值的數據依然爲正,而低於均值的數據就會變成負數:

df_yc.積分.mean() #求所有球隊的平均積分
df_yc.積分 = df_yc.積分 - df_yc.積分.mean() #所有球隊的積分減掉均值
df_yc.sort_values("積分", inplace=True) #依據減掉均值後的積分進行升序排序
df_yc.head(10) #查看最新的前十條數據

data_new

​ 由於條形圖在繪製過程中是先從最下邊開始畫,我們希望最小的數值被畫在最下邊,由下到上升序排序,所以原數據要進行升序排序。

​ 到這裏其實什麼都不用設置就可以直接出圖了(做個心理建設,直接出的圖有點醜):

plt.barh(y =df_yc.iloc[:,0],width=df_yc.iloc[:,1],height=0.3 ,color = colors,alpha=0.5);

choutu

​ 是不是和曾經見過的發散型條形圖長的差不多,除了醜一點。下邊來進行一些完善,美化圖形。

​ 完善後的代碼可就多了很多呢,具體如下:

plt.figure(figsize=(12,8)) #新建畫布,尺寸爲12*8

colors = [] #指定條形顏色
for i in df_yc.iloc[:,1]:
    if i > 0:
        colors.append("g") #超過均值的數值爲綠色
    else:
        colors.append("r") #低於均值的數值爲紅色

 #繪製橫向條形圖,設置條形透明度爲0.5,降低色彩飽和度,看起來更舒服一些       
plt.barh(y =df_yc.iloc[:,0],width=df_yc.iloc[:,1],height=0.3 ,color = colors,alpha=0.5)

pos = [] #指定要添加文本的x軸位置
for i in df_yc.iloc[:,1]:
    if i > 0:
        pos.append(i+0.5) #如果數值高於均值,文本在x軸的位置超過條形頂端0.5的距離
    else:
        pos.append(i- 0.5)#如果數值低於均值,文本在x軸的位置小於條形頂端0.5的距離

for i in range(len(df_yc)): #通過循環爲每個條形添加標籤值
    if pos[i] > 0:   #plt.text(x軸方向位置,y軸方向位置,添加的文本信息)
        plt.text(x = pos[i]+0.5,y = i,s = round(df_yc.iloc[:,1].iloc[i],2))
    else:
        plt.text(x = pos[i]-2,y = i,s =  round(df_yc.iloc[:,1].iloc[i],2))

plt.title("2019英超各球隊積分排名圖(積分均值爲30.25)")
plt.grid(linestyle='--', alpha=0.5); #配置網格線

效果圖:

發散條形圖

​ 是不是好看了很多,其實就是設置了畫布大小,讓整個圖看起來不那麼侷促;然後控制條形的上下寬度,再加上標籤方便查看每個條形的數據以及加了網格線,看起來就高大上了許多。

​ 這個圖很明顯能看出英超球隊積分參差不齊,沒過均線的球隊數量幾乎是均線上球隊數量的兩倍,這也說明了好的球隊特別好,把均線拉高了,差的球隊數量很多,但是水平倒沒有差的太離譜;整體來說還是好的球隊更厲害,最好的超均線30分,最差的球隊也只低於均線16分。

(本人一點都不懂足球,僅僅從2019年的數據中得到的一點點分析結果,之所以選擇英超數據單純的因爲體育數據更容易得到一點而已,所以如果分析的不好,還請輕拍。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章