如何运用python绘制nba投篮图表

2024-05-19 02:24

1. 如何运用python绘制nba投篮图表

调出菜单,进入(球员)选项中的(装备升级)选项,找到(专属动作)里的(跳投),按一下游戏左键,就会显示你最近买的投篮动作。不用进(编辑球员)选项。

如何运用python绘制nba投篮图表

2. 如何使用 Python 创建一个 NBA 得分图

首先,我们需要获得每个球员的投篮数据。利用 Savvas Tjortjoglou 贴出的代码,笔者从 NBA.com 网站 API 上获取了数据。在此不会贴出这个函数的结果。如果你感兴趣,推荐你去看看 Savvas Tjortjoglou 的博客。

def aqcuire_shootingData(PlayerID,Season):
import requests
shot_chart_url = 'http://stats.nba.com/stats/shotchartdetail?CFID=33&CFPARAMS='+Season+'&ContextFilter='\
'&ContextMeasure=FGA&DateFrom=&DateTo=&GameID=&GameSegment=&LastNGames=0&LeagueID='\
'00&Location=&MeasureType=Base&Month=0&OpponentTeamID=0&Outcome=&PaceAdjust='\
'N&PerMode=PerGame&Period=0&PlayerID='+PlayerID+'&PlusMinus=N&Position=&Rank='\
'N&RookieYear=&Season='+Season+'&SeasonSegment=&SeasonType=Regular+Season&TeamID='\
'0&VsConference=&VsDivision=&mode=Advanced&showDetails=0&showShots=1&showZones=0'
response = requests.get(shot_chart_url)
headers = response.json()['resultSets'][0]['headers']
shots = response.json()['resultSets'][0]['rowSet']
shot_df = pd.DataFrame(shots, columns=headers)
return shot_df


接下来,我们需要绘制一个包含得分图的篮球场图。该篮球场图例必须使用与NBA.com API 相同的坐标系统。例如,3分位置的投篮距篮筐必须为 X 单位,上篮距离篮筐则是 Y 单位。同样,笔者再次使用了 Savvas Tjortjoglou 的代码(哈哈,否则的话,搞明白 NBA.com 网站的坐标系统肯定会耗费不少的时间)。

def draw_court(ax=None, color='black', lw=2, outer_lines=False):
from matplotlib.patches import Circle, Rectangle, Arc
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)

ax.set_xticklabels([])
ax.set_yticklabels([])
ax.set_xticks([])
ax.set_yticks([])
return ax


我想创造一个不同位置的投篮百分比数组,因此决定利用 matplot 的 Hexbin 函数 http://matplotlib.org/api/pyplot_api.html 将投篮位置均匀地分组到六边形中。该函数会对每个六边形中每一个位置的投篮次数进行计数。

六边形是均匀的分布在 XY 网格中。「gridsize」变量控制六边形的数目。「extent」变量控制第一个和最后一个六边形的绘制位置(一般来说第一个六边形的位置基于第一个投篮的位置)。

计算命中率则需要对每个六边形中投篮的次数和投篮得分次数进行计数,因此笔者对同一位置的投篮和得分数分别运行 hexbin 函数。然后,只需用每个位置的进球数除以投篮数。

def find_shootingPcts(shot_df, gridNum):
x = shot_df.LOC_X[shot_df['LOC_Y']<425.1] #i want to make sure to only include shots I can draw
y = shot_df.LOC_Y[shot_df['LOC_Y']<425.1]

x_made = shot_df.LOC_X[(shot_df['SHOT_MADE_FLAG']==1) & (shot_df['LOC_Y']<425.1)]
y_made = shot_df.LOC_Y[(shot_df['SHOT_MADE_FLAG']==1) & (shot_df['LOC_Y']<425.1)]

#compute number of shots made and taken from each hexbin location
hb_shot = plt.hexbin(x, y, gridsize=gridNum, extent=(-250,250,425,-50));
plt.close() #don't want to show this figure!
hb_made = plt.hexbin(x_made, y_made, gridsize=gridNum, extent=(-250,250,425,-50),cmap=plt.cm.Reds);
plt.close()

