Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在matplotlib和tkinter中提示动画时刷新_Python_Matplotlib_Animation_Tkinter - Fatal编程技术网

Python 如何在matplotlib和tkinter中提示动画时刷新

Python 如何在matplotlib和tkinter中提示动画时刷新,python,matplotlib,animation,tkinter,Python,Matplotlib,Animation,Tkinter,我试图提示刷新动画绘图,但显然函数FuncAnimation()等待刷新和最后一个间隔条目,我想覆盖它。我的目标:我希望让绘图非常缓慢地更新,例如每分钟更新一次,但在提示或事件时刷新(此事件是一个参数条目) 让我一步一步地解释我的tkinter应用程序是如何工作的。我将在最后发布整个代码 为了这篇文章,我把我的应用程序缩减到最低限度。该应用程序包含一个绘图面板和一个带有命令的侧面板。该应用程序由包含菜单栏的主类plotApp()和两个Pananel组成。这两个面板是两个tk帧,编码成一个单独的类

我试图提示刷新动画绘图,但显然函数
FuncAnimation()
等待刷新和最后一个间隔条目,我想覆盖它。我的目标:我希望让绘图非常缓慢地更新,例如每分钟更新一次,但在提示或事件时刷新(此事件是一个参数条目)

让我一步一步地解释我的tkinter应用程序是如何工作的。我将在最后发布整个代码

为了这篇文章,我把我的应用程序缩减到最低限度。该应用程序包含一个绘图面板和一个带有命令的侧面板。该应用程序由包含菜单栏的主类
plotApp()
和两个Pananel组成。这两个面板是两个tk帧,编码成一个单独的类
Graph()
Commands()
。然后使用函数
show\u frame()
引发这些问题。
Graph()
部件使用对象
f=plt.figure()
初始化绘图区域。
Commands()
部分包含tk输入方法,因此我可以插入参数
my_参数
。插入
my_参数
后,函数
animate()
将执行嵌入绘图的部分

问题是。绘图数据由大型查询
x,y=my\u big\u query\u命令(my\u参数)
检索。我必须降低查询更新的频率,比如每分钟一次——数据不会有太大变化。然而,当我设置
interval=60000
(毫秒)并输入新参数时,函数
FuncAnimation()
会等待整整一分钟来更新查询和绘图。目标1:我希望他们能立即更新。目标2:我希望保持(或重置)一分钟的慢节奏。我该怎么做

到目前为止我都试过了。为了重复性,我用简单的数据替换了对数据
x,y
的查询。输入参数my_parameter时,函数
toggle_refresh_plot()
将激活标志以运行查询和打印。这发生在类
Commands()
的函数
set\u entry()

我还尝试从
set\u entry()
中调用函数
animate()
,但没有用

然后,我在函数
animate()
中嵌入了
if
语句。如果标志为
True
,则调用查询和绘图。查询之后,我使用命令
ani.event\u source.interval=slow\u refresh
将速度设置为一分钟,其中
ani
对象定义为
animation.FuncAnimation(f,animate,interval=slow\u refresh)
。如果标志为
False
,则间隔将缩短为1秒,这样应用程序可以更快地听到我的提示,而无需刷新繁重的查询。命令
ani.event\u source.interval
起作用,但效果并不理想:它在输入后仍会等待整整一分钟

def animate(i):
    print("refresh_flag", refresh_flag)

    if refresh_flag:
        try:
            # query data here
            # ...

            # plot here
            # ...

            print('refreshed: ', datetime.today())

        except Exception as e:
            print("error message:", str(e))

        ani.event_source.interval = slow_refresh  # after query slow down pace
    else:
        ani.event_source.interval = 1000  # every second
        # ani.event_source.interval = slow_refresh
函数
animate()
中的
print()
命令显示何时调用查询和绘图

我在冻结模式下初始化应用程序,即
refresh\u flag=False
,慢60秒
slow\u refresh=60*1000
,空
my\u参数=“”

菜单中还有一个刷新命令,用于控制功能
切换\u Refresh\u plot()

下面是整个代码

from datetime import datetime, timedelta
import numpy as np

from matplotlib import pyplot as plt
import matplotlib.animation as animation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk

import tkinter as tk
from tkinter import ttk


def toggle_refresh_plot(toggle):
    global refresh_flag

    if toggle == 'resume':
        refresh_flag = True
    elif toggle == 'freeze':
        refresh_flag = False


