手把手帶你可視化分析 NBA 季後賽

2021-02-20 高級農民工

作者 | 石曉文

來源 | 小小挖掘機

NBA激戰正酣,首輪除掘金和馬刺的較量還沒有結束外,其餘對決都已經結束,本文將手把手帶你可視化分析下各球隊的首輪表現,同時將對次輪最受矚目的火勇大戰進行一個簡單的前瞻分析!

通過本文,你將學會python中使用matplotlib庫繪製柱狀圖、散點圖、雷達圖的相關知識!咱們開始吧!

01 數據獲取及準備

我們首先獲取各球隊季後賽首輪的數據,網址是:https://www.basketball-reference.com/playoffs/NBA_2019.html。首先選擇Playoffs:

img

然後,下拉到球隊技術統計這裡,導出csv,如果無法直接倒出,可以複製到txt文件裡面(我就是這麼幹的):

img

然後,我們再把對手表現的數據導出,這樣基礎數據就準備好了:

img

好了,我們使用代碼將數據進行讀取,首先導入所需要的庫:

1import pandas as pd
2import matplotlib.pyplot as plt
3import numpy as np

將數據使用pandas進行讀取,看看數據如何:

1team_stats_df = pd.read_csv('data/nba1.txt',sep=',')
2team_stats_df

img

同樣,將對手表現的數據讀入,但是這裡列名需要修改一下:

1team_opp_stats_df = pd.read_csv('data/nba2.txt',sep=',')
2team_opp_stats_df.columns = ['Rk','Team','G'] + ['opp' + x for x in team_opp_stats_df.columns[3:]]

將兩個表按照隊名進行merge,這樣oppPTS列,可以表示場均失分,這也是我們在對手表現數據裡面主要關注的列:

1mergedf = pd.merge(team_stats_df,team_opp_stats_df,on=['Team'])

02 柱狀圖分析球隊場均得失分

繪製柱狀圖,需要使用的是plt.bar方法,其主要輸入的有兩個參數,一個是x軸的值,一個是高度,比如,我們繪製一下各球隊首輪平均得分的柱狀圖:

1pts = np.array(mergedf[['PTS','oppPTS']].values.tolist())
2index = np.arange(pts.shape[0])
3plt.bar(index,pts[:,1])
4plt.show()

結果如下:

img

上面的圖還是有幾個問題的,首先,我們不希望X顯示的是數值,我們希望展示各個球隊名稱的縮寫,同時刻度可以不從0開始,這樣看上去區分度不是十分的明顯。

針對第一個問題,我們需要首先按順序得到各個球隊名稱的縮寫:

1team_name = ['DEN','SA','GSW','PHI','LAC','BKN','POR','HOU','TOR','OKC','UTA','MIL','ORL','BOS','DET','IND']

隨後,將x軸的刻度設置為相應的隊名:

1plt.xticks(index,team_name) 

針對第二個問題,我們需要限定y軸的範圍,使用ylim方法:

1plt.ylim(80,140) 

這樣,我們得到了下面的圖片:

img

上面這部分的完整代碼如下:

1team_name = ['DEN','SA','GSW','PHI','LAC','BKN','POR','HOU','TOR','OKC','UTA','MIL','ORL','BOS','DET','IND']
2plt.ylabel('Score') 
3plt.xlabel('Team') 
4plt.xticks(index,team_name) 
5plt.yticks(np.arange(80,141,10)) 
6plt.ylim(80,140) 
7plt.bar(index,pts[:,0]) 
8plt.rcParams['figure.figsize'] = (12.0, 6.0) 
9plt.show()

此時,我們可能想要將球隊的得失分表示出來,代碼如下:

1fig, ax = plt.subplots()
2bar_width = 0.35
3opacity = 0.4
4rects1 = ax.bar(index, pts[:,0], bar_width,alpha=opacity, color='b',label='OFFENSE')
5rects2 = ax.bar(index + bar_width, pts[:,1], bar_width,alpha=opacity, color='r',     label='DEFENSE')
6ax.set_xlabel('Team')
7ax.set_ylabel('PTS')
8ax.set_xticks(index + bar_width / 2)
9ax.set_xticklabels(team_name)
10ax.set_yticks(np.arange(80,141,10)) 
11plt.show()

