最近看了公众号「Crossin的编程教室」的一篇文章。

是有关于NBA球员出手数据的可视化案例,原文链接如下。

个人感觉比较有趣,所以想着自己也来实现一波。

总体上来说差不多,可能就是美观点吧...

/ 01 / 篮球场

从网上找的篮球场尺寸图,如下。

其中单位为英尺,NBA的球场尺寸为94英尺长,50英尺宽。

下图是我用CAD绘制半场尺寸图,本次绘图就是按照下面这个尺寸来的。

有了尺寸,接下来就可以使用matplotlib进行绘制篮球场了。

主要是绘制矩形、圆形以及圆弧。

具体代码如下。

from matplotlib import pyplot as plt
from matplotlib.patches import Arc, Circle, Rectangle

def draw_ball_field(color='#20458C', lw=2):
    """
    绘制篮球场
    """
    # 新建一个大小为(6,6)的绘图窗口
    plt.figure(figsize=(6, 6))
    # 获得当前的Axes对象ax,进行绘图
    ax = plt.gca()

# 对篮球场进行底色填充
    lines_outer_rec = Rectangle(xy=(-250, -47.5), width=500, height=470, linewidth=lw, color='#F0F0F0', fill=True)
    # 设置篮球场填充图层为最底层
    lines_outer_rec.set_zorder(0)
    # 将rec添加进ax
    ax.add_patch(lines_outer_rec)

# 绘制篮筐,半径为7.5
    circle_ball = Circle(xy=(0, 0), radius=7.5, linewidth=lw, color=color, fill=False)
    # 将circle添加进ax
    ax.add_patch(circle_ball)

# 绘制篮板,尺寸为(60,1)
    plate = Rectangle(xy=(-30, -7.5), width=60, height=-1, linewidth=lw, color=color, fill=False)
    # 将rec添加进ax
    ax.add_patch(plate)

# 绘制2分区的外框线,尺寸为(160,190)
    outer_rec = Rectangle(xy=(-80, -47.5), width=160, height=190, linewidth=lw, color=color, fill=False)
    # 将rec添加进ax
    ax.add_patch(outer_rec)

# 绘制2分区的内框线,尺寸为(120,190)
    inner_rec = Rectangle(xy=(-60, -47.5), width=120, height=190, linewidth=lw, color=color, fill=False)
    # 将rec添加进ax
    ax.add_patch(inner_rec)

# 绘制罚球区域圆圈,半径为60
    circle_punish = Circle(xy=(0, 142.5), radius=60, linewidth=lw, color=color, fill=False)
    # 将circle添加进ax
    ax.add_patch(circle_punish)

# 绘制三分线的左边线
    three_left_rec = Rectangle(xy=(-220, -47.5), width=0, height=140, linewidth=lw, color=color, fill=False)
    # 将rec添加进ax
    ax.add_patch(three_left_rec)

# 绘制三分线的右边线
    three_right_rec = Rectangle(xy=(220, -47.5), width=0, height=140, linewidth=lw, color=color, fill=False)
    # 将rec添加进ax
    ax.add_patch(three_right_rec)

# 绘制三分线的圆弧,圆心为(0,0),半径为238.66,起始角度为22.8,结束角度为157.2
    three_arc = Arc(xy=(0, 0), width=477.32, height=477.32, theta1=22.8, theta2=157.2, linewidth=lw, color=color, fill=False)
    # 将arc添加进ax
    ax.add_patch(three_arc)

# 绘制中场处的外半圆,半径为60
    center_outer_arc = Arc(xy=(0, 422.5), width=120, height=120, theta1=180, theta2=0, linewidth=lw, color=color, fill=False)
    # 将arc添加进ax
    ax.add_patch(center_outer_arc)

# 绘制中场处的内半圆,半径为20
    center_inner_arc = Arc(xy=(0, 422.5), width=40, height=40, theta1=180, theta2=0, linewidth=lw, color=color, fill=False)
    # 将arc添加进ax
    ax.add_patch(center_inner_arc)

# 绘制篮球场外框线,尺寸为(500,470)
    lines_outer_rec = Rectangle(xy=(-250, -47.5), width=500, height=470, linewidth=lw, color=color, fill=False)
    # 将rec添加进ax
    ax.add_patch(lines_outer_rec)

return ax

axs = draw_ball_field(color='#20458C', lw=2)

# 设置坐标轴范围
axs.set_xlim(-250, 250)
axs.set_ylim(422.5, -47.5)
# 消除坐标轴刻度
axs.set_xticks([])
axs.set_yticks([])
# 添加备注信息
plt.annotate('By xiao F', xy=(100, 160), xytext=(178, 418))
plt.show()

最后得到下图。

下面去获取球员的投篮数据。

/ 02 / 投篮数据

投篮数据来源于NBA官方网站——NBA Stats。

在这个网页下打开开发者工具,找到下面这个请求。

便能获取到球员的投篮数据,本次只获取球员的投篮点及是否得分的数据。

