无法使用按钮和自定义数据更新Tkinter matplotlib图形 [英] Unable to update Tkinter matplotlib graph with buttons and custom data

查看:268
本文介绍了无法使用按钮和自定义数据更新Tkinter matplotlib图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个使用 Tkinter matplotlib 的程序。我有2个列表列表(一个为x轴,一个为y轴),我想有一个按钮,可以在列表中的列表之间切换。我从问题中获取了大量代码。基于Tkinter和matplotlib的交互图a>,但是当按下按钮时我无法得到更新的图形。我很新鲜,使用类和有点难以理解他们。

I'm working on creating a program that utilizes Tkinter and matplotlib. I have 2 lists of lists (one for x-axis, one for y-axis) and I'm looking to have a button that can switch between the lists within the list. I took much of the code from the question Interactive plot based on Tkinter and matplotlib, but I can't get the graph to update when the button is pressed. I'm quite new to using classes and having a bit of difficulty understanding them.

tft 数据 tf1 是我的代码中的y数据。

tft is the x-data tf1 is the y-data in my code.

数据示例:

x-data = [[1,2,3,4,5],[10,11,13,15,12,19],[20,25, 27]]

y-data = [[5.4,6,10,11,6],[4 ,6,8,34,20,12],[45,25,50]]

列表中,但按下按钮时不会在列表内的列表之间切换。 event_num 的正确值也打印在命令窗口中( event_num 的问题已在先前的问题这里)。

My code below will graph one of the lists within a list, but won't switch between the lists within that list when the button is pressed. The correct value for event_num also prints in the command window (the issue of event_num was solved in a previous questions here).

没有出现的错误,程序只打印数字(当按下按钮时),但不用列表中的新数据更新图形。

There is no error that appears, the program only prints the number (when the button is pressed), but doesn't update the graph with the new data from the list.

#Importing Modules
import glob
from Tkinter import *
from PIL import Image
from Text_File_breakdown import Text_File_breakdown
import re
import matplotlib.pyplot as plt
from datetime import datetime

#Initializing variables
important_imgs=[]
Image_dt=[]
building=[]
quick=[]
num=0
l=0
match=[]

#Getting the names of the image files
image_names=glob.glob("C:\Carbonite\EL_36604.02_231694\*.jpeg")


#image= Image.open(images_names[1])
#image.show()

#Text_File_breakdown(file,voltage limit,pts after lim, pts before lim)
tft,tf1,tf2=Text_File_breakdown('C:\Carbonite\EL_36604.02_231694.txt',3.0,5,5)
#tft= time of voltages      tf1=Voltage signal 1             tf2=Voltage signal 2
#Test Settings: 'C:\Carbonite\EL_36604.02_231694.txt',3.0,5,5


#Getting the Dates from the image names
for m in image_names:
    Idt=re.search("([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}.[0-9]{2}.[0-9]{2})", m)
    Im_dat_tim=Idt.group(1)
    Im_dat_tim=datetime.strptime(Im_dat_tim, '%Y-%m-%d %H.%M.%S')
    Image_dt.append(Im_dat_tim)
    Im_dat_tim=None

#Looking for the smallest difference between the voltage and image dates and associating an index number (index of the image_names variable) with each voltage time
for event in range(len(tft)):
    for i in range(len(tft[event])):
        diff=[tft[event][i]-Image_dt[0]]
        diff.append(tft[event][i]-Image_dt[0])
        while abs(diff[l])>=abs(diff[l+1]):
            l=l+1
            diff.append(tft[event][i]-Image_dt[l])
        match.append(l)
        l=0

#Arranging the index numbers (for the image_names variable) in a list of lists like tft variable
for count in range(len(tft)):
    for new in range(len(tft[count])):
        quick.append(match[num])
        num=num+1
    building.append(quick)
    quick=[]




plt.close('all')
fig, ax = plt.subplots(1)
ax.plot(tft[1],tf1[1],'.')

# rotate and align the tick labels so they look better
fig.autofmt_xdate()

# use a more precise date string for the x axis locations in the
# toolbar
import matplotlib.dates as mdates
ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')
plt.title('Single Event')



继续代码/部分代码,其中问题是:



Continuation of code/Portion of code where the issue is:

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np