def animate(i):
    print("refresh_flag", refresh_flag)

    if refresh_flag:
        try:
            # query data here
            # x, y = my_big_query_command(my_parameter)
            x = np.arange(10)
            y = np.sqrt(x)

            a1 = plt.subplot2grid((1, 2), (0, 0), rowspan=1, colspan=1)
            a2 = plt.subplot2grid((1, 2), (0, 1), sharey=a1, rowspan=1, colspan=1)
            plt.subplots_adjust(wspace=0.2)

            a1.plot(x, y, 'b-')
            a2.plot(x, x / (y + 1), 'b-')

            print('refreshed: ', datetime.today())

        except Exception as e:
            print("error message:", str(e))

        ani.event_source.interval = slow_refresh  # after query slow down pace
    else:
        ani.event_source.interval = 1000  # every second
        # ani.event_source.interval = slow_refresh


class plotApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.wm_title(self, "Plotting App")

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        menubar = tk.Menu(container)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Exit", command=quit)
        menubar.add_cascade(label="File", menu=filemenu)

        startStop = tk.Menu(menubar, tearoff=1)
        startStop.add_command(label="Resume", command=lambda: toggle_refresh_plot('resume'))
        startStop.add_command(label="Freeze", command=lambda: toggle_refresh_plot('freeze'))
        menubar.add_cascade(label="Refresh", menu=startStop)

        tk.Tk.config(self, menu=menubar)

        self.frames = {}  # initialize empty frames

        # build Graph frame
        frame = Graph(container, self)
        self.frames[Graph] = frame
        frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(Graph)
        # build Commands frame
        frame = Commands(container, self)
        self.frames[Commands] = frame
        frame.grid(row=0, column=1)
        self.show_frame(Commands)


    def show_frame(self, frame_name):
        frame = self.frames[frame_name]
        frame.tkraise()