这里以「库里」为例,爬取代码如下。

import requests
import json

headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
    }

# 球员职业生涯时间
years = [2018, 2019]
for i in range(years[0], years[1]):
    # 赛季
    season = str(i) + '-' + str(i + 1)[-2:]
    # 球员ID
    player_id = '201939'
    # 请求网址
    url = 'https://stats.nba.com/stats/shotchartdetail?AheadBehind=&CFID=33&CFPARAMS=' + season + '&ClutchTime=&Conference=&ContextFilter=&ContextMeasure=FGA&DateFrom=&DateTo=&Division=&EndPeriod=10&EndRange=28800&GROUP_ID=&GameEventID=&GameID=&GameSegment=&GroupID=&GroupMode=&GroupQuantity=5&LastNGames=0&LeagueID=00&Location=&Month=0&OnOff=&OpponentTeamID=0&Outcome=&PORound=0&Period=0&PlayerID=' + player_id + '&PlayerID1=&PlayerID2=&PlayerID3=&PlayerID4=&PlayerID5=&PlayerPosition=&PointDiff=&Position=&RangeType=0&RookieYear=&Season=' + season + '&SeasonSegment=&SeasonType=Regular+Season&ShotClockRange=&StartPeriod=1&StartRange=0&StarterBench=&TeamID=0&VsConference=&VsDivision=&VsPlayerID1=&VsPlayerID2=&VsPlayerID3=&VsPlayerID4=&VsPlayerID5=&VsTeamID='
    # 请求结果
    response = requests.get(url=url, headers=headers)
    result = json.loads(response.text)

# 获取数据
    for item in result['resultSets'][0]['rowSet']:
        # 是否进球得分
        flag = item[10]
        # 横坐标
        loc_x = str(item[17])
        # 纵坐标
        loc_y = str(item[18])
        with open('curry.csv', 'a+') as f:
            f.write(loc_x + ',' + loc_y + ',' + flag + '\n')

获取到的数据如下。

其中可以通过设置球员ID以及赛季时间来获取不同的数据。

球员ID和赛季时间可以通过官网中的球员信息网页了解到。

/ 03 / 数据可视化

现在球场有了,投篮数据也有了,就可以来画图了。

使用matplotlib的散点图来实现。

import pandas as pd

# 读取数据
df = pd.read_csv('curry.csv', header=None, names=['width', 'height', 'type'])
# 分类数据
df1 = df[df['type'] == 'Made Shot']
df2 = df[df['type'] == 'Missed Shot']
# 绘制散点图
axs.scatter(x=df2['width'], y=df2['height'], s=30, marker='x', color='#A82B2B')
axs.scatter(x=df1['width'], y=df1['height'], s=30, marker='o', edgecolors='#3A7711', color="#F0F0F0", linewidths=2)

得到下图。

来和官网的图对比一下。

看起来还不错,匹配度还是蛮高的。

下面绘制投篮热力图,通过seaborn绘制,代码如下。

import seaborn as sns
import matplotlib as mpl

# 读取数据
df = pd.read_csv('curry.csv', header=None, names=['width', 'height', 'type'])

def colormap():
    """
    颜色转换
    """
    return mpl.colors.LinearSegmentedColormap.from_list('cmap', ['#C5C5C5', '#9F9F9F', '#706A7C', '#675678', '#713A71','#9D3E5E', '#BC5245',  '#C86138', '#C96239', '#D37636', '#D67F39', '#DA8C3E', '#E1A352'], 256)

# 绘制球员投篮热力图
shot_heatmap = sns.jointplot(df['width'], df['height'], stat_func=None, kind='kde', space=0, color='w', cmap=colormap())
# 设置图像大小
shot_heatmap.fig.set_size_inches(6, 6)
# 图像反向
ax = shot_heatmap.ax_joint
# 绘制投篮散点图
ax.scatter(x=df['width'], y=df['height'], s=0.1, marker='o', color="w", alpha=1)
# 添加篮球场
draw_ball_field(color='w', lw=2)
# 将坐标轴颜色更改为白色
lines = plt.gca()
lines.spines['top'].set_color('none')
lines.spines['left'].set_color('none')
# 去除坐标轴标签
ax.axis('off')

得到结果如下。

还是来看一下官网的图。

两个效果都不错,不过边框我没调好,显得没那么好看。

库里投篮最密集的区域,篮下和三分线。

最后看一下于小F而言,印象比较深的球员,「科比」和「霍华德」。

「科比」的ID为977,职业生涯时间为1996年到2012年。

全线开花,不少负角度投篮,甚至还有超远三分。

「霍华德」的ID为2730,职业生涯时间为2004年到2019年。

魔兽霍华德,屈指可数的三分。

其他都是围绕着篮板的得分。

还有好多球员,就靠大伙自己去看啦!

推荐阅读

···END···

扫二维码关注

