如何解决如何在 Tkinter 窗口中绘制 Matplotlib 图?
我需要你的一些想法来尝试自己实现。我有一个带有 2 个标签的主 Tk()
窗口,但我现在只关注一个(group_stage_frame):
root = tk.Tk()
my_notebook = ttk.Notebook(root)
my_notebook.pack()
group_stage_frame = Frame(my_notebook,width=1080,height=1080)
knockout_stage_frame = Frame(my_notebook,height=1080)
group_stage_frame.pack(fill="both",expand=1)
knockout_stage_frame.pack(fill="both",expand=1)
my_notebook.add(group_stage_frame,text="GROUP STAGE")
my_notebook.add(knockout_stage_frame,text="KNOCKOUT STAGE")
group_A_label = Label(group_stage_frame,text="GROUP A").grid(row=0,column=0)
buttonA1 = Button(group_stage_frame,text="Russia 5-0 Saudi arabia",width=25,command=A1window).grid(row=1,column=0)
root.mainloop()
buttonA1 功能:
def A1window():
def showPlayersA1():
heat_pass_map(df,clickedRussia.get())
heat_pass_map(df,clickedarabia.get())
rootA1 = tk.Toplevel()
rootA1.title("Russia 5-0 Saudi arabia")
#events
with open(r'C:\Users\Catalin\Desktop\WorldCupData\data\events\7525.json',encoding = 'utf-8') as f:
data = json.load(f)
df = pd.json_normalize(data,sep = "_")
#lineup
with open(r'C:\Users\Catalin\Desktop\WorldCupData\data\lineups\7525.json',encoding = 'utf-8') as f:
lineup = json.load(f)
#Dropdown menu Russia lineup
clickedRussia = tk.StringVar()
clickedRussia.set("Choose any Russian player")
options_list_Russia = []
for i in range(14):
options_list_Russia.append(lineup[0]['lineup'][i]['player_name'])
dropRussia = tk.OptionMenu(rootA1,clickedRussia,*options_list_Russia)
dropRussia.config(width=50)
dropRussia.pack(side = "top",anchor = CENTER)
#Dropdown menu Saudi arabia lineup
clickedarabia = tk.StringVar()
clickedarabia.set("Choose any Saudi arabia player")
options_list_arabia = []
for i in range(14):
options_list_arabia.append(lineup[1]['lineup'][i]['player_name'])
droparabia = tk.OptionMenu(rootA1,clickedarabia,*options_list_arabia)
droparabia.config(width=50)
droparabia.pack(side = "top",anchor = CENTER)
buttonCompare = tk.Button(rootA1,text="COMPARE",command=showPlayersA1).pack(side = "top",anchor = CENTER)
我正在为每个国家的选定球员绘制热图和传球图以比较图表:
def draw_pitch(ax):
# size of the pitch is 120,80
#Create figure
#Pitch Outline & Centre Line
plt.plot([0,0],[0,80],color="black")
plt.plot([0,120],[80,color="black")
plt.plot([120,color="black")
plt.plot([60,60],color="black")
#Left Penalty Area
plt.plot([14.6,14.6],[57.8,22.2],57.8],[22.2,color="black")
#Right Penalty Area
plt.plot([120,105.4],color="black")
plt.plot([105.4,22.5],[22.5,color="black")
#Left 6-yard Box
plt.plot([0,4.9],[48,48],color="black")
plt.plot([4.9,32],[32,color="black")
#Right 6-yard Box
plt.plot([120,115.1],color="black")
plt.plot([115.1,color="black")
#Prepare Circles
centreCircle = plt.Circle((60,40),8.1,color="black",fill=False)
centreSpot = plt.Circle((60,0.71,color="black")
leftPenSpot = plt.Circle((9.7,color="black")
rightPenSpot = plt.Circle((110.3,color="black")
#Draw Circles
ax.add_patch(centreCircle)
ax.add_patch(centreSpot)
ax.add_patch(leftPenSpot)
ax.add_patch(rightPenSpot)
#Prepare Arcs
# arguments for arc
# x,y coordinate of centerpoint of arc
# width,height as arc might not be circle,but oval
# angle: degree of rotation of the shape,anti-clockwise
# theta1,theta2,start and end location of arc in degree
leftArc = Arc((9.7,height=16.2,width=16.2,angle=0,theta1=310,theta2=50,color="black")
rightArc = Arc((110.3,theta1=130,theta2=230,color="black")
#Draw Arcs
ax.add_patch(leftArc)
ax.add_patch(rightArc)
def heat_pass_map(data,player_name):
pass_data = data[(data['type_name'] == "Pass") & (data['player_name'] == player_name)]
action_data = data[(data['player_name']==player_name) & (data['type_name'] != 'Substitution')]
fig=plt.figure()
fig.set_size_inches(7,5)
ax=fig.add_subplot(1,1,1)
draw_pitch(ax)
plt.axis('off')
#passes
for i in range(len(pass_data)):
# we also differentiate different half by different color
color = "blue" if pass_data.iloc[i]['period'] == 1 else "red"
ax.annotate("",xy = (pass_data.iloc[i]['pass_end_location'][0],pass_data.iloc[i]['pass_end_location'][1]),xycoords = 'data',xytext = (pass_data.iloc[i]['location'][0],pass_data.iloc[i]['location'][1]),textcoords = 'data',arrowprops=dict(arrowstyle="->",connectionstyle="arc3",color = color))
#heatmap
x_coord = [i[0] for i in action_data["location"]]
y_coord = [i[1] for i in action_data["location"]]
sns.kdeplot(x = x_coord,y = y_coord,shade = "True",thresh = 0,cmap = "Greens",n_levels = 10)
#create arrow legend
blue_arrow = mlines.Line2D([],[],c='blue',marker=r'$\rightarrow$',markersize=15,linestyle='None',label='First half pass')
red_arrow = mlines.Line2D([],c='red',label='Second half pass')
plt.ylim(0,80) # need this,otherwise kde plot will go outside
plt.xlim(0,120)
plt.legend(handles=[blue_arrow,red_arrow],loc='upper right')
plt.title(str(player_name)+ "'s pass map")
plt.show()
所以,基本上,如果我能以某种方式将 2 个图形绘制到我的 rootA1 窗口中,我想要一些想法。我读过关于画布小部件的信息,但我认为这不是很有帮助,因为 rootA1(当我从大型机单击按钮时弹出的第二个框架)在 A1window 函数中。
我想到的另一个想法是在 main 函数中创建 rootA1 并隐藏它直到我按下按钮。
想问问各位大佬,谢谢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。