mplsoccer足球场坐标绘图出线问题排查及适配方案求助
问题根源与解决方法
1. 出线原因
你使用的plt.fill_between()函数并非用于绘制闭合多边形填充,它的作用是填充x轴与指定y值曲线之间的区域,这会导致坐标点顺序或范围不合适时,出现超出球场边界的线条。
2. 修正方案
(1)替换填充函数
把plt.fill_between()换成plt.fill(),这个函数专门用于绘制闭合多边形,配合你已经追加首尾点的操作,能正确闭合图形:
plt.scatter(alistx, alisty) plt.fill(alistx, alisty, color='red', alpha=0.3)
(2)限制坐标在球场范围内
mplsoccer的球场有固定坐标范围(比如默认statsbomb类型是x∈[0,120]、y∈[0,80]),你对endX乘1.2、endY乘0.8可能让部分坐标超出边界,需要裁剪坐标:
# 裁剪坐标到球场范围内(以statsbomb类型为例) alistx = [max(0, min(120, x)) for x in map(int, dfs['endX']*1.2)] alistx.append(alistx[0]) alisty = [max(0, min(80, y)) for y in map(int, dfs['endY']*0.8)] alisty.append(alisty[0])
(3)适配mplsoccer的更优写法
mplsoccer推荐直接在球场轴上操作,用Polygon工具绘制填充区域,适配不同球场类型:
from mplsoccer import Pitch import matplotlib.pyplot as plt from matplotlib.patches import Polygon # 初始化球场 pitch = Pitch(pitch_color='green', pitch_type='statsbomb') fig, ax = pitch.draw() # 处理坐标并自动适配球场范围 alistx = list(map(int, dfs['endX']*1.2)) alistx.append(alistx[0]) alisty = list(map(int, dfs['endY']*0.8)) alisty.append(alisty[0]) # 自动获取球场边界并裁剪坐标 alistx = [max(pitch.extent[0], min(pitch.extent[1], x)) for x in alistx] alisty = [max(pitch.extent[2], min(pitch.extent[3], y)) for y in alisty] # 绘制散点和填充多边形 ax.scatter(alistx, alisty) polygon = Polygon(list(zip(alistx, alisty)), color='red', alpha=0.3) ax.add_patch(polygon) plt.show()
用pitch.extent可以自动获取当前球场的坐标范围,不用手动写死数值,适配不同的球场规格。
3. 额外提示
如果你的endX和endY是0-1的归一化坐标,不需要额外缩放,直接用mplsoccer自带的绘图方法更便捷:
# 归一化坐标的简化写法 pitch = Pitch(pitch_color='green') fig, ax = pitch.draw() pitch.scatter(dfs['endX'], dfs['endY'], ax=ax) pitch.fill(dfs['endX'], dfs['endY'], color='red', alpha=0.3, ax=ax) plt.show()
内容的提问来源于stack exchange,提问作者Timothy Dill
相关产品推荐
相关产品推荐