繪製的結果如下:

img03 散點圖分析球隊場均得失分

這一部分,我們使用散點圖來分析球隊場均得失分,使用plt.scatter函數,分別指定各個點的x和y值:

1plt.scatter(pts[:,0], pts[:,1])
2plt.xlabel('Offense PTS') 
3plt.ylabel('Defense PTS') 
4plt.show()

得到的效果如下:

img

簡單的繪製散點圖,什麼都看不出來,此時,我們提出兩個需求,首先,能不能將各個球隊的簡稱放到各個點的旁邊,這樣我們就能清楚知道哪個點代表哪個球隊。其次,能不能在圖中添加兩條直線,分別表示球隊得分和失分的平均值?我們一個一個來解決。

首先,將球隊標記加入到圖中,我們使用plt.annotate函數,該函數需要傳入三個參數,依次是注釋文本內容,被注釋的坐標點,注釋文字的坐標位置:

1plt.scatter(pts[:,0], pts[:,1])
2plt.xlabel('Offense PTS') 
3plt.ylabel('Defense PTS') 
4for i in range(len(pts[:,0])):    
5    plt.annotate(team_name[i], xy = (pts[i,0], pts[i,1]), xytext = (pts[i,0]+0.1, pts[i,1]+0.1)) 
6plt.show()

此時的效果就能滿足我們的第一個需求:

img

對於第二個需求,我們使用plt.vlines和plt.hlines方法,對於plt.vlines方法,它是在圖中繪製一條豎直線,因此需要指定x軸的坐標,同時需要指定y軸的起始坐標和結束坐標,對於plt.hlines方法,它是在圖中繪製一條水平線,因此需要指定y軸的坐標,同時需要指定x軸的起始坐標和結束坐標:

1offense_mean = np.mean(pts[:,0])
2defense_mean = np.mean(pts[:,1])
3print(offense_mean,defense_mean)
4plt.scatter(pts[:,0], pts[:,1])
5plt.vlines(np.mean(pts[:,0]), np.min(pts[:,1])-5,np.max(pts[:,1])+5,colors = "r", linestyles = "dashed")
6plt.hlines(np.mean(pts[:,1]), np.min(pts[:,0])-5,np.max(pts[:,0])+5,colors = "r", linestyles = "dashed")
7plt.ylim(np.min(pts[:,1])-5,np.max(pts[:,1])+5) 
8plt.xlim(np.min(pts[:,0])-5,np.max(pts[:,0])+5) 
9labelplt.ylabel('Defense PTS') 
10for i in range(len(pts[:,0])):    
11    plt.annotate(team_name[i], xy = (pts[i,0], pts[i,1]), xytext = (pts[i,0]+0.1, pts[i,1]+0.1)) 

結果如下:

img

基於上面的散點圖,我們就能很快將十六支球隊分為四個象限。
1)第一象限:進攻好,防守差,包含的球隊有金州勇士、費城76人、洛杉磯快船、布魯克林籃網
2)第二象限:進攻差,防守差,包含的球隊有底特律活塞、俄克拉荷馬雷霆、聖安東尼奧馬刺
3)第三象限:進攻差,防守好,包含的球隊有休斯頓火箭、奧蘭多魔術、印第安納步行者、猶他爵士、多倫多猛龍、波士頓凱爾特人
4)第四象限:進攻好,防守好,包含的球隊有密爾沃基雄鹿、波特蘭開拓者、丹佛掘金

哈哈,是不是跟你想像的不太一樣,比如火箭怎麼能說是進攻差的球隊呢!因為他們的對手爵士是全聯盟常規賽防守第一的球隊,這種因素我們是無法通過這種圖分析出來的。也就是說,數據不能表明一切!

04 基於雷達圖的火勇對決前瞻

