1

I am trying to update a plot within my GTK window with FunkAnimation. I want to click a button to start updating the plot which gets its data from a txt file. The txt-file gets updated constantly. The intent is to plot a temperature profile. Here is the simplified code:

import gtk
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
import matplotlib.animation as animation
from matplotlib import pyplot as plt

class MyProgram():
    def __init__(self):
        some_gtk_stuff
        self.signals = {
                'on_button_clicked': self.create_plot,
        }
        self.builder.connect_signals(self.signals)

        self.vbox = self.builder.get_object('vbox')

        self.figure = plt.figure()
        self.axis = self.figure.add_subplot(1,1,1)
        self.init = 0

    def create_plot(self):                        
        def update_plot(i):
            #read SampleData from txt File
            x = []
            y = []
            readFile = open('SampleData.txt', 'r')
            sepFile = readFile.read().split('\n')
            readFile.close()

            for data in sepFile:
                xy = data.split(',')
                x.append(int(x)
                y.append(int(y)

            self.axis.plot(x, y)

            if (self.init == 0):
                self.canvas = FigureCanvas(self.figure)
                self.vbox.pack_start(self.canvas)
                self.canvas.show()

            ani = animation.FuncAnimation(self.figure, update_plot, interval = 1000)
            self.canvas.draw()
            return ani

MyProgram()
gtk.main()

So I guess, the problem is, that the create_plot function is only called once. The plot window is created in the gui, but it doesn't get updated. I couldn't find a solution for my problem. Adding `return any' as suggested here didn't work.

You can see a working example here, the code is at the bottom of the page.

I'm aware that i have to implement something like threading for the logging and updating at a later time, but i don't even get it to work without.

Any Tips? :)

1 Answer 1

1

I think this is what you want to achieve. Note that I changed the way you read your file. The with open() as f: takes care of the file closing operation which you forgot. It is also possible to write the name of the signal handler in the builder file so one can simply say self.builder.connect(self) and omit the self.signals dicitonary.

import gtk
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
import matplotlib.animation as animation
from matplotlib import pyplot as plt

class MyProgram():
    def __init__(self):
        #some_gtk_stuff
        self.signals = {
                'on_button_clicked': self.create_plot,
        }
        self.builder.connect_signals(self.signals)

        self.vbox = self.builder.get_object('vbox')

        self.figure = plt.figure()
        self.axis = self.figure.add_subplot(1,1,1)
        self.canvas = None

    def create_plot(self, button):
        self.ani = animation.FuncAnimation(self.figure, self.update_plot, interval = 1000)


    def update_plot(self, i):
        #read SampleData from txt File
        x = []
        y = []
        with open('SampleData.txt') as f:
            x_raw, y_raw = f.readline().strip().split(',')
            x.append(int(x_raw))
            y.append(int(y_raw))

        self.axis.plot(x, y)

        if not self.canvas:
            self.canvas = FigureCanvas(self.figure)
            self.vbox.pack_start(self.canvas)
            self.canvas.show()

        self.canvas.draw()

MyProgram()
gtk.main()
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for you answer, but unfortunately this doesn't solve my problem. I edited my post to make it more obvious that i want to update the plot constantly. I also added a link with a working example that i'm trying to implement.
You are aware of the fact that you need to change SampleData.txt to see a change, right? It is also described the example that you linked: Any time there is an update, this will give us the new graph. If there is no update, then it will look the same.
Yes, i'm aware of that. The example code will update the plot automatically within the interval time. With the code i posted in OP and your code, the plot only updates after clicking the button again.
It works for me. Have you also added the self.ani = in front of the animation.FuncAnimation(...) so it does not get garbage collected?
Yes, i added the self.ani. It behaves very strange on my end. I just tried it again and on the 1st and 2nd click on the button it updates from the txt file and just does nothing. After clicking the button the 3rd time it updates automatically, but it seems like the FuncAnimation is started twice. my Code here
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.