在 tkinter 中制作计数历史的交互式图表
Make interactive graph of count history in tkinter
我有以下用于带有两个按钮的计数器的代码,一个用于增加计数,另一个用于减少计数。 count 是一个包含数字的标签。与按钮一起出现的图表应该可视化计数的历史,即。 x 轴是 results_table 的索引号,y 轴是计数中出现的数字。按钮和计数有效,但图表不显示以下代码。显然我缺少一些东西来更新图表。这是代码:
import tkinter
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
class App:
def __init__(self, master):
# Create a container
frame = tkinter.Frame(master)
# Create 2 buttons
self.button_left = tkinter.Button(frame,text="-", command=self.decrease, bg = 'red', fg = 'white')
self.button_left.pack(side="left")
self.button_right = tkinter.Button(frame,text="+", command=self.increase, bg = 'green', fg = 'white')
self.button_right.pack(side="right")
self.label_value = tk.Label(frame, text = '0')
self.label_value.pack(side = "bottom")
fig = Figure()
ax = fig.add_subplot(111)
self.line, = ax.plot(0)
self.canvas = FigureCanvasTkAgg(fig,master=master)
self.canvas.draw()
self.canvas.get_tk_widget().pack(side='top', fill='both', expand=1)
frame.pack()
result_table = []
def decrease(self):
value = int(self.label_value["text"])
self.label_value["text"] = f"{value - 1}"
result_table.append(self.label_value['text'])
x, y = self.line.get_data('result_table')
self.canvas.draw()
def increase(self):
value = int(self.label_value["text"])
self.label_value["text"] = f"{value + 1}"
result_table.append(self.label_value['text'])
x, y = self.line.get_data('result_table')
self.canvas.draw()
root = tkinter.Tk()
app = App(root)
root.mainloop()
非常感谢任何帮助。
马特
所以我解决了你的问题,但这不是直接的 answer/solution。
首先你把你的GUI设计的好好的!我只是不会使用 pack()
,但我更喜欢 grid()
。
接下来,我不得不删除你的 class,因为我从未将 tkinter 与 class 一起使用。也许你可以把它放回去。
所以我做了什么:
正如 Matiiss 已经提到的,您并没有真正使用 x
和 y
值来绘制您的图形。另一方面,您的 result_table
工作正常并存储所有创建的值!
所以你必须将它们绘制为 y
值,而你的 x
值基本上取决于你的 result_table len(result_table)
的长度。对于这一部分,我使用 numpy 始终生成适当长度的数组。
此外,我在根目录中创建了一个额外的容器fig_frame
,我总是在其中显示图形。
这段代码对我有用:
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
def decrease():
value = int(label_value["text"])
label_value["text"] = f"{value - 1}"
result_table.append(label_value['text'])
x = np.arange(len(result_table))
y = result_table
create_fig(x, y)
def increase():
value = int(label_value["text"])
label_value["text"] = f"{value + 1}"
result_table.append(label_value['text'])
x = np.arange(len(result_table))
y = result_table
create_fig(x, y)
def create_fig(x, y):
fig = Figure()
ax = fig.add_subplot(111)
line, = ax.plot(x, y)
canvas = FigureCanvasTkAgg(fig, fig_frame)
canvas.draw()
canvas.get_tk_widget().grid(row=0, column=0)
root = tk.Tk()
# Create a container
frame = tk.Frame(root)
fig_frame = tk.Canvas(root, height=650, width=650, borderwidth=1, relief='ridge')
fig_frame.pack()
# Create 2 buttons
button_left = tk.Button(frame, text="-", command=decrease, bg='red', fg='white')
button_left.pack(side="left")
button_right = tk.Button(frame, text="+", command=increase, bg='green', fg='white')
button_right.pack(side="right")
label_value = tk.Label(frame, text='0')
label_value.pack(side="bottom")
fig = Figure()
ax = fig.add_subplot(111)
line, = ax.plot(0)
canvas = FigureCanvasTkAgg(fig, fig_frame)
canvas.draw()
canvas.get_tk_widget().grid(row=0, column=0)
frame.pack()
result_table = []
root.mainloop()
继续这样下去!你真的已经做得很好了,即使我的代码看起来与你的代码不同,大多数部分只是重新排列!
我有以下用于带有两个按钮的计数器的代码,一个用于增加计数,另一个用于减少计数。 count 是一个包含数字的标签。与按钮一起出现的图表应该可视化计数的历史,即。 x 轴是 results_table 的索引号,y 轴是计数中出现的数字。按钮和计数有效,但图表不显示以下代码。显然我缺少一些东西来更新图表。这是代码:
import tkinter
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
class App:
def __init__(self, master):
# Create a container
frame = tkinter.Frame(master)
# Create 2 buttons
self.button_left = tkinter.Button(frame,text="-", command=self.decrease, bg = 'red', fg = 'white')
self.button_left.pack(side="left")
self.button_right = tkinter.Button(frame,text="+", command=self.increase, bg = 'green', fg = 'white')
self.button_right.pack(side="right")
self.label_value = tk.Label(frame, text = '0')
self.label_value.pack(side = "bottom")
fig = Figure()
ax = fig.add_subplot(111)
self.line, = ax.plot(0)
self.canvas = FigureCanvasTkAgg(fig,master=master)
self.canvas.draw()
self.canvas.get_tk_widget().pack(side='top', fill='both', expand=1)
frame.pack()
result_table = []
def decrease(self):
value = int(self.label_value["text"])
self.label_value["text"] = f"{value - 1}"
result_table.append(self.label_value['text'])
x, y = self.line.get_data('result_table')
self.canvas.draw()
def increase(self):
value = int(self.label_value["text"])
self.label_value["text"] = f"{value + 1}"
result_table.append(self.label_value['text'])
x, y = self.line.get_data('result_table')
self.canvas.draw()
root = tkinter.Tk()
app = App(root)
root.mainloop()
非常感谢任何帮助。 马特
所以我解决了你的问题,但这不是直接的 answer/solution。
首先你把你的GUI设计的好好的!我只是不会使用 pack()
,但我更喜欢 grid()
。
接下来,我不得不删除你的 class,因为我从未将 tkinter 与 class 一起使用。也许你可以把它放回去。
所以我做了什么:
正如 Matiiss 已经提到的,您并没有真正使用 x
和 y
值来绘制您的图形。另一方面,您的 result_table
工作正常并存储所有创建的值!
所以你必须将它们绘制为 y
值,而你的 x
值基本上取决于你的 result_table len(result_table)
的长度。对于这一部分,我使用 numpy 始终生成适当长度的数组。
此外,我在根目录中创建了一个额外的容器fig_frame
,我总是在其中显示图形。
这段代码对我有用:
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
def decrease():
value = int(label_value["text"])
label_value["text"] = f"{value - 1}"
result_table.append(label_value['text'])
x = np.arange(len(result_table))
y = result_table
create_fig(x, y)
def increase():
value = int(label_value["text"])
label_value["text"] = f"{value + 1}"
result_table.append(label_value['text'])
x = np.arange(len(result_table))
y = result_table
create_fig(x, y)
def create_fig(x, y):
fig = Figure()
ax = fig.add_subplot(111)
line, = ax.plot(x, y)
canvas = FigureCanvasTkAgg(fig, fig_frame)
canvas.draw()
canvas.get_tk_widget().grid(row=0, column=0)
root = tk.Tk()
# Create a container
frame = tk.Frame(root)
fig_frame = tk.Canvas(root, height=650, width=650, borderwidth=1, relief='ridge')
fig_frame.pack()
# Create 2 buttons
button_left = tk.Button(frame, text="-", command=decrease, bg='red', fg='white')
button_left.pack(side="left")
button_right = tk.Button(frame, text="+", command=increase, bg='green', fg='white')
button_right.pack(side="right")
label_value = tk.Label(frame, text='0')
label_value.pack(side="bottom")
fig = Figure()
ax = fig.add_subplot(111)
line, = ax.plot(0)
canvas = FigureCanvasTkAgg(fig, fig_frame)
canvas.draw()
canvas.get_tk_widget().grid(row=0, column=0)
frame.pack()
result_table = []
root.mainloop()
继续这样下去!你真的已经做得很好了,即使我的代码看起来与你的代码不同,大多数部分只是重新排列!