# NBA球员投篮数据可视化分析

/ 01 / 篮球场

```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

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

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

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

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

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

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

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

# 绘制三分线的圆弧,圆心为(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

# 绘制中场处的外半圆,半径为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

# 绘制中场处的内半圆,半径为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

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

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 / 投篮数据

```import requests
import json

'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='
# 请求结果

# 获取数据
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')```

/ 03 / 数据可视化

```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)```

```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')```

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

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

/ 04 / 总结

0 条评论

• ### python算法与数据结构-双向链表(40)

一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链接：一个指向前一个节点，当此节点为第一个节点时，指向空值；而另一个指向下一个节点，当此节点为最...

• ### mybatis 查询的时候提示 JDBC requires that the JdbcType 错误的解决方法

1：mybatis查询时候提示错误：JDBC requires that the JdbcType

• ### 骚操作！用Python把公众号文章打包成pdf文件,不再怕自己的劳动成果被丢失

做自媒体的人，尤其是做了一年甚至更久的自媒体人，尤其是通过自媒体还有一些小收入的人，他们最怕自己的公众号内容因为各种原因而丢失，那就太可怕了! 在做自媒体内容上...

• ### 菜鸟学Python——初识Python

很多初学Python的同学经常问我这样的问题：学Python应该看什么书啊？我会非常自信的把之前整理的Python教程扔给他，后来收到很多反馈：你的排版太烂了...

• ### python基础-变量运算符(3)

注释就是对代码的解释和说明。目的是为了让别人和自己很容易看懂。为了让别人一看就知道这段代码是做什么用的。正确的程序注释一般包括序言性注释和功能性注释。序言性注释...

• ### 项目实战 | 手把手做一款小说阅读器

前一段时间书荒的时候，在喜马拉雅APP发现一个主播播讲的小说-大王饶命。听起来感觉很好笑，挺有意思的，但是只有前200张是免费的，后面就要收费。一章两毛钱，本来...

• ### 工欲善其事,必先利其器-Python编辑器选择(2)

一款顺手的好的编辑器可以让程序员写代码更得心应手，效率也会更高，但是编辑器本身没有好坏，只有使用者使用起来是否顺手而已，这里简单给大家介绍几款常用的可以编辑Py...

• ### PyCharm在创建py文件时自动添加默认头部注释

File ----->> Setting ----->> Editor ----->> File and Code Templates ----->> Pyth...

• ### celery时差问题解决方法

请记得点赞和分享这篇文章让更多的人看到它！另外，记得关注我的简书号马哥学Python，这样你就不会错过任何有价值的文章！