勇士在今天的比賽中,憑藉杜蘭特的神奇表現,擊敗快船與火箭會師西部半決賽,這也是半決賽對決中最受人矚目的。那麼,我們通過雷達圖來分析下兩隊在季後賽首輪的表現吧。這裡要說明的是,我們的數據是在勇船第六場之前獲取的,因此只有勇士五場的數據。

我們先來看看兩隊的基礎數據,我們挑選了場均得分,場均失分、命中率、三分命中率、籃板、助攻、搶斷、蓋帽、失誤等九項數據:

1two_team_stats = mergedf[(mergedf['Team']=='Houston Rockets') | (mergedf['Team']=='Golden State Warriors')]
2hou_and_gsw_df = two_team_stats[['FG%','3P%','TRB','AST','STL','BLK','PTS','oppPTS','TOV']]
3print(hou_and_gsw_df)

結果如下,其中2代表勇士,7代表火箭:

img

接下來,我們想通過雷達圖來對比一下二者的這九項數據,matplotlib裡面的雷達圖貌似必須是統一刻度的,至少我目前還沒有找到如何設置為不同刻度。因此,我們首先將二者的數據,用統一的標準,轉換到0-1區間內:

1hou_and_gsw_data[:,0] = hou_and_gsw_data[:,0] / 0.55hou_and_gsw_data[:,1] = hou_and_gsw_data[:,1] / 0.55hou_and_gsw_data[:,2] = hou_and_gsw_data[:,2] / 55hou_and_gsw_data[:,3] = hou_and_gsw_data[:,3] / 40hou_and_gsw_data[:,4] = hou_and_gsw_data[:,4] / 12hou_and_gsw_data[:,5] = hou_and_gsw_data[:,5] / 12hou_and_gsw_data[:,6] = hou_and_gsw_data[:,6] / 130hou_and_gsw_data[:,7] = hou_and_gsw_data[:,7] / 130hou_and_gsw_data[:,8] = hou_and_gsw_data[:,8] / 20

繪製雷達圖,使用的是極坐標系,因此,我們需要設置一下:

1fig=plt.figure(figsize=(14,8))
2ax1=fig.add_subplot(1,1,1,polar=True) #設置第一個坐標軸為極坐標體系

隨後,我們獲取勇士和火箭的數據,並取得對應的數據標籤:

1gsw=hou_and_gsw_data[0,:] 
2hou=hou_and_gsw_data[1,:] 
3label=np.array([j for j in hou_and_gsw_df.columns]) 

隨後,我們基於label的數量,對整圓進行切分,在切分的同時,我們需要加入切分後的第一個元素,以形成一個閉環:

1angle = np.linspace(0, 2*np.pi, len(gsw), endpoint=False) 
2np.concatenate((angle, [angle[0]])) 
3np.concatenate((gsw, [gsw[0]])) 
4hou = np.concatenate((hou, [hou[0]])) 

隨後,便可以繪製我們的雷達圖:

1ax1.set_thetagrids(angles*180/np.pi, label, fontproperties="Microsoft Yahei") 
2ax1.plot(angles,gsw,"o-",label='GSW')
3ax1.plot(angles,hou,"o-",label='HOU')ax1.set_theta_zero_location('NW') 
4ax1.set_rlim(0,1) 
5ax1.fill(angles,gsw,facecolor='g', alpha=0.2) 
6ax1.set_title("HOU VS GSW",fontproperties="SimHei",fontsize=16) 
7plt.legend(loc = 'best')plt.show()

結果如下:

img

從雷達圖來看,火箭除了在搶斷和失分上佔據一定優勢外,其他各項數據均落後於勇士。不過還是剛才的那句話,數據不能體現一切,希望火勇雙方能給我們帶來一場精彩絕倫的較量。