class Commands(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.parent = parent

        side_frame = tk.Frame(self)
        side_frame.pack()

        Lab1 = tk.Label(side_frame, text="Insert name", anchor=tk.W)
        Lab1.grid(row=1, column=0)

        def set_entry(self):
            global my_parameter
            my_parameter = (e1.get())
            print("Entry:", my_parameter)
            toggle_refresh_plot('resume')


        e1 = ttk.Entry(side_frame)
        e1.bind("<Return>", set_entry)
        e1.grid(row=2, column=0)


class Graph(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        canvas = FigureCanvasTkAgg(f, self)
        canvas.draw()
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        toolbar = NavigationToolbar2Tk(canvas, self)
        toolbar.update()
        canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)


f = plt.figure()
# a1 = f.add_subplot(111)

refresh_flag = False
slow_refresh = 60 * 1000  # refresh plot every 60 sec

my_parameter = ''  # initialize as empty

app = plotApp()
ani = animation.FuncAnimation(f, animate, interval=slow_refresh)  # update chart every 'interval' milliseconds
app.mainloop()
从datetime导入datetime,timedelta
将numpy作为np导入
从matplotlib导入pyplot作为plt
将matplotlib.animation导入为动画
从matplotlib.backends.backend_tkagg导入图CAVASTKAGG,导航工具栏2TK
将tkinter作为tk导入
从tkinter导入ttk
def切换\刷新\绘图(切换):
全局刷新标志
如果切换==“恢复”:
刷新标志=True
elif切换==“冻结”:
刷新标志=False
定义动画(i):
打印(“刷新标志”,刷新标志)
如果刷新\u标志:
尝试:
#在此查询数据
#x,y=my\u big\u query\u命令(my\u参数)
x=np.arange(10)
y=np.sqrt(x)
a1=plt.subplot2grid((1,2)、(0,0),rowspan=1,colspan=1)
a2=plt.subplot2grid((1,2)、(0,1),sharey=a1,rowspan=1,colspan=1)
plt.子批次调整(wspace=0.2)
a1.图(x,y,'b-')
a2.图(x,x/(y+1),‘b-’)
打印('刷新:',datetime.today())
例外情况除外,如e:
打印(“错误消息:”,str(e))
ani.event_source.interval=慢_刷新#查询后慢节奏
其他:
ani.event_source.interval=1000#每秒
#ani.event\u source.interval=缓慢刷新
类plotApp(tk.tk):
定义初始化(self,*args,**kwargs):
tk.tk.\uuuuu初始化(self,*args,**kwargs)
tk.tk.wm_标题(自,“绘图应用程序”)
容器=tk.框架(自身)
container.pack(side=“top”,fill=“both”,expand=True)
container.grid_rowconfigure(0,权重=1)
container.grid\u column配置(0,权重=1)
菜单栏=传统菜单(容器)
filemenu=tk.Menu(menubar,tearoff=0)
filemenu.add_命令(label=“Exit”,command=quit)
menubar.add_级联(label=“File”,menu=filemenu)
startStop=tk.菜单(菜单栏,tearof=1)
startStop.add_命令(label=“Resume”,command=lambda:toggle_refresh_plot('Resume'))
startStop.add_命令(label=“Freeze”,command=lambda:toggle_refresh_plot('Freeze'))
菜单栏.add_级联(label=“Refresh”,menu=startStop)
tk.tk.config(self,menu=menubar)
self.frames={}#初始化空帧
#建立图形框架
框架=图形(容器、自身)
self.frames[图]=帧
frame.grid(行=0,列=0,sticky=“nsew”)
self.show_框架(图形)
#构建命令框架
frame=命令(容器,s
from datetime import datetime, timedelta
import numpy as np

from matplotlib import pyplot as plt
import matplotlib.animation as animation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk

import tkinter as tk
from tkinter import ttk


def toggle_refresh_plot(toggle):
    global refresh_flag

    if toggle == 'resume':
        refresh_flag = True
    elif toggle == 'freeze':
        refresh_flag = False


def animate(i):
    print("refresh_flag", refresh_flag)

    if refresh_flag:
        try:
            # query data here
            # x, y = my_big_query_command(my_parameter)
            x = np.arange(10)
            y = np.sqrt(x)

            a1 = plt.subplot2grid((1, 2), (0, 0), rowspan=1, colspan=1)
            a2 = plt.subplot2grid((1, 2), (0, 1), sharey=a1, rowspan=1, colspan=1)
            plt.subplots_adjust(wspace=0.2)

            a1.plot(x, y, 'b-')
            a2.plot(x, x / (y + 1), 'b-')

            print('refreshed: ', datetime.today())

        except Exception as e:
            print("error message:", str(e))

        ani.event_source.interval = slow_refresh  # after query slow down pace
    else:
        ani.event_source.interval = 1000  # every second
        # ani.event_source.interval = slow_refresh


class plotApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.wm_title(self, "Plotting App")

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        menubar = tk.Menu(container)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Exit", command=quit)
        menubar.add_cascade(label="File", menu=filemenu)

        startStop = tk.Menu(menubar, tearoff=1)
        startStop.add_command(label="Resume", command=lambda: toggle_refresh_plot('resume'))
        startStop.add_command(label="Freeze", command=lambda: toggle_refresh_plot('freeze'))
        menubar.add_cascade(label="Refresh", menu=startStop)

        tk.Tk.config(self, menu=menubar)

        self.frames = {}  # initialize empty frames

        # build Graph frame
        frame = Graph(container, self)
        self.frames[Graph] = frame
        frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(Graph)
        # build Commands frame
        frame = Commands(container, self)
        self.frames[Commands] = frame
        frame.grid(row=0, column=1)
        self.show_frame(Commands)


    def show_frame(self, frame_name):
        frame = self.frames[frame_name]
        frame.tkraise()


class Commands(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.parent = parent

        side_frame = tk.Frame(self)
        side_frame.pack()

        Lab1 = tk.Label(side_frame, text="Insert name", anchor=tk.W)
        Lab1.grid(row=1, column=0)

        def set_entry(self):
            global my_parameter
            my_parameter = (e1.get())
            print("Entry:", my_parameter)
            toggle_refresh_plot('resume')


        e1 = ttk.Entry(side_frame)
        e1.bind("<Return>", set_entry)
        e1.grid(row=2, column=0)


class Graph(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        canvas = FigureCanvasTkAgg(f, self)
        canvas.draw()
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        toolbar = NavigationToolbar2Tk(canvas, self)
        toolbar.update()
        canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)


f = plt.figure()
# a1 = f.add_subplot(111)

refresh_flag = False
slow_refresh = 60 * 1000  # refresh plot every 60 sec

my_parameter = ''  # initialize as empty

app = plotApp()
ani = animation.FuncAnimation(f, animate, interval=slow_refresh)  # update chart every 'interval' milliseconds
app.mainloop()