class App:

    def __init__(self, master):

        self.event_num = 1

        # Create a container
        frame = Frame(master)

        # Create 2 buttons
        self.button_left = Button(frame,text="< Previous Event",
                                    command=self.decrease)
        self.button_left.grid(row=0,column=0)
        self.button_right = Button(frame,text="Next Event >",
                                    command=self.increase)
        self.button_right.grid(row=0,column=1)


        fig = Figure()
        ax = fig.add_subplot(111)
        fig.autofmt_xdate()
        import matplotlib.dates as mdates
        ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')
        self.line, = ax.plot(tft[self.event_num],tf1[self.event_num],'.')


        self.canvas = FigureCanvasTkAgg(fig,master=master)
        self.canvas.show()
        self.canvas.get_tk_widget().grid(row=1,column=0)
        frame.grid(row=0,column=0)

    def decrease(self):
        self.event_num -= 1
        print self.event_num
        self.line, = ax.plot(tft[self.event_num],tf1[self.event_num],'.')
        self.canvas.draw()
        #self.canvas.draw(tft[self.event_num],tf1[self.event_num],'.')
        #self.line.set_xdata(tft[event_num])
        #self.line.set_ydata(tf1[event_num])



    def increase(self):
        self.event_num += 1        
        print self.event_num
        self.line, = ax.plot(tft[self.event_num],tf1[self.event_num],'.')
        self.canvas.draw()
        #self.canvas.draw(tft[self.event_num],tf1[self.event_num],'.')
        #self.set_xdata(tft[event_num])
        #self.set_ydata(tf1[event_num])



root = Tk()
app = App(root)
root.mainloop()


推荐答案

问题是你总是在不同的坐标轴上绘制比你想象的。 self.line,= ax.plot(tft [self.event_num],tf1 [self.event_num],'。')指的是你在类外创建的轴,而不是您在 App 类中创建的轴。该问题可以通过创建 self.fig self.ax 属性来补救:

The problem is that you are constantly plotting on a different set of axes than you think. self.line, = ax.plot(tft[self.event_num],tf1[self.event_num],'.') refers to the axes that you created outside your class, not the axes in the figure you created in the App class. The problem can be remedied by creating self.fig and self.ax attributes:

class App:

    def __init__(self, master):

        self.event_num = 1

        # Create a container
        frame = Frame(master)

        # Create 2 buttons
        self.button_left = Button(frame,text="< Previous Event",
                                    command=self.decrease)
        self.button_left.grid(row=0,column=0)
        self.button_right = Button(frame,text="Next Event >",
                                    command=self.increase)
        self.button_right.grid(row=0,column=1)


        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)
        self.fig.autofmt_xdate()
        import matplotlib.dates as mdates
        self.ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')
        self.line, = self.ax.plot(tft[self.event_num],tf1[self.event_num],'.')


        self.canvas = FigureCanvasTkAgg(self.fig,master=master)
        self.canvas.show()
        self.canvas.get_tk_widget().grid(row=1,column=0)
        frame.grid(row=0,column=0)

    def decrease(self):
        self.event_num -= 1
        print self.event_num
        self.line, = self.ax.plot(tft[self.event_num],tf1[self.event_num],'.')
        self.canvas.draw()

    def increase(self):
        self.event_num += 1        
        print self.event_num
        self.line, = self.ax.plot(tft[self.event_num],tf1[self.event_num],'.')
        self.canvas.draw()

另一个(可能的)问题是数据被附加到绘图而不是被替换。有两种方法可以解决此问题:

Another (possible) problem is that the data gets appended to the plot instead of being replaced. There are two ways to fix this:


  1. 转动保持关闭: self.ax.hold(False) __ init __()之前的任何地方。

  2. 实际替换绘图数据:替换

  1. Turn hold off: self.ax.hold(False) somewhere in __init__() before you plot anything.
  2. Actually replace the plot data: Replace the line

self.line, = self.ax.plot(tft[self.event_num],tf1[self.event_num],'.')



< >

with

self.line.set_xdata(tft[self.event_num])
self.line.set_ydata(tf1[self.event_num])


这篇关于无法使用按钮和自定义数据更新Tkinter matplotlib图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