#compute shooting percentage
ShootingPctLocs = hb_made.get_array() / hb_shot.get_array()
ShootingPctLocs[np.isnan(ShootingPctLocs)] = 0 #makes 0/0s=0
return (ShootingPctLocs, hb_shot)


笔者非常喜欢 Savvas Tjortjoglou 在他的得分图中加入了球员头像的做法,因此也顺道用了他的这部分代码。球员照片会出现在得分图的右下角。

def acquire_playerPic(PlayerID, zoom, offset=(250,400)):
from matplotlib import  offsetbox as osb
import urllib
pic = urllib.urlretrieve("http://stats.nba.com/media/players/230x185/"+PlayerID+".png",PlayerID+".png")
player_pic = plt.imread(pic[0])
img = osb.OffsetImage(player_pic, zoom)
#img.set_offset(offset)
img = osb.AnnotationBbox(img, offset,xycoords='data',pad=0.0, box_alignment=(1,0), frameon=False)
return img


笔者想用连续的颜色图来描述投篮进球百分比,红圈越多代表着更高的进球百分比。虽然「红」颜色图示效果不错,但是它会将0%的投篮进球百分比显示为白色http://matplotlib.org/users/colormaps.html,而这样显示就会不明显,所以笔者用淡粉红色代表0%的命中率,因此对红颜色图做了下面的修改。

#cmap = plt.cm.Reds
#cdict = cmap._segmentdata
cdict = {
'blue': [(0.0, 0.6313725709915161, 0.6313725709915161), (0.25, 0.4470588266849518, 0.4470588266849518), (0.5, 0.29019609093666077, 0.29019609093666077), (0.75, 0.11372549086809158, 0.11372549086809158), (1.0, 0.05098039284348488, 0.05098039284348488)],
'green': [(0.0, 0.7333333492279053, 0.7333333492279053), (0.25, 0.572549045085907, 0.572549045085907), (0.5, 0.4156862795352936, 0.4156862795352936), (0.75, 0.0941176488995552, 0.0941176488995552), (1.0, 0.0, 0.0)],
'red': [(0.0, 0.9882352948188782, 0.9882352948188782), (0.25, 0.9882352948188782, 0.9882352948188782), (0.5, 0.9843137264251709, 0.9843137264251709), (0.75, 0.7960784435272217, 0.7960784435272217), (1.0, 0.40392157435417175, 0.40392157435417175)]
}

mymap = mpl.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)


好了,现在需要做的就是将它们合并到一块儿。下面所示的较大函数会利用上文描述的函数来创建一个描述投篮命中率的得分图,百分比由红圈表示(红色越深 = 更高的命中率),投篮次数则由圆圈的大小决定(圆圈越大 = 投篮次数越多)。需要注意的是,圆圈在交叠之前都能增大。一旦圆圈开始交叠,就无法继续增大。

在这个函数中,计算了每个位置的投篮进球百分比和投篮次数。然后画出在该位置投篮的次数(圆圈大小)和进球百分比(圆圈颜色深浅)。

def shooting_plot(shot_df, plot_size=(12,8),gridNum=30):
from matplotlib.patches import Circle
x = shot_df.LOC_X[shot_df['LOC_Y']<425.1]
y = shot_df.LOC_Y[shot_df['LOC_Y']<425.1]

#compute shooting percentage and # of shots
(ShootingPctLocs, shotNumber) = find_shootingPcts(shot_df, gridNum)

#draw figure and court
fig = plt.figure(figsize=plot_size)#(12,7)
cmap = mymap #my modified colormap
ax = plt.axes([0.1, 0.1, 0.8, 0.8]) #where to place the plot within the figure
draw_court(outer_lines=False)
plt.xlim(-250,250)
plt.ylim(400, -25)

#draw player image
zoom = np.float(plot_size[0])/(12.0*2) #how much to zoom the player's pic. I have this hackily dependent on figure size
img = acquire_playerPic(PlayerID, zoom)
ax.add_artist(img)

