尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

赛后数据雷达图实战:用Python与ECharts绘制NIP vs WBG多维对比

赛后数据雷达图实战:用Python与ECharts绘制NIP vs WBG多维对比 LPL 的 BO3 一结束除了比分之外讨论度最高的往往不是某一次团战操作而是一张图赛后数据雷达图。NIP 2-1 WBG 这场比赛赛后在各个平台的复盘帖里雷达图几乎是标配。很多人看雷达图只看两个点谁的圈大谁就赢。这个判断在多数情况下成立但放到比赛复盘里它忽略了雷达图真正有用的地方。雷达图不是用来证明结果的而是用来解释过程的。同样是 2-1 赢下比赛是靠前期滚雪球、中期控图还是后期团战翻盘在雷达图上的形状完全不同。这篇文章不打算只贴一张图而是把赛后数据雷达图的完整链路讲清楚从指标怎么选、数据怎么归一化到用 Python 和 ECharts 怎么画再到怎么看图、怎么避坑。读完你可以自己做一张 NIP 对 WBG 的赛后数据雷达图也可以把这套方法迁移到任何电竞赛事或任意多维数据分析场景。1. 这篇文章真正要解决的问题赛后数据分析听起来很专业实际上面临一个非常朴素的矛盾比赛产生的数据维度太多了观众根本看不过来。一场 LPL 比赛结束官方后台会输出几十项统计击杀、死亡、助攻、补刀、分均经济、分均伤害、伤害占比、承伤占比、视野得分、小龙、大龙、镀层、推塔数……如果把这一堆数字直接丢给读者复盘文章会变成一张 Excel 表格阅读体验很差。雷达图在这个场景下承担的是信息压缩任务。它把多个指标放在同一个坐标系里每个指标对应一根轴各个轴上的取值连成一个多边形。读者不需要精确记忆数字只需要看形状就能快速形成判断这个队的经济获取能力是否突出那个队的视野控制是不是短板两边综合下来谁更均衡。这篇文章主要解决四个问题第一理解雷达图的基本原理和适用边界知道它适合什么、不适合什么。第二拆解赛后复盘常用的数据指标弄清楚哪些指标真正能说明问题。第三用 Python 和 ECharts 从零实现一张双队对比雷达图代码可以直接复制运行。第四掌握数据归一化、指标方向处理、图表解读和常见坑。如果你是做数据可视化开发的读者这篇文章能帮你把电竞题材快速落地成一个可复用的模板如果你只是对赛后数据感兴趣的玩家读完也能更准确地去读官方和社区制作的雷达图而不是只看“面积大小”。2. 雷达图的基础概念与适用场景雷达图在英文里叫 Radar Chart也常叫 Spider Chart 或 Spider Web Chart中文又叫蛛网图、极坐标图。它的本质是把多维度数据映射到从同一个圆心向外延伸的坐标轴上每个维度的数值在对应轴上取值再把相邻轴上的点用线段连起来形成一个闭合多边形。这个设计有一个很直观的特点指标越多轴越多多边形越接近圆形某个指标数值越高对应顶点越远离圆心图形在该方向就越“外凸”。雷达图最适合的场景是同类对象的横向对比。比如两支队伍、两名选手、三套阵容方案用同一套指标、同一个量纲标准去比较形状差异就非常明显。它也很适合做综合评价因为图形围起来的面积可以粗略代表“综合水平”面积越大整体能力越强。但雷达图并不适合所有场景。第一它不适合精确数值比较。人眼对图形的面积和边长判断是模糊的想精确比较某个指标的大小用柱状图或表格更合适。第二它不适合维度太多的数据。一般建议控制在 5 到 8 个指标超过 10 个轴之后图形会变得非常拥挤相邻轴之间的角度太小读起来很费劲。第三它不适合时间序列分析展示趋势用折线图更直观。如果要用一个类比来理解雷达图的价值它更像篮球比赛里的“球员六边形能力图”。观众不会通过它精确计算得分而是快速看出一个球员是偏内线、偏投射还是全面均衡。赛后数据雷达图的逻辑完全一致它解决的是“快速定位强弱项”的问题而不是“精确回答谁更强”的问题。图表类型优势劣势适合场景雷达图多维对比直观强弱项一目了然精确数值难读维度过多会混乱队伍/选手综合对比柱状图单维精确对比维度多时占用空间大单项指标精确排名折线图展示变化趋势不适合多维横向对比联赛各周数据变化散点图展示两维相关性只能承载少量维度伤害与经济的相关性3. 赛后数据雷达图常用指标拆解做一张合格的赛后数据雷达图第一步不是写代码而是选指标。指标选错图再漂亮也没有说服力。在 LOL 的赛后分析里团队维度常用的指标有这几种指标通俗含义代表能力使用注意分均经济每分钟获得的经济资源获取与滚雪球能力线上补刀、防御塔镀层、野区资源都会影响分均伤害每分钟打出的有效伤害输出效率比赛时长过短时数值可能偏低伤害转化率总伤害 / 总经济经济使用效率越高说明吃经济越能打输出击杀参与率参与击杀数 / 队伍总击杀团队联动与支援频率单核体系下选手间差异较大视野得分视野布置与排眼的综合评分地图控制与信息战水平辅助和打野通常贡献最大控龙率成功拿到的小龙比例中立资源掌控能力版本和阵容强度会影响结果控大龙率成功拿到的大龙比例后期决策能力样本量小单场波动大场均推塔数每场比赛摧毁防御塔数量推进效率与是否速推局强相关选手维度则更常使用这些指标伤害占比、承伤占比、经济占比、对位经济差、分均补刀、KDA。其中 KDA 是最容易误导人的指标因为它是 (击杀 助攻) / 死亡助攻多会明显抬高数值却不能完全代表个人输出能力。做雷达图时指标数量建议控制在 7 个以内。太多会让图形失去“一眼看懂”的优势。另外要注意指标方向雷达图默认是“数值越大越好”的朝外延伸逻辑如果某个指标越小越好比如场均死亡数、场均被推塔数需要先做反向处理再放进图中。4. 数据准备与归一化方法数据准备有两个容易出错的地方来源和量纲。先说来源。制作赛后数据雷达图最稳妥的数据来源是官方赛事数据、直播平台赛后统计、官方数据站或经过授权的内容平台。如果做个人研究也可以使用公开赛事录像配合人工标注的方式整理数据。这里要特别提醒数据采集必须使用合法公开渠道遵守平台规则不要破解接口、不要绕过访问限制。做技术演示没问题但不能把别人的数据接口或者网页结构当作可随意爬取的资源。再说量纲。原始数据里分均经济可能是 2000 左右视野得分是 100 左右击杀数是个位数小龙数是 0 到 4。这些指标如果直接丢进雷达图数值大的轴会把数值小的轴完全压扁击杀数连贴地都看不见图形直接失去意义。所以必须先做归一化处理。最常用的归一化方法是极差归一化也叫 Min-Max 归一化把原始值按比例映射到 0 到 100 的区间def normalize_by_minmax(values, lower_is_betterFalse): 将一组数值归一化到 0-100 区间。 lower_is_betterTrue 表示该指标越小越好需要取反向。 min_v min(values) max_v max(values) if max_v min_v: # 所有值相同统一给 50避免除零 return [50.0 for _ in values] if lower_is_better: return [round((max_v - v) / (max_v - min_v) * 100, 2) for v in values] return [round((v - min_v) / (max_v - min_v) * 100, 2) for v in values]这个函数有一个细节值得注意当最大值等于最小值时直接返回 50。这个处理在常规比赛数据里不常见但当你比较的数据集只有一个样本或者某个指标两侧完全相等时如果不做保护就会出现除零错误。归一化完成之后所有指标都在同一个量纲下雷达图各轴才有可比性。实际项目中我建议把原始数据和归一化后的数据都保存下来方便追溯和复核。因为你可能在文章里只展示归一化结果但如果读者质疑某个数据你需要能快速找到原始来源。5. 环境准备与开发工具制作雷达图有两种常见技术路线。第一种是 Python 桌面端绘图适合生成静态图片、批量处理数据、做论文或博客配图。我推荐使用 matplotlib 作为主力绘图库搭配 numpy 做数值计算pandas 做数据整理。安装命令如下pip install matplotlib numpy pandasPython 版本建议 3.8 及以上。如果你只需要画图不涉及复杂数据处理只安装 matplotlib 和 numpy 就足够了。第二种是 ECharts 前端交互方案适合网页展示、数据看板、运营页面。ECharts 是百度开源的可视化库雷达图配置简单支持鼠标悬浮查看具体数值、动画过度和自适应布局。浏览器端开发直接引用 CDN 即可不需要构建工具。我用的是两种结合的方式数据整理和归一化用 Python 完成静态成图用 matplotlib如果要做网页看板就直接把归一化后的 JSON 数据交给 ECharts 渲染。关于中文字体这里提前说一个比较常见的坑。matplotlib 默认字体可能不支持中文绘图时如果指标名称包含中文会出现方块乱码。解决方案是在绘图脚本开头设置中文字体import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, PingFang SC] plt.rcParams[axes.unicode_minus] FalseWindows 系统一般有 SimHei 或 Microsoft YaHeimacOS 一般有 PingFang SC。Linux 服务器可能需要额外安装中文字体否则即使设置了字体名称也可能找不到。6. 完整示例绘制 NIP vs WBG 赛后数据雷达图下面进入核心实操环节。以 NIP 2-1 WBG 这场 BO3 赛后的团队数据对比为例我给出完整的实现代码。6.1 定义指标与演示数据首先要说明下面的数据是演示用途的模拟数值不是官方比赛真实统计。真实比赛数据请以 LPL 官方赛事数据平台为准。我用模拟数据的原因是为了让代码运行结果稳定可复现同时不误导读者以为这是真实赛果的精确统计。# 定义 7 个雷达图指标 labels [ 分均经济, 分均伤害, 击杀参与率, 视野得分, 场均推塔, 控龙率, 控大龙率, ] # 演示数据已归一化到 0-100 区间 nip [82, 75, 68, 80, 72, 70, 66] wbg [70, 78, 74, 65, 60, 62, 55]这里nip和wbg是两个数组数组顺序必须和labels完全一致否则画出来的图形会被整体错位这是雷达图最容易出现却最难发现的问题。6.2 Matplotlib 绘制双队雷达图下面是完整的 matplotlib 绘图脚本可以直接保存为radar_chart.py运行# 文件路径radar_chart.py import numpy as np import matplotlib.pyplot as plt # 设置中文字体避免中文乱码 plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, PingFang SC] plt.rcParams[axes.unicode_minus] False # 指标与演示数据模拟数据非官方统计 labels [分均经济, 分均伤害, 击杀参与率, 视野得分, 场均推塔, 控龙率, 控大龙率] nip [82, 75, 68, 80, 72, 70, 66] wbg [70, 78, 74, 65, 60, 62, 55] # 计算每个指标在坐标系中的角度并闭合首尾 angles np.linspace(0, 2 * np.pi, len(labels), endpointFalse).tolist() angles angles[:1] nip_values nip nip[:1] wbg_values wbg wbg[:1] # 创建极坐标子图 fig, ax plt.subplots(figsize(8, 8), subplot_kwdict(polarTrue)) # 绘制 NIP ax.plot(angles, nip_values, linewidth2, labelNIP, color#ff4d4f) ax.fill(angles, nip_values, alpha0.15, color#ff4d4f) # 绘制 WBG ax.plot(angles, wbg_values, linewidth2, labelWBG, color#1677ff) ax.fill(angles, wbg_values, alpha0.15, color#1677ff) # 设置指标标签和坐标范围 ax.set_xticks(angles[:-1]) ax.set_xticklabels(labels, fontsize11) ax.set_ylim(0, 100) plt.title(NIP vs WBG 赛后数据雷达图演示数据, fontsize15, pad30) plt.legend(locupper right, bbox_to_anchor(1.25, 1.05)) plt.tight_layout() plt.savefig(nip_vs_wbg_radar.png, dpi150) plt.show()这段代码的关键点有几个第一np.linspace(0, 2 * np.pi, len(labels), endpointFalse)把圆周平均分成 7 份得到 7 个角度每个角度对应一个指标。endpointFalse很重要它保证不会和后面手动追加的第一个角度重合。第二angles angles[:1]和nip nip[:1]是为了让多边形首尾闭合。如果不做这一步雷达图会缺一条边看起来像一根断开的折线。第三ax.set_ylim(0, 100)固定坐标范围。因为归一化后的数值都在 0 到 100 之间固定范围可以避免 matplotlib 自动缩放导致视觉失真。第四颜色和透明度的搭配。我先用实线画出轮廓再用alpha0.15做半透明填充这样两个队的多边形即使重叠也能分清边界。6.3 从原始数据到归一化数据的完整流程如果你手里拿到的不是 0 到 100 的归一化数值而是原始统计就需要先处理。下面是一个完整的示例import pandas as pd # 模拟原始数据非官方统计 raw_data pd.DataFrame({ team: [NIP, WBG], gpm: [2015, 1920], # 分均经济 dpm: [3120, 3420], # 分均伤害 kp: [0.68, 0.74], # 击杀参与率 vision: [126, 108], # 视野得分 towers: [7, 5], # 场均推塔 dragons: [3, 2], # 小龙数 barons: [1, 0], # 大龙数 }) # 对团队平均值做归一化 norm_data raw_data.copy() for col in [gpm, dpm, kp, vision, towers, dragons, barons]: lo raw_data[col].min() hi raw_data[col].max() if hi lo: norm_data[col] (raw_data[col] - lo) / (hi - lo) * 100 else: norm_data[col] 50.0 print(norm_data.round(2))这段代码展示了两个队伍之间存在一个有趣的问题如果某项指标的样本量太少比如大龙只有 NIP 拿到 1 条、WBG 拿到 0 条那么归一化后 NIP 是 100WBG 是 0视觉差距会被拉得很大。所以在做雷达图时必须注意归一化会放大“相对差异”样本量小的时候结果可能失真。这也是为什么赛后雷达图通常要和实际比赛过程结合看不能只看形状。6.4 ECharts 交互式雷达图如果要发布到网页或者想让读者用鼠标悬浮查看具体数值ECharts 是更好的选择。创建一个 HTML 文件!-- 文件路径radar_demo.html -- !DOCTYPE html html langzh-CN head meta charsetUTF-8 / titleNIP vs WBG 赛后数据雷达图/title script srchttps://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js/script /head body stylemargin:0 div idradar stylewidth:100%;height:600px;/div script const chart echarts.init(document.getElementById(radar)); const option { title: { text: NIP vs WBG 赛后数据雷达图演示数据 }, tooltip: {}, radar: { indicator: [ { name: 分均经济, max: 100 }, { name: 分均伤害, max: 100 }, { name: 击杀参与率, max: 100 }, { name: 视野得分, max: 100 }, { name: 场均推塔, max: 100 }, { name: 控龙率, max: 100 }, { name: 控大龙率, max: 100 } ], radius: 65%, splitArea: { areaStyle: { color: [rgba(255,255,255,0.02), rgba(255,255,255,0.04)] } } }, series: [ { type: radar, data: [ { value: [82, 75, 68, 80, 72, 70, 66], name: NIP }, { value: [70, 78, 74, 65, 60, 62, 55], name: WBG } ] } ] }; chart.setOption(option); /script /body /html这段代码的核心配置都在radar.indicator和series.data里。indicator定义了每个轴的名称和最大值series.data传入两队归一化后的数值顺序要和indicator保持一致。直接双击 HTML 文件即可在浏览器中查看效果。7. 运行结果与效果验证运行前面的 matplotlib 脚本执行命令python radar_chart.py如果一切正常当前目录会生成nip_vs_wbg_radar.png同时弹出一个 matplotlib 窗口。图中应该包含以下内容第一7 根从圆心向外辐射的轴线每根轴上的刻度都是从 0 到 100。第二红色线条代表 NIP 的多边形蓝色线条代表 WBG 的多边形两个多边形都有半透明填充。第三右上角的图例标注了两支队伍。从演示数据来看NIP 在分均经济、视野得分、场均推塔和控龙率上更靠外圈说明这套模拟数据呈现的是一支偏控制和资源滚雪球的队伍WBG 在分均伤害和击杀参与率上反超说明中后期输出能力不低但中立资源控制偏弱。再看比赛结果 NIP 2-1 获胜这样的雷达图形态和比分是自洽的。判断图表是否成功有几个标准可以从代码层面检查第一个标准是多边形是否闭合。如果图形看起来像是一条断开的线多半是忘记把第一个数值追加到数组末尾。第二个标准是中文标签是否正常显示。如果出现方块检查字体设置并把系统中不存在的字体名称删掉。第三个标准是两个队的数值是否落在 0 到 100 之间。如果某个点跑到图表外面说明归一化没有生效或者set_ylim范围设置不对。如果运行时报错第一步先看错误信息里是否有“No module named”字样这是依赖缺失第二步看是否有中文字体相关警告这是字体问题第三步看数值类型确保传入 matplotlib 的是一维数值列表或 numpy 数组而不是字符串。8. 常见问题与排查思路下面是雷达图绘制和使用过程中最常遇到的问题我整理成了一张排查表问题现象可能原因排查方式解决方案中文标签显示为方块系统缺少中文字体或字体名称配置错误打印当前可用字体检查系统是否安装该字体更换为系统中存在的字体Linux 可安装 fonts-wqy-microhei雷达图没有闭合数值数组没有首尾拼接检查angles和数据列表是否都追加了第一个元素使用values values[:1]闭合某个队伍的图形被完全覆盖两组数据重叠度高填充透明度太低观察图例和线条颜色提高透明度对比或只画线条不填充图形严重偏向一侧某个指标数值异常大未归一化检查该轴刻度范围统一做 Min-Max 归一化刻度标签重叠指标数量过多或图片尺寸过小调整图片尺寸观察标签间距减少指标或增大figsize数值范围显示异常坐标范围被 matplotlib 自动缩放检查是否调用ax.set_ylim固定为 0 到 100ECharts 图表不显示容器没有高度或脚本加载失败打开浏览器开发者工具查看 Console给容器设置固定高度检查 CDN 是否可访问运行报错 No module named依赖未安装在终端执行pip list查看执行pip install matplotlib numpy pandas这里最容易被忽略的是 ECharts 容器高度问题。很多人在 HTML 里给div设置了宽度却忘记设置高度导致图表区域高度为 0页面一片空白。这个问题的排查耗时并不短建议在写 demo 时直接给容器写死height:600px。9. 最佳实践与工程建议做了多次雷达图之后我总结了几条值得长期坚持的实践规范。第一个建议是指标数量控制在 5 到 8 个。超过 8 个轴人眼很难快速判断形状差异少于 4 个雷达图的形状优势又发挥不出来。在赛后数据分析里我通常选 5 到 7 个团队级指标保持“一眼看出强弱项”的效果。第二个建议是对同一张雷达图使用同一套指标和统一口径。如果一张图里 NIP 用的是分均经济WBG 用的是总经济那这个图就失去了比较意义。对比前必须先确认双方数据来源一致、统计口径一致、采集时间一致。第三个建议是保留原始数据痕迹。归一化后的数值只是中间产物真实的比赛统计才是可验证的事实。在博客或报告中最好同时列出原始数据表格或者提供数据来源链接方便读者复核。第四个建议是解读雷达图时先看形状再看面积最后回到比赛过程验证。面积大的队伍综合能力可能更强但并不等于一定赢下比赛。比如某个队前期被滚雪球后期靠一波团战翻盘它的分均伤害可能很高但经济、视野、推塔都落后这时候雷达图面积不一定小却未必能真实反映“整场比赛的统治力”。第五个建议是不要为了视觉效果拉伸坐标轴起点。雷达图是一种容易被主观误导的图形如果把坐标轴起点从 50 开始而不是从 0 开始两个队伍之间的微小差距会被放大成巨大差异。我的建议是固定从 0 开始保持视觉诚实。第六个建议是数据获取始终遵循合法合规原则。优先使用官方公开数据、授权 API 或人工整理数据不要用破解、绕过访问限制等方式获取赛事数据。技术方法本身没有偏向但使用边界要清楚。如果需要工程化落地可以实现一个简单的处理管线数据采集公开渠道→ 数据清洗 → 指标计算 → 归一化 → 图表渲染 → 导出。Python 脚本负责前面四步ECharts 负责网页端渲染这样可以做到每天赛后自动更新图表前提是数据源和计算逻辑足够稳定。10. 总结与后续学习方向赛后数据雷达图的正确用法是用它解释“为什么赢”和“怎么赢”而不是用它直接宣布“谁更强”。NIP 2-1 WBG 这场比赛如果只看比分结论只有一个但把两队的分均经济、视野、控龙、推进和输出数据放进雷达图就能具体地分析出优势来源和短板所在。这篇文章从雷达图的基础原理讲到指标选取再到数据归一化和完整代码实现覆盖了从零做一张赛后数据雷达图的整个链路。核心可以概括为三句话指标选对比画图漂亮更重要归一化是雷达图能读的基础形状解读必须结合比赛过程。如果你的下一步是深入学习可以从这几个方向入手第一用 pandas 批量处理整个赛季的 BO3 数据做成按周更新的雷达图序列第二把选手维度的雷达图和团队维度分开分析选手在版本变化前后的表现波动第三用 ECharts 做一个可交互的雷达图组件加入鼠标悬浮查看具体数值和指标释义功能。最后提醒一句雷达图只是复盘工具不是标准答案。拿任意一场你熟悉的比赛数据先把 7 个指标列出来归一化再用上面的代码画一张图。你会发现复盘讨论很多时候会在看图之后变得更具体。这也是做数据可视化最让人上瘾的地方。
返回列表