科比投籃數據可視化小例子

作為一名喜歡籃球的python初學者,一直在尋找利用python分析NBA比賽數據的案例,希望可以通過重複這些案例提高自己的python編程水平,畢竟將相對比較無聊的程式碼和自己的興趣結合起來,可以使學習過程顯得不再那麼單調!下文內容介紹自己找到並完全重複其程式碼的一個案例。

原文地址 How to Create NBA Shot Charts in Python;原文的主要內容是通過可視化的手段展示哈登2014-2015賽季的投籃數據。但是第一部分通過爬蟲獲取數據的過程自己還不是很理解,沒有能夠獲得原文使用的數據集。稍顯遺憾之際想到了自己之前重複過的一個kaggle案例 Kobe Brant Shot Selection —— 科比的投籃選擇。數據集完全匹配,遂用科比的投籃數據來重複原文。

第一部分:使用matplotlib畫一個籃球場
from matplotlib.patches import Circle  from matplotlib.patches import Rectangle  from matplotlib.patches import Arc    def draw_court(ax=None,color='black',lw=2,outer_lines=False):      if ax is None:          ax = plt.gca()      hoop = Circle((0,0),radius=7.5,linewidth=lw,color=color,fill=False)      backboard = Rectangle((-30,-7.5),60,-1,linewidth=lw,color=color)      outer_box = Rectangle((-80,-47.5),160,190,linewidth=lw,color=color,fill=False)      inner_box = Rectangle((-60,-47.5),120,190,linewidth=lw,color=color,fill=False)      top_free_throw = Arc((0,142.5),120,120,theta1=0,theta2=180,linewidth=lw,color=color,fill=False)      bottom_free_throw = Arc((0,142.5),120,120,theta1=180,theta2=0,linewidth=lw,color=color,linestyle='dashed')      restricted = Arc((0,0),80,80,theta1=0,theta2=180,linewidth=lw,color=color)      corner_three_a = Rectangle((-220,-47.5),0,140,linewidth=lw,color=color)      corner_three_b = Rectangle((220,-47.5),0,140,linewidth=lw,color=color)      three_arc = Arc((0,0),475,475,theta1=22,theta2=158,linewidth=lw,color=color)      center_outer_arc = Arc((0,422.5),120,120,theta1=180,theta2=0,linewidth=lw,color=color)      center_inner_arc = Arc((0,422.5),40,40,theta1=180,theta2=0,linewidth=lw,color=color)      court_elements = [hoop, backboard,outer_box,inner_box,top_free_throw,bottom_free_throw,restricted,corner_three_a,corner_three_b,three_arc,center_outer_arc,center_inner_arc]      if outer_lines:          outer_lines = Rectangle((-250,-47.5),500,470,linewidth=lw,color=color,fill=False)          court_elements.append(outer_lines)      for element in court_elements:          ax.add_patch(element)      return ax  

Court_1.jpg

第二部分:籃球場結合科比的投籃數據

import pandas as pd  import matplotlib.pyplot as plt    shot_df = pd.read_csv("data.csv")    plt.figure(figsize=(12,11))  plt.scatter(shot_df.loc_x,shot_df.loc_y)  draw_court(outer_lines=True)  plt.xlim(300,-300)  plt.show()  

Court_2.jpg

第三部分:jointplot

jointplot是什麼意思自己還不太明白

import seaborn as sns  joint_shot_chart = sns.jointplot(shot_df.loc_x,shot_df.loc_y,stat_func=None,kind='scatter',space=0,alpha=0.5)  joint_shot_chart.fig.set_size_inches(12,11)  ax = joint_shot_chart.ax_joint  draw_court(ax)  ax.set_xlim(-250,250)  ax.set_ylim(422.5,-47.5)  ax.set_xlabel('')  ax.set_ylabel('')  ax.tick_params(labelbottom='off',labelleft='off')  ax.set_title('The location and circumstances of every field goal attempted by Kobe Bryant',y=1.2,fontsize=18)  ax.text(-250,445,'Data Source: KagglenAuthor:MingYan',fontsize=12)  plt.show()  

Court_3.jpg

第四部分:抓取一張科比的大頭貼

import urllib.request    url = "https://d2cwpp38twqe55.cloudfront.net/req/201902151/images/players/bryanko01.jpg"  picture = urllib.request.urlretrieve(url)  kobe_picture = plt.imread(picture[0])  plt.imshow(kobe_picture)  plt.savefig("Kobe.jpg")  

Kobe.jpg

第五部分:將大頭貼和投籃分布圖結合到一起

from matplotlib.offsetbox import OffsetImage  cmap = plt.cm.YlOrRd_r  joint_shot_chart = sns.jointplot(shot_df.loc_x,shot_df.loc_y,stat_func=None,kind='kde',space=0,color=cmap(0.1),cmap=cmap,n_levels=50)  joint_shot_chart.fig.set_size_inches(12,11)  ax = joint_shot_chart.ax_joint  draw_court(ax)  ax.set_xlim(-250,250)  ax.set_ylim(422.5,-47.5)  ax.set_xlabel('')  ax.set_ylabel('')  ax.tick_params(labelbottom='off',labelleft='off')  ax.set_title('The location of every goal attempted by Kobe Bryabt took during his 20-year career',y=1.2,fontsize=18)  ax.text(-250,445,"Data Source: KagglenPorter: MingYan",fontsize=12)  img = OffsetImage(kobe_picture,zoom=0.6)  img.set_offset((1000,920))  ax.add_artist(img)  plt.savefig("Court_4.jpg")  

Court_4.jpg

第五部分:換另外一種風格

cmap = plt.cm.gist_heat_r  joint_shot_chart = sns.jointplot(shot_df.loc_x,shot_df.loc_y,stat_func=None,kind='hex',space=0,color=cmap(.2),cmap=cmap)  joint_shot_chart.fig.set_size_inches(12,11)  ax = joint_shot_chart.ax_joint  draw_court(ax)  ax.set_xlim(-250,250)  ax.set_ylim(422.5,-47.5)  ax.set_xlabel('')  ax.set_ylabel('')  ax.tick_params(labelbottom='off',labelleft='off')  ax.set_title('The location of every goal attempted by Kobe Bryabt took during his 20-year career',y=1.2,fontsize=18)  ax.text(-250,445,"Data Source: KagglenPorter: MingYan",fontsize=12)  img = OffsetImage(kobe_picture,zoom=0.6)  img.set_offset((1000,920))  ax.add_artist(img)  plt.savefig("Court_5.jpg")  

Court_5.jpg

第六部分:版本資訊

print('Python version:',sys.version_info)  import IPython  print('IPython version:', IPython.__version__)  print('Urllib.requests version:', urllib.request.__version__)  import matplotlib as mpl  print('Matplotlib version:', mpl.__version__)  print('Seaborn version:', sns.__version__)  print('Pandas version:', pd.__version__)  
Python version: sys.version_info(major=3, minor=6, micro=3, releaselevel='final', serial=0)  IPython version: 6.1.0  Urllib.requests version: 3.6  Matplotlib version: 2.1.0  Seaborn version: 0.5.0  Pandas version: 0.20.3