相關焦點

  • 手把手帶你可視化分析NBA首輪球隊表現及火勇對決前瞻!
    作者 | 石曉文來源 | 小小挖掘機(ID:wAIsjwj)NBA激戰正酣,首輪除掘金和馬刺的較量還沒有結束外,其餘對決都已經結束,本文將手把手帶你可視化分析下各球隊的首輪表現,同時將對次輪最受矚目的火勇大戰進行一個簡單的前瞻分析!
  • kaggle:NBA球員投籃數據分析與可視化
    每位註冊參加的kaggler都可以自由獲取競賽題目和數據集,並將自己的數據分析方案以報告的形式呈現在平臺上供大家討論,最後被企業方採用的數據分析方案的參賽者將會獲得一大筆獎金。鑑於目前小編的水平,不敢貿然去參賽,生怕做出來的結果排名墊底,於是盤算著先拿幾個kaggle題的數據集來練手,一方面鍛鍊自己的數據思維和分析能力,另一方面則是提升R或者Python的coding能力。
  • 分享:關於NBA數據分析可視化(Python)
    這兩周上課剛給同學們嘰嘰歪歪聊完如何基於半結構化數據實現NBA的各種數據可視化,如圖然而,就在今天,發現了如此神器!!!首先,from shot_chart.core import *下載裝載數據shots_2019 = make_df(untar_data(URLs.SHOTS_2019))大家也可以直接去https://nba-shot-charts.s3.amazonaws.com/shots-2019.
  • 實戰|手把手教你用Python爬取存儲數據,還能自動在Excel中可視化
    清洗整理爬取的球員數據,對其進行可視化。目標URL如下:URL1:http://nba.hupu.com/players/URL2(此處以湖人球隊為例):https://nba.hupu.com/players/lakersURL3(
  • 【實戰】手把手教你用Python爬取存儲數據,還能自動在Excel中可視化!
    目標URL如下:URL1:http://nba.hupu.com/players/URL2(此處以湖人球隊為例):https://nba.hupu.com/players/lakersURL3(此處以詹姆斯為例):https://nba.hupu.com/players/lebronjames-650.html
  • 實戰|手把手教你用Python爬取存儲數據,還能自動在Excel中可視化!
    目標URL如下:URL1:http://nba.hupu.com/players/URL2(此處以湖人球隊為例):https://nba.hupu.com/players/lakersURL3(此處以詹姆斯為例):https://nba.hupu.com/players/lebronjames-650.html
  • Python數據可視化分析告訴你答案
    數據源來自Kaggle,提供了2012-2018年的所有球員的個人技術統計和球隊戰績,連結如下:https://www.kaggle.com/pablote/nba-enhanced-stats本篇採用2017-18年的統計數據對勇士隊進行分析。
  • 案例實操|手把手教你搭建,RFM客戶價值分析模型
    通過本文,你能夠理解和學會RFM模型的基礎知識,並且手把手教你用BI工具搭建RFM分析模型。內容大綱1、RFM客戶價值模型的強大之處RFM模型為什麼能成為客戶價值管理裡的「明星模型」?RFM模型能夠解決哪些業務問題?RFM模型應用的典型案例RFM模型能夠應用在以下行業領域和細分場景搭建RFM需要哪些基礎數據?
  • 用Python爬取NBA官網球員數據,並自動在Excel中可視化!
    目標URL如下:URL1:http://nba.hupu.com/players/URL2(此處以湖人球隊為例):https://nba.hupu.com/players/lakersURL3(此處以詹姆斯為例):https://nba.hupu.com/players/lebronjames-650.html
  • NBA季後賽西部次輪第一場 火湖大戰分析
    今天早上的九點的NBA季後賽西部次輪的火箭和湖人的比賽,雖然中央臺及企鵝臺沒播,但很多球友通過網絡各種渠道觀看了直播,結果大跌眼鏡,西部第一輸給西部第四15分之多,完全看起來像兩個不同檔次的nba球隊。但冷靜仔細理性分析,也覺得這結果合理正確。
  • NBA 投籃數據可視化,4行代碼就能實現
    關於NBA球員投籃數據的可視化,小F以前也寫過一篇文章。訪問地址:NBA球員投籃數據可視化自己畫球場圖,自己爬數據,碼了不少代碼。這回發現了大佬造的輪子,只需4行代碼就能實現。# 2000-2001賽季常規賽數據https://nba-shot-charts.s3.amazonaws.com/shots-2000.tgz.......................................................
  • NBA 投籃數據可視化,4 行代碼就能實現
    關於NBA球員投籃數據的可視化,小F以前也寫過一篇文章。訪問地址:NBA球員投籃數據可視化自己畫球場圖,自己爬數據,碼了不少代碼。這回發現了大佬造的輪子,只需4行代碼就能實現。# 2000-2001賽季常規賽數據https://nba-shot-charts.s3.amazonaws.com/shots-2000.tgz.......................................................
  • Excel製作圖表不行,用哪些可視化分析工具?
    好比公司領導讓你對某一個項目得研究成果做匯報,那麼你不可能給他看單純的數據一樣,你需要讓數據更直觀,甚至更美觀。像我們以前上學的時候學過的柱狀圖,餅狀圖,也是數據可視化的一種。 肯定會有人覺得不需用什麼可視化分析工具,excel就可以做柱狀圖餅狀圖啊。
  • 用python和BI可視化分析,湖人贏在這點上
    python和BI可視化分析,湖人贏在這點上。在經歷了很多很多之後,湖人隊終於獲得了總冠軍,眾望所歸。如果科比還在的話,一定也很自豪吧,畢竟上一次奪冠還是10年前。口說無憑,我覺得只有數據能說明一切,為此,我特地爬取了NBA和湖人以及季後賽對手的相關數據,意在從數據的角度看看球員的表現。註:數據來源準確,所使用的爬蟲工具為Python,分析工具為國產數據分析工具FineBI。大家都應該知道python是幹什麼的吧,那這裡就不再重複了,從獲取數據的角度上來看,python確實是一個很不錯的工具。
  • 周六直播:圖分析與可視化|《巴拉巴西網絡科學》最後一課
    直播預告 圖數據的可視化可以幫助人們對其結構進行理解與分析,目前市場上也有一些基於圖分析與可視化的產品與應用但是畢竟在國內圖分析與可視化整體生態正在萌芽,大家對其理解也是千差萬別,於是結合自身經驗,從可視分析、圖技術生態、產品與應用這三個角度聊聊對圖分析與可視化的一點系統理解。因為本身從事產品工作,因此並不是在技術上進行更多的探討,而是秉承著「好讀書不求甚解」的精神,為大家梳理一些應用思路,供參考。
  • 「疫情分析」的數據可視化大屏設計要點
    此刻,疫情仍然在蔓延,如何利用全面、有效,及時的數據和可視化技術準確感知疫情態勢,為決策者、管理人員提供宏觀數據依據,節省決策時間,讓數據可視化成為管理者和時間賽跑的幫手,是快速打贏這場「戰疫」的關鍵。在家為祖國做貢獻期間,設計了該NCP疫情數據可視化大屏,並總結了一些關於數據可視化大屏設計的思考。
  • 大數據可視化常用分析圖表的優缺點
    可視化圖表次整理了一些平常不太使用,但在合適的場景的使用它們,往往能為你的分析報告加分不少的圖表。   需要說明的是,這次演示的圖表幾乎都是用Tableau製作的「因自身學習的原因」,不再是Excel製作的圖表。
  • 幾行代碼搞定NBA球員數據分析
    - 基本概念    - 數據分析是指用適當的方法與工具,對收集來的大量數據進行分析,提取其中有意義的信息
  • 手把手教你如何使用DeFi分析工具DeFiBox
    今天為大家介紹一款當前再DeFi市場使用比較廣泛的DeFi分析工具——DeFiBox,幫助用戶快速高效地了解DeFi項目和DeFi相關數據。根據官方介紹,DeFiBox是一個專注於幫助用戶捕捉DeFi世界最新投資機會、精準把脈用戶投資收益率和提供一站式DeFi資產和信息聚合平臺。
  • 如何選擇數據分析可視化工具?Excel,Tableau還是Power BI?
    正確分析使用數據可能會挖到寶藏。那麼,作為個人或公司,如何選擇分析和可視化數據的工具? 用戶可以選擇許多可視化作為藍圖,然後使用Power BI將側邊欄中的數據插入到可視化中。它還允許用戶通過使用自然語言進行查詢來創建可視化效果。當深入到數據集進行分析時,Power BI確實設置了3500個數據點限制。