1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
import pandas
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Arc
import matplotlib.animation as animation
import time
# *调整字体以保证中文正常输出
font = {'family': 'Microsoft YaHei'}
# *创建面板
fig = plt.figure(num=1, dpi=200)
# *添加子图(a*b子图第c位置)
ax = fig.add_subplot(1, 1, 1, facecolor='#33691E')
# *调整xy轴比例相等
plt.axis('equal')
# *读取文件
data = pandas.read_csv(
"D:/下载/data/2020_Problem_D_DATA/passingevents.csv", index_col=None)
ID = data.MatchID.values
Teamid = data.TeamID.values
OPI = data.OriginPlayerID.values
DPI = data.DestinationPlayerID.values
MP = data.MatchPeriod.values
Time = data.EventTime.values
Type = data.EventSubType.values
Ox = data.EventOrigin_x.values
Oy = data.EventOrigin_y.values
Dx = data.EventDestination_x.values
Dy = data.EventDestination_y.values
# *绘制基本背景,作为第一帧画面
def init_func():
plt.plot([0, 0], [0, 90],
color="white", linewidth=2)
plt.plot([0, 130], [90, 90],
color="white", linewidth=2)
plt.plot([130, 130], [90, 0],
color="white", linewidth=2)
plt.plot([130, 0], [0, 0],
color="white", linewidth=2)
plt.plot([65, 65], [0, 90],
color="white", linewidth=2)
# *中间的圆
circle_center = plt.Circle((65, 45), 9.15,
color="white", fill=False, linewidth=2)
circle_spot = plt.Circle((65, 45), 0.8,
color="white", linewidth=2)
ax.add_patch(circle_spot)
ax.add_patch(circle_center)
# *左侧禁区
plt.plot([16.5, 16.5], [65, 25],
color="white", linewidth=2)
plt.plot([0, 16.5], [65, 65],
color="white", linewidth=2)
plt.plot([16.5, 0], [25, 25],
color="white", linewidth=2)
# *右侧禁区
plt.plot([130, 113.5], [65, 65],
color="white", linewidth=2)
plt.plot([113.5, 113.5], [65, 25],
color="white", linewidth=2)
plt.plot([113.5, 130], [25, 25],
color="white", linewidth=2)
# *左侧圆弧
left_Arc = Arc((11, 45), height=18.3, width=18.3,
angle=0, theta1=310, theta2=50, color="white", linewidth=2)
ax.add_patch(left_Arc)
# *右侧圆弧
right_Arc = Arc((119, 45), height=18.3, width=18.3,
angle=0, theta1=130, theta2=230, color="white", linewidth=2)
ax.add_patch(right_Arc)
# *左侧小禁区
plt.plot([0, 5.5], [54, 54],
color="white", linewidth=2)
plt.plot([5.5, 5.5], [54, 36],
color="white", linewidth=2)
plt.plot([5.5, 0.5], [36, 36],
color="white", linewidth=2)
# *右侧小禁区
plt.plot([130, 124.5], [54, 54],
color="white", linewidth=2)
plt.plot([124.5, 124.5], [54, 36],
color="white", linewidth=2)
plt.plot([124.5, 130], [36, 36],
color="white", linewidth=2)
# *获得线段XY范围
def cal_line(num):
x = np.linspace(Ox[num]*1.3, Dx[num]*1.3)
y = np.linspace(Oy[num]*0.9, Dy[num]*0.9)
return x, y
# *绘制帧1
def draw_frame1(num):
Time_MatchPeriod.set_text(
"Time:%d MatchPeriod:%s" % (Time[num], MP[num]))
text_matchid.set_text("MatchID: %d" % (ID[num]))
pos_oriplayer.set_data(Ox[num]*1.3, Oy[num]*0.9)
OPI_name.set_position((Ox[num]*1.3, Oy[num]*0.9-2))
OPI_name.set_text("%s" % (OPI[num]))
return pos_oriplayer, OPI_name, Time_MatchPeriod, text_matchid,
# *绘制帧2
def draw_frame2(num):
time.sleep(0.3)
Time_MatchPeriod.set_text(
"Time:%d MatchPeriod:%s" % (Time[num-1], MP[num-1]))
text_matchid.set_text("MatchID: %d" % (ID[num-1]))
text_type.set_position(
((Ox[num-1]*1.3+Dx[num-1]*1.3)/2, (Dy[num-1]*0.9+Oy[num-1]*0.9)/2))
text_type.set_text(Type[num-1])
pos_oriplayer.set_data(Ox[num-1]*1.3, Oy[num-1]*0.9)
OPI_name.set_position((Ox[num-1]*1.3, Oy[num-1]*0.9-2))
OPI_name.set_text("%s" % (OPI[num-1]))
x, y = cal_line(num-1)
line.set_data(x, y)
return pos_oriplayer, OPI_name, Time_MatchPeriod, text_matchid, text_type, line,
# *绘制帧3
def draw_frame3(num):
Time_MatchPeriod.set_text(
"Time:%d MatchPeriod:%s" % (Time[num-2], MP[num-2]))
text_matchid.set_text("MatchID: %d" % (ID[num-2]))
pos_desplayer.set_data(Dx[num-2]*1.3, Dy[num-2]*0.9)
DPI_name.set_position((Dx[num-2]*1.3, Dy[num-2]*0.9-3))
DPI_name.set_text("%s" % (DPI[num-2]))
pos_oriplayer.set_data(Ox[num-2]*1.3, Oy[num-2]*0.9)
OPI_name.set_position((Ox[num-2]*1.3, Oy[num-2]*0.9-2))
OPI_name.set_text("%s" % (OPI[num-2]))
x, y = cal_line(num-2)
line.set_data(x, y)
return pos_desplayer, DPI_name, pos_oriplayer, OPI_name, Time_MatchPeriod, text_matchid, text_type, line,
# *逐帧绘制主函数
def draw_one(num):
if num % 3 == 0:
return draw_frame1(num)
elif num % 3 == 1:
return draw_frame2(num)
elif num % 3 == 2:
return draw_frame3(num)
def update_frames(num):
Time_MatchPeriod.set_position((80, 95))
text_matchid.set_position((-5, 95))
return draw_one(num)
# *初始化位置
line, = plt.plot(0, 0, color='#FFE0B2') # *初始化线段
pos_oriplayer, = plt.plot(0, 0,
"ro", color='#F4511E') # *初始化设置传球者位置
pos_desplayer, = plt.plot(0, 0,
"ro", color='#03A9F4') # *初始化设置接球者位置
OPI_name = plt.text(0, 0, '', ha='center', va='top',
fontsize=5, color='#F4511E') # *初始化设置传球者ID位置
DPI_name = plt.text(0, 0, '', ha='center', va='top',
fontsize=5, color='#03A9F4') # *初始化设置接球者ID位置
Time_MatchPeriod = plt.text(0, 0, '',
fontsize=10, color='white') # *初始化设置比赛时间&比赛阶段位置
text_matchid = plt.text(0, 0, '',
fontsize=10, color='#4DD0E1') # *初始化设置比赛场次ID位置
text_type = plt.text(0, 0, '', ha='center', va='top',
fontsize=6, color='#D81B60') # *初始化设置传球类型位置
ani = animation.FuncAnimation(
fig, update_frames, interval=150, blit=True, repeat=False, save_count=500, frames=500, init_func=init_func()) # *绘制动画
ani.save('plswork.gif', writer="ffmpeg", progress_callback=lambda i, n: print(f'Saving frame {i/n*100}%')) # *利用ffmpeg编码保存动画为mp4,并以百分比形式返回当前进度
plt.show()
|