#draw circles
for i, shots in enumerate(ShootingPctLocs):
restricted = Circle(shotNumber.get_offsets()[i], radius=shotNumber.get_array()[i],
color=cmap(shots),alpha=0.8, fill=True)
if restricted.radius > 240/gridNum: restricted.radius=240/gridNum
ax.add_patch(restricted)

#draw color bar
ax2 = fig.add_axes([0.92, 0.1, 0.02, 0.8])
cb = mpl.colorbar.ColorbarBase(ax2,cmap=cmap, orientation='vertical')
cb.set_label('Shooting %')
cb.set_ticks([0.0, 0.25, 0.5, 0.75, 1.0])
cb.set_ticklabels(['0%','25%', '50%','75%', '100%'])

plt.show()
return ax


好了,大功告成!因为笔者是森林狼队的粉丝,在下面用几分钟跑出了森林狼队前六甲的得分图。

PlayerID = '203952' #andrew wiggins
shot_df = aqcuire_shootingData(PlayerID,'2015-16')
ax = shooting_plot(shot_df, plot_size=(12,8));

3. NBA这三十年发生了什么,Python告诉你

不太可能找到那么多数据,以前看到有一个分析2016-2018赛季的,在NBA官网找的数据,预测胜率

NBA这三十年发生了什么,Python告诉你

4. 谁是nba最佳球员 python

2007年官方投票的结果。

1) Michael Jordan
2) Kareem Abdul-Jabbar
3) Magic Johnson
4) Shaquille O'Neal
5) Wilt Chamberlain
6) Bill Russell
7) Tim Duncan
8) Larry Bird
9) Oscar Robertson
10) Karl Malone

5. 关于Python命令行的NBA文字直播小工具

找了一圈NBA文字直播网站,发现手机版直播吧有现成的接口,直接返回json格式数据。那就是它了,听我慢慢道来。
首先在电脑浏览器打开手机版直播吧,我用的是chrome浏览器,在Network中可以看到,它不停地用GET方式请求http://bifen4m.qiumibao.com/json/list.htm,这个地址会返回当前正在进行的所有类型比赛的基本情况,根据其中的type字段过滤掉非NBA比赛就OK了。其中最重要的是ID字段,之后的所有操作都需要用到。返回的数据如下所示:
{
"code": "2760624",
"second": "10",
"list": [
{
"id": "96233",
"sdate": "2017-04-20",
"time": "10:30",
"url": "/zhibo/nba/2017/042096233.htm",
"type": "basketball",
"start": "2017-04-20 10:30",
"home_team": "勇士",
"visit_team": "开拓者",
"home_score": "106",
"visit_score": "81",
"period_cn": "第4节\n01:30",
"from": "dc.live",
"code": "373",
"update": "13:13:37",
"big_score_1": "",
"big_score_2": ""
},
... # 省略了其它比赛的信息
]}12345678910111213141516171819202122232425

获得所有正在进行的比赛ID后,点击某一场比赛,进入文字直播页面。首先请求http://dingshi4pc.qiumibao.com/livetext/data/cache/max_sid/XXXX/0.htm页面,其中XXXX是上一步获取的id,它会返回一个数字,即max_sid。然后判断该max_sid是否大于上次获取的该值,如果大于,表示有新的直播文字,否则表示没有。
如果max_sid大于上一次的值,通过请求http://bifen4pc2.qiumibao.com/json/XXXX/YYYY.htm(其中XXXX是今天的日期,格式为2017-04-20,YYYY是第一步中获取的id),返回这场比赛的基本情况,比如比分,是第几节等,如下所示:
{    "id": "96233",    "home_team": "勇士",    "visit_team": "开拓者",    "home_score": "110",    "visit_score": "81",    "period_cn": "第4节结束",    ...}123456789

