在 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 已经提到的,您并没有真正使用 xy 值来绘制您的图形。另一方面,您的 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()

继续这样下去!你真的已经做得很好了,即使我的代码看起来与你的代码不同,大多数部分只是重新排列!