NBA球员投篮数据可视化相关推荐

  1. python绘图篮球_用Python把NBA球员投篮数据可视化

    最近看了一篇文章是有关于NBA球员出手数据的可视化案例,原文链接如下. 虎扑热帖|Python数据分析|NBA的球星们喜欢在哪个位置出手 个人感觉比较有趣,所以想着自己也来实现一波. 总体上来说差不多 ...

  2. NBA 投篮数据可视化,4行代码就能实现!

    作者 | 小F 来源 | 法纳斯特(ID:walker398) 头图 |  CSDN 下载自东方IC 之前小F说了G6湖人总冠军,果不其然湖人夺冠了. 不过硬实力摆在那里,说不说其实关系也不大,哈哈哈 ...

  3. NBA 投篮数据可视化,4 行代码就能实现!

    作者 | 小F 来源 | 法纳斯特(ID:walker398) 头图 |  CSDN 下载自东方IC 之前小F说了G6湖人总冠军,果不其然湖人夺冠了. 不过硬实力摆在那里,说不说其实关系也不大,哈哈哈 ...

  4. nba球员数据分析和可视化_可视化NBA球员统计

    nba球员数据分析和可视化 I haven't written a post in a while. I had a lot to do for university and my hobbies l ...

  5. 爬table数据_爬取NBA球员薪资数据【Python数据分析百例连载】

    通过Pandas模块也可以实现简单的爬虫.主要使用Pandas的read_html方法,该方法用于导入带有table标签的网页表格数据,语法如下: pandas.read_html(io,match= ...

  6. NBA球员生涯数据统计系统(中南大学C语言课设)

    自动化与电气类专业大一第一学期C语言的课程设计,留给后来的新生参考. 前排提醒:由于链表和文件不属于课程学习内容,且本人自学能力菜得真实,因此本人写的课设没有使用到链表(在学了在学了).但据本人同学所 ...

  7. 爬取2016-2017赛季NBA球员的数据

    最近学习了下爬虫就自己想爬个NBA球员的数据,记录一下自己第一次的爬虫 其中有一个问题实在无法解决了,就是一些超长名字用制表符 "\t" 对不齐的情况,"\t" ...

  8. kaggle:NBA球员投篮数据分析与可视化

    感谢关注天善智能,走好数据之路↑↑↑ 欢迎关注天善智能,我们是专注于商业智能BI,大数据,数据分析领域的垂直社区,学习,问答.求职一站式搞定! 本文作者:天善智能社区专家鲁伟 天善智能社区地址:htt ...

  9. kaggle:NBA球员投篮数据分析与可视化(一)

    作为数据科学领域的金字招牌,kaggle已成为世界上最受欢迎的数据科学竞赛平台.在kaggle上,每个竞赛题下都藏匿着大批来自世界各地并且身怀绝技的数据科学家.作为一种众包模式,kaggle通过收取部 ...

最新文章

  1. 在矩阵上跑最小生成树
  2. 用Python创建漂亮的交互式可视化效果
  3. php nginx日志分析,如何通过NGINX的log日志来分析网站的访问情况,试试这些命令...
  4. 如何用Pygame写游戏(十七)
  5. 嘉奥丰农显示无法连接服务器,Arcaea无法连接服务器如何解决
  6. Vi编辑器的基本使用方法及vi和Vim的区别【ZT】
  7. mysql返回前2行_取得前一次MySQL操作所影响的记录行数
  8. java书籍_2020年java从入门到进阶书籍推荐,基础\自学\编程\数据结构\后端\虚拟机\网络\设计模式书籍...
  9. 文件读写: 二进制方式和文本方式的区别
  10. 【Unity3D】Photon环境搭建
  11. 【微信小程序项目】——十分钟开发网络API·天气查询小程序、天气查询,美观简约,简单易上手
  12. 求解答!iframe在IE浏览器加载页面无反应问题
  13. 手机丢了,微信、支付宝绑了银行卡,第一时间该怎么办?
  14. 输入一个小写字母变成下一个小写字母(z变a)
  15. java虚拟机与安卓虚拟机的区别
  16. kepler克卜勒_克卜勒(Kepler)
  17. Crossplane 和 Terraform 的区别
  18. 【微信小程序+echarts点亮中国地图】微信小程序echarts中国地图点亮功能
  19. 基于图正则化的贝叶斯宽度学习系统
  20. rtthread的console

热门文章

  1. mysql 为什么使用视图_Mysql为什么要使用视图?
  2. 消费平板售后镜像一键刷机操作教程
  3. 在Dell服务器PowerEdge R730上安装操作系统
  4. 边缘服务器 邮件队列堵塞,位于集线器传输服务器上无法到达队列中的出站邮件问题疑难解答...
  5. php采集一言代码_【PHP】简单的一言API源码
  6. 未来Web3将用邮箱或密码登陆?
  7. bat如何执行完上一条命令_一条SQL查询语句是如何执行的?
  8. Unity3d中实现翻书效果(一)
  9. 阿里云轻量应用服务器应用镜像——WordPress 4.8.1
  10. Noah Mt4跟单系统制作第五篇 Mt4TradeApi挂单篇