最后,就可以获取直播的文字了。请求http://dingshi4pc.qiumibao.com/livetext/data/cache/livetext/XXXX/0/lit_page_2/YYYY.htm(其中XXXX是比赛id,YYYY是max_sid),它会返回最新的直播文字,其中包括一条或多条直播文字,如下所示:
[
{        "live_id": "8769977",        "live_text": "@仙女最库阿-:库里正负值最高32我去!!!!",        "home_score": "110",        "visit_score": "81",        "pid_text": "比赛结束",        ...
},    ... # 可能有多条直播文字]1234567891011

可以看到,该请求返回的信息中没有比赛剩余时间、主队和客队等信息,所以每次获取直播文字之前,需要多一次请求,获得比赛的基本信息。
基本流程就是这样,非常简单,一共就四个GET请求,返回四串json,用requests库请求,然后解析搞定。
先定义一个Match类,表示当前正在进行的每一场比赛。
# match.pyclass Match:
def __init__(self, **kwargs):
self.id = kwargs['id']
self.home_team = kwargs['home_team']
self.visit_team = kwargs['visit_team']
self.home_score = kwargs['home_score']
self.visit_score = kwargs['visit_score']
self.period_cn = kwargs['period_cn'].replace('\n', ' ')    def __repr__(self):
return '{self.id} {self.home_team} {self.home_score} - {self.visit_score} {self.visit_team} {self.period_cn}'.format(self=self)12345678910111213

再定义一个TextLiving类,表示获取的每一条文字直播。
# text_living.pyclass TextLiving:
def __init__(self, match_info, **kwargs):
self.home_team = match_info['home_team']
self.visit_team = match_info['visit_team']
self.period_cn = match_info['period_cn']
self.live_text = kwargs['live_text']
self.home_score = kwargs['home_score']
self.visit_score = kwargs['visit_score']    def __repr__(self):
return '{self.home_team} {self.home_score} - {self.visit_score} {self.visit_team} {self.period_cn}\n{self.live_text}\n{sep}'.format(self=self, sep='*'*60)12345678910111213

接着创建zhibo8_api.py模块,用于获取相关数据。
# 当前正在进行的比赛Living_Matches_Url = 'http://bifen4m.qiumibao.com/json/list.htm'# 某一场比赛当前的max_sidMatch_Max_Sid_Url = 'http://dingshi4pc.qiumibao.com/livetext/data/cache/max_sid/%s/0.htm'# 某一场比赛最新文字直播Match_Living_Text_Url = 'http://dingshi4pc.qiumibao.com/livetext/data/cache/livetext/%s/0/lit_page_2/%d.htm'# 某一场比赛当前的基本情况Match_Info_Url = 'http://bifen4pc2.qiumibao.com/json/%s/%s.htm'def get_living_matches():
response = requests.get(Living_Matches_Url)
result = json.loads(response.text)
matches = [Match(**match) for match in result['list'] if match['type'] == 'basketball' and match['period_cn'] != '完赛']    return matchesdef get_match_max_sid(match_id):
response = requests.get(Match_Max_Sid_Url % match_id)    if response.status_code == requests.codes.ok:        return int(response.text)def get_match_living(match_id, max_sid):
# 先获取比赛的当前情况,再获取最新文字直播
match_info = get_match_info(match_id)

response = requests.get(Match_Living_Text_Url % (match_id, max_sid))

texts = []    if response.status_code == requests.codes.ok:
result = json.loads(response.text)
texts = [TextLiving(match_info, **living) for living in result]    return textsdef get_match_info(match_id):
today = datetime.now().strftime('%Y-%m-%d')
response = requests.get(Match_Info_Url % (today, match_id))
match_info = json.loads(response.text)    return match_info123456789101112131415161718192021222324252627282930313233343536373839404142

最后,在main.py模块中启动程序,开始直播!
def get_living_matches():
matches = zhibo8_api.get_living_matches()    for match in matches:
print(match)    return matchesdef get_watch_match(matches):
match_id = input('请输入比赛ID:')    for match in matches:        if match.id == match_id:            return match    else:
print('输入的ID不正确')        return Nonedef main_loop():
matches = get_living_matches()    if len(matches) == 0:
print('当前没有比赛!!!')        return

match = get_watch_match(matches)    if not match:
print('没去找到该比赛')        return

current_match_max_sid = -1
while True:
match_max_sid = zhibo8_api.get_match_max_sid(match.id)        if not match_max_sid:
print('没有直播数据')            return

if current_match_max_sid == match_max_sid:            continue

current_match_max_sid = match_max_sid
text_livings = zhibo8_api.get_match_living(match.id, current_match_max_sid)        for text in text_livings:
print(text)if __name__ == '__main__':
main_loop()

关于Python命令行的NBA文字直播小工具

6. 怎么快速学习python

对于刚入门的人,最重要的是培养Ta的学习兴趣和信心,其实python非常适合初学者入门。相比较其他不少主流编程语言,有更好的可读性,因此上手相对容易,自个也可以在【皮特收集者】里面下教程。
点击下载链接: https://pan.baidu.com/s/1YKqBGWi1cxemu_HZ0Ctb2w 提取码: ad4p

7. python能做什么项目

大家在学完python基础之后,突然迷茫起来了,这时就需要一些项目练练手,增加自己的经验,同时找到自己的不足。Python3 实现火车票查询工具(推荐学习:Python视频教程)
使用 Python3 抓取 12306 网站信息,完成一个火车票查询工具。该项目练习 Python3 基础及网络编程,以及 docopt,requests,prettytable 等库的使用。
高德API+Python解决租房问题
使用Python脚本爬取某租房网站的房源信息,利用高德的 js API 在地图上标出房源地点,找到距离工作地点1小时车程的房源!在项目实现的过程中将熟悉requests、BeautifulSoup、csv等库的简单使用。
NBA常规赛结果预测:利用Python进行比赛数据分析
利用NBA在2015~2019年的比赛统计数据进行回归模型建立,最终在今年2016~2017的常规赛中预测每场比赛的输赢情况。
Python代码实现2048
学习 Python 基本知识,状态机的概念,以及编写 python 游戏的步骤。为 Python 的进阶课程,需要用户具有 Python 的语法基础。
Python实现从excel读取数据并绘制成精美图像
这个世界从古至今一直是一个看颜值的世界。对于我们作报告,写文章时使用的图片,也是一样的。一图胜千言,一张制作精美的图片,不仅能展示大量的信息,更能体现绘图者的水平,审美,与态度。使用python从excel读取数据,并使用matplotpb绘制成二维图像。这一过程中,将通过一系列操作来美化图像
这些项目可以说是有难的也有容易的,但是只要能独立完成一定会有很大的收获。
更多Python相关技术文章,请访问Python教程栏目进行学习!以上就是小编分享的关于python能做什么项目的详细内容希望对大家有所帮助,更多有关python教程请关注环球青藤其它相关文章!

python能做什么项目

8. 如何快速学好Python,然后找到工作,或者不用工作就赚钱

零基础情况下,想学一门语言。其实python非常适合初学者入门。相比较其他不少主流编程语言,有更好的可读性,因此上手相对容易。那么如何快速掌握python?
设定目标:做 Python 开发除了熟悉语言本身之外,还需要掌握很多相关联的技能,好比打NBA,你不光要学如何投篮,还要练习力量、技战术等一整套东西。所以,一个普通Python Web开发工程师需要掌握的技能包括至少一个Web框架,比如:Django、Flask、Tornado,做业务系统必须熟知一种数据库,还需要对Linux系统的基本操作和常用命令有所了解,因为以后你写到程序基本上都会运行在Linux平台上。
开发工具:工欲善其事必先利其器,Python IDE层出不穷,推荐Pycharm 和Sublime两个工具都是免费的,而且它们的学习成本非常低,网上找一篇教程看了基本就能上手,Vim、Emacs这样的远古神器还是放以后再去了解吧。
Python3:新手开始总纠结学 Python2 还是 Python3,这种纠结完全就是给自己徒增烦恼,因为它们是同一种语言,只有少部分地方语法不兼容,尽管目前大部分公司还在用Python2,但是Python3逐渐成为主流已是不争事实,毕竟后者性能方面更占有优势。
学习框架:对于刚入门的人,最重要的是培养Ta的学习兴趣和信心。有的会担心自己的基础知识都那么薄弱,如何能学好框架呢?其实这个担心倒是不必,大多数大型的框架都把功能封装得很完整,定义了一套在自己的框架下做事的“规则”,学习框架更多的是学习这些“规则”,入门倒不需要很深的理论基础。
最新文章
热门文章
推荐阅读