所以我在这里有一个包含2帧的基本GUI。第一页有两个下拉菜单,用户可以从中选择数据框中的列。它还包括一个按钮,当按下该按钮时,将两个选定列都输出到标签上(这只是为了确保它正确选择)。
我试图让代码执行的操作是,每次在下拉菜单中选择新列时,图表都会使用新绘图进行更新。我认为它就像将它们分配给字符串变量一样简单,但这似乎不起作用。
还有第二页也带有图表,以防更容易在帧中使用此功能,但理想情况下它将保留在同一帧上。
import pandas as pd
import tkinter as tk
#from tkinter import filedialog
from tkinter import ttk
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
df = pd.DataFrame(
[[4, 5, 6],
[7, 8, 9],
[10, 11, 12]],
columns=['a', 'b', 'c'])
xList = []
yList = []
Options = df.dtypes.index
fig = Figure(figsize=(5,4), dpi=100)
ax= fig.add_subplot(111)
LARGE_FONT= ("Verdana", 12)
class GUI(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "GUI")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (Home, Graph):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Home)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class Home(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
def selectXY():
x = varX.get()
y = varY.get()
ax.clear()
X.config(text=x)
Y.config(text=y)
xList = df.loc[:,X]
yList = df.loc[:,Y]
return xList
return yList
#Y axis select
varY = tk.StringVar(self)
# initial value
varY.set('Select Y axis')
optionY = tk.OptionMenu(self, varY, *Options)
optionY.pack()
#X axis select
varX = tk.StringVar(self)
# initial value
varX.set('Select X axis')
optionX = tk.OptionMenu(self, varX, *Options)
optionX.pack()
button2 = tk.Button(self, text="Plot Axes", command = selectXY)
button2.pack()
button2 = ttk.Button(self, text="Graph",
command=lambda: controller.show_frame(Graph))
button2.pack()
Y = ttk.Label(self, text=yList)
Y.pack()
X = ttk.Label(self, text=xList)
X.pack()
df.plot.scatter(xList, yList, ax=ax)
canvas = FigureCanvasTkAgg(fig, self)
canvas.show()
canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
class Graph(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="Graph", font=LARGE_FONT)
label.pack(pady=10,padx=10)
df.plot.scatter(xList, yList, ax=ax)
canvas = FigureCanvasTkAgg(fig, self)
canvas.show()
canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
button3 = ttk.Button(self, text="Back",
command=lambda: controller.show_frame(Home))
button3.pack()
app = GUI()
app.mainloop()
答案 0 :(得分:0)
考虑以下调整:
将您的图形构建移动到 selectXY 方法中,以便按钮可以在单击时运行它。
按名称将轴传递到pandas.DataFrame.plot,其中 x 和 y 为字符串值。因此,不需要带有.loc
调用的 xList 和 yList ,并且值可以直接从 varX 和 varY <派生/ em>下降。
最后,将canvas移动到要调用一次的__init__
方法,而不是每次都创建一个新画布。
以下是 Home 类的调整:
class Home(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10, padx=10)
canvas = FigureCanvasTkAgg(fig, self)
def selectXY():
x = varX.get()
y = varY.get()
X.config(text=x)
Y.config(text=y)
ax.clear()
df.plot.scatter(x, y, ax=ax)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
# Y axis select
varY = tk.StringVar(self)
# initial value
varY.set('Select Y axis')
optionY = tk.OptionMenu(self, varY, *Options)
optionY.pack()
# X axis select
varX = tk.StringVar(self)
# initial value
varX.set('Select X axis')
optionX = tk.OptionMenu(self, varX, *Options)
optionX.pack()
button2 = tk.Button(self, text="Plot Axes", command = selectXY)
button2.pack()
button2 = ttk.Button(self, text="Graph",
command=lambda: controller.show_frame(Graph))
button2.pack()
Y = ttk.Label(self, text=yList)
Y.pack()
X = ttk.Label(self, text=xList)
X.pack()
对于 Graph 类,要复制与 Home 相同的图,需要对全局变量, show_frame 中的visiblity触发事件和更新的属性进行一些广泛的调整在 Graph 。