微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 Tkinter 窗口中绘制 Matplotlib 图?

如何解决如何在 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 举报,一经查实,本站将立刻删除。