前言
勒布朗-詹姆斯终于登顶了NBA历史总得分王,他花了20个赛季得了38390分,超越了天勾——贾巴尔老爷子,然后,我经常逛的论坛,就出现了很多讨论帖,讨论NBA球星们的得分能力孰强孰弱,又是一堆关公战秦琼的问题,不过我觉得挺有趣的,大家都在讲述着自己的道理,拿出自己的数据,我想了下,不如做一个得分能力的对比图,决出冠军。
准备
指标确定
首先我们确定得分能力包括哪些指标,我这里选取了职业生涯场均得分,职业生涯场均投篮命中率,职业生涯场均三分命中率,职业生涯场均罚球命中率,总决赛场均得分,总决赛场均命中率六大指标;这些指标我们通过数据网站可以获取,这里不做赘述。我们获得数据之后,会按照自己的主观感受赋予5-10分不一样的档次,5分最低,10分最高。
球星名单
关于球星,我决定选择乔丹(Goat),詹姆斯(历史总得分王),杜兰特(现役最强得分手),库里(历史最强三分手),科比(只有情怀),奥尼尔(最强中锋大鲨鱼)。
实践第一步:导包
首先还是导入各种功能模块。opts(options)是 pyecharts 中设置图片详细格式的模块,Radar 是绘制雷达图的类名,因为得分能力包含多个数值,所以我们决定使用雷达图,JsCode 是 pyecharts 中执行 JavaScript 代码的一个类。
from pyecharts import options as optsfrom pyecharts.charts import Radarfrom pyecharts.commons.utils import JsCode第二步:数据
我们将获取到的数据准备好,数值内容并不多,主要代码如下所示:
Jordan = [{"value": [10, 8, 7, 7, 10, 8], "name": "乔丹"}]James= [{"value": [8, 8, 6, 6, 9, 8], "name": "詹姆斯"}]Durant = [{"value": [8, 9, 7, 9, 9, 9], "name": "杜兰特"}]Kobe = [{"value": [7, 7, 7, 8, 8, 6], "name": "科比"}]Curry = [{"value": [6, 7, 9, 9, 8, 7], "name": "库里"}]O'Neal = [{"value": [8, 9, 6, 5, 8, 9], "name": "奥尼尔"}]
这6个人的数值都用他们各自的英文名作变量名,每个变量是一个 list,里面包含一个 dict,dict 中 value 就代表了每个人的数据值,其同样是一个 list,包含上述6个数据的评级。后面的 name 则是每个人的中文名,实际上 name 在整个代码中并没有什么作用,只方便显示。
接下来是一个名为 myschema 的变量,是一个 list,里面包含6个 dict,每个 dict 包含3个 key,这6个 dict 主要用来设置雷达图的坐标轴,后面会详细说明。
myschema = [ {"name": '生涯场均得分', "max": 10, "min": 0}, {"name": '生涯命中率', "max": 10, "min": 0}, {"name": '生涯三分命中率', "max": 10, "min": 0}, {"name": '生涯罚球命中率', "max": 10, "min": 0}, {"name": '总决赛场均得分', "max": 10, "min": 0}, {"name": '总决赛场均命中率', "max": 10, "min": 0}]
然后就开始我们的主要绘图部分。首先生成一个 Radar 类的实例 r,在这里我们设置了图表的背景图,用到的是 opts.InitOpts 中的 bg_color 属性,其值为
{"type": "pattern", "image": JsCode("img"), "repeat": "no-repeat"}
“type”: “pattern” 表示我们用图片作背景,“image”: JsCode(“img”) 表示我们用 JavaScript 代码来设置这个背景图,“repeat”: “no-repeat” 表示图片不重复。而 add_js_funcs 方法就是执行相关的 JavaScript 代码,这里的 JavaScript 代码也很简单,就设置一个名为 img 的变量,指定一下路径。在这里我们用的图片是本地图片,名为 a5.png,我们要把这个图片放在自己的当前工作目录下,不知道当前工作目录的可以执行下面的代码查看:
import osroot = os.getcwd()print(root)
接下来是一个长长的 chaining methods(方法链),虽然内容多了点,但不少都是重复性代码,所以并不难理解,这里介绍一下里面的主要部分。
add_schema 方法就是设置我们的雷达图
参数 schema 设置为 myschema,就是前面我们提到过的那个 list,里面有6个 dict,每个 dict 就是一个径向轴,dict 的 name 就是径向轴的标签,min 和 max 设置径向轴的最小和最大值。
shape 是雷达图的形状,这里设置为圆形,也可以设置为多边形 polygon。
center=[“50%”, “50%”] 表示雷达图的中心在当前绘图区域的中点位置,即当前绘图区域的高度和宽度的50%位置
radius=“80%” 表示雷达图的半径为当前绘图区域的大小的80%,即这个区域的宽度和高度中的较小者的80%。
angleaxis_opts 参数是用来设置角度坐标轴,其2个参数 axistick_opts、axislabel_opts 全都设为不显示,他们的分别代表了角度轴的刻度、标签,大家可以试试把这些参数设置为 True 的结果。
radiusaxis_opts,其用来设置径向轴,其最小值为0,最大值为10,间隔为1,其包含的 splitarea_opts 参数用来设置间隔区域,也就是图中灰色的部分。
polar_opts 参数则是设置这个雷达图的相关属性,这里我们全部采用默认设置。
add_schema 的另外两个参数 splitline_opt 和 textstyle_opts 则分别用来设置径向轴的分割线和图中文字,这里我们把分割线设为不显示,文章颜色设为黑色。
r 的 add 方法则用来向图中添加数据,每个 add 方法会添加一个数据,因为我们一共有6个球星,所以用了6次 add 方法。add 方法中 series_name 用来设置数据序列的名称,这也就是图中上面一排圆圈后面的文字,data 是所要输入的数据,areastyle_opts 用来设置每个数据序列图形区域的属性,这里把每个图形区域的不透明度设为0.1,linestyle_opts 设置图形连线的属性,这里把线宽设为1。set_global_opt 则用来设置整个图表的属性,这里我们设置图的标题为"NBA球星得分能力对比"。最后我们用 render 生成一个网页。
( r.add_schema( schema=myschema, shape="circle", # 图片形状 center=["50%", "50%"], # 图片中心位置 radius="75%", # 图片半径大小 angleaxis_opts=opts.AngleAxisOpts( axistick_opts=opts.AxisTickOpts(is_show=False), axislabel_opts=opts.LabelOpts(is_show=False), splitline_opts=opts.SplitLineOpts(is_show=False), ), radiusaxis_opts=opts.RadiusAxisOpts( min_=0, max_=7, interval=1, splitarea_opts=opts.SplitAreaOpts( is_show=True, areastyle_opts=opts.AreaStyleOpts(opacity=1) ), splitline_opts=opts.series_options.SplitLineOpts(is_show=True, linestyle_opts={'color': 'grey', 'opacity': 0.8}) ), polar_opts=opts.PolarOpts(), splitline_opt=opts.SplitLineOpts(is_show=False), textstyle_opts=opts.TextStyleOpts(color="black"), ) .add( series_name="乔丹", data=Jordan, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .add( series_name="詹姆斯", data=James, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .add( series_name="杜兰特", data=Durant, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .add( series_name="科比", data=Kobe, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .add( series_name="库里", data=Curry, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .add( series_name="奥尼尔", data=ONeal, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .set_global_opts( title_opts=opts.TitleOpts(title="NBA球星得分能力对比"), legend_opts=opts.LegendOpts() ) .render('ht1.html') # 生成网页)
生成的图如下所示:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=764fd2e0c318367aad897fd51e728b68/efa10cf431adcbefb01761cfe9af2edda2cc9fdf.jpg?tbpicau=2025-02-22-05_818f37c9e4a321dc9334bb1ccf0cc780)
在我们绘制的图中,如果想只查看某个球星的数值,我们则可以单击其他球星的序列名称,就是图中上面那一排小圆圈和后面的文字,每次单击就会使这个球星的名称变成灰色,其代表的图形也会在图中消失,再次单击则会复原,这样就会只留下我们需要的球星的数值。如下图所示,我们只留下杜兰特的图:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=3f07ace1737adab43dd01b4bbbd5b36b/33f731adcbef76098c2886566bdda3cc7dd99edf.jpg?tbpicau=2025-02-22-05_22c8f953c92fc7442fa39e5c02454be3)
总结
我们NBA球星得分能力对比图绘制就完成了,请大家不要当真,我只是展示了一下pyecharts的绘图功能,这是我们本篇文章的重点,哈哈。
大家还想学习哪些Python知识,可以给我留言哦!
勒布朗-詹姆斯终于登顶了NBA历史总得分王,他花了20个赛季得了38390分,超越了天勾——贾巴尔老爷子,然后,我经常逛的论坛,就出现了很多讨论帖,讨论NBA球星们的得分能力孰强孰弱,又是一堆关公战秦琼的问题,不过我觉得挺有趣的,大家都在讲述着自己的道理,拿出自己的数据,我想了下,不如做一个得分能力的对比图,决出冠军。
准备
指标确定
首先我们确定得分能力包括哪些指标,我这里选取了职业生涯场均得分,职业生涯场均投篮命中率,职业生涯场均三分命中率,职业生涯场均罚球命中率,总决赛场均得分,总决赛场均命中率六大指标;这些指标我们通过数据网站可以获取,这里不做赘述。我们获得数据之后,会按照自己的主观感受赋予5-10分不一样的档次,5分最低,10分最高。
球星名单
关于球星,我决定选择乔丹(Goat),詹姆斯(历史总得分王),杜兰特(现役最强得分手),库里(历史最强三分手),科比(只有情怀),奥尼尔(最强中锋大鲨鱼)。
实践第一步:导包
首先还是导入各种功能模块。opts(options)是 pyecharts 中设置图片详细格式的模块,Radar 是绘制雷达图的类名,因为得分能力包含多个数值,所以我们决定使用雷达图,JsCode 是 pyecharts 中执行 JavaScript 代码的一个类。
from pyecharts import options as optsfrom pyecharts.charts import Radarfrom pyecharts.commons.utils import JsCode第二步:数据
我们将获取到的数据准备好,数值内容并不多,主要代码如下所示:
Jordan = [{"value": [10, 8, 7, 7, 10, 8], "name": "乔丹"}]James= [{"value": [8, 8, 6, 6, 9, 8], "name": "詹姆斯"}]Durant = [{"value": [8, 9, 7, 9, 9, 9], "name": "杜兰特"}]Kobe = [{"value": [7, 7, 7, 8, 8, 6], "name": "科比"}]Curry = [{"value": [6, 7, 9, 9, 8, 7], "name": "库里"}]O'Neal = [{"value": [8, 9, 6, 5, 8, 9], "name": "奥尼尔"}]
这6个人的数值都用他们各自的英文名作变量名,每个变量是一个 list,里面包含一个 dict,dict 中 value 就代表了每个人的数据值,其同样是一个 list,包含上述6个数据的评级。后面的 name 则是每个人的中文名,实际上 name 在整个代码中并没有什么作用,只方便显示。
接下来是一个名为 myschema 的变量,是一个 list,里面包含6个 dict,每个 dict 包含3个 key,这6个 dict 主要用来设置雷达图的坐标轴,后面会详细说明。
myschema = [ {"name": '生涯场均得分', "max": 10, "min": 0}, {"name": '生涯命中率', "max": 10, "min": 0}, {"name": '生涯三分命中率', "max": 10, "min": 0}, {"name": '生涯罚球命中率', "max": 10, "min": 0}, {"name": '总决赛场均得分', "max": 10, "min": 0}, {"name": '总决赛场均命中率', "max": 10, "min": 0}]
然后就开始我们的主要绘图部分。首先生成一个 Radar 类的实例 r,在这里我们设置了图表的背景图,用到的是 opts.InitOpts 中的 bg_color 属性,其值为
{"type": "pattern", "image": JsCode("img"), "repeat": "no-repeat"}
“type”: “pattern” 表示我们用图片作背景,“image”: JsCode(“img”) 表示我们用 JavaScript 代码来设置这个背景图,“repeat”: “no-repeat” 表示图片不重复。而 add_js_funcs 方法就是执行相关的 JavaScript 代码,这里的 JavaScript 代码也很简单,就设置一个名为 img 的变量,指定一下路径。在这里我们用的图片是本地图片,名为 a5.png,我们要把这个图片放在自己的当前工作目录下,不知道当前工作目录的可以执行下面的代码查看:
import osroot = os.getcwd()print(root)
接下来是一个长长的 chaining methods(方法链),虽然内容多了点,但不少都是重复性代码,所以并不难理解,这里介绍一下里面的主要部分。
add_schema 方法就是设置我们的雷达图
参数 schema 设置为 myschema,就是前面我们提到过的那个 list,里面有6个 dict,每个 dict 就是一个径向轴,dict 的 name 就是径向轴的标签,min 和 max 设置径向轴的最小和最大值。
shape 是雷达图的形状,这里设置为圆形,也可以设置为多边形 polygon。
center=[“50%”, “50%”] 表示雷达图的中心在当前绘图区域的中点位置,即当前绘图区域的高度和宽度的50%位置
radius=“80%” 表示雷达图的半径为当前绘图区域的大小的80%,即这个区域的宽度和高度中的较小者的80%。
angleaxis_opts 参数是用来设置角度坐标轴,其2个参数 axistick_opts、axislabel_opts 全都设为不显示,他们的分别代表了角度轴的刻度、标签,大家可以试试把这些参数设置为 True 的结果。
radiusaxis_opts,其用来设置径向轴,其最小值为0,最大值为10,间隔为1,其包含的 splitarea_opts 参数用来设置间隔区域,也就是图中灰色的部分。
polar_opts 参数则是设置这个雷达图的相关属性,这里我们全部采用默认设置。
add_schema 的另外两个参数 splitline_opt 和 textstyle_opts 则分别用来设置径向轴的分割线和图中文字,这里我们把分割线设为不显示,文章颜色设为黑色。
r 的 add 方法则用来向图中添加数据,每个 add 方法会添加一个数据,因为我们一共有6个球星,所以用了6次 add 方法。add 方法中 series_name 用来设置数据序列的名称,这也就是图中上面一排圆圈后面的文字,data 是所要输入的数据,areastyle_opts 用来设置每个数据序列图形区域的属性,这里把每个图形区域的不透明度设为0.1,linestyle_opts 设置图形连线的属性,这里把线宽设为1。set_global_opt 则用来设置整个图表的属性,这里我们设置图的标题为"NBA球星得分能力对比"。最后我们用 render 生成一个网页。
( r.add_schema( schema=myschema, shape="circle", # 图片形状 center=["50%", "50%"], # 图片中心位置 radius="75%", # 图片半径大小 angleaxis_opts=opts.AngleAxisOpts( axistick_opts=opts.AxisTickOpts(is_show=False), axislabel_opts=opts.LabelOpts(is_show=False), splitline_opts=opts.SplitLineOpts(is_show=False), ), radiusaxis_opts=opts.RadiusAxisOpts( min_=0, max_=7, interval=1, splitarea_opts=opts.SplitAreaOpts( is_show=True, areastyle_opts=opts.AreaStyleOpts(opacity=1) ), splitline_opts=opts.series_options.SplitLineOpts(is_show=True, linestyle_opts={'color': 'grey', 'opacity': 0.8}) ), polar_opts=opts.PolarOpts(), splitline_opt=opts.SplitLineOpts(is_show=False), textstyle_opts=opts.TextStyleOpts(color="black"), ) .add( series_name="乔丹", data=Jordan, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .add( series_name="詹姆斯", data=James, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .add( series_name="杜兰特", data=Durant, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .add( series_name="科比", data=Kobe, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .add( series_name="库里", data=Curry, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .add( series_name="奥尼尔", data=ONeal, areastyle_opts=opts.AreaStyleOpts(opacity=0.1), linestyle_opts=opts.LineStyleOpts(width=1), ) .set_global_opts( title_opts=opts.TitleOpts(title="NBA球星得分能力对比"), legend_opts=opts.LegendOpts() ) .render('ht1.html') # 生成网页)
生成的图如下所示:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=764fd2e0c318367aad897fd51e728b68/efa10cf431adcbefb01761cfe9af2edda2cc9fdf.jpg?tbpicau=2025-02-22-05_818f37c9e4a321dc9334bb1ccf0cc780)
在我们绘制的图中,如果想只查看某个球星的数值,我们则可以单击其他球星的序列名称,就是图中上面那一排小圆圈和后面的文字,每次单击就会使这个球星的名称变成灰色,其代表的图形也会在图中消失,再次单击则会复原,这样就会只留下我们需要的球星的数值。如下图所示,我们只留下杜兰特的图:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=3f07ace1737adab43dd01b4bbbd5b36b/33f731adcbef76098c2886566bdda3cc7dd99edf.jpg?tbpicau=2025-02-22-05_22c8f953c92fc7442fa39e5c02454be3)
总结
我们NBA球星得分能力对比图绘制就完成了,请大家不要当真,我只是展示了一下pyecharts的绘图功能,这是我们本篇文章的重点,哈哈。
大家还想学习哪些Python知识,可以给我留言哦!