trvrrp
trvrrp

Reputation: 554

Embed a pyplot in a tkinter window and update it

I am trying to write a program that has a pyplot (as in matplotlib.pyplot) within a Tkinter GUI which can be updated. Basically what I want is a program with a Tkinter interface to be displaying some data on a pyplot, then when the program gets some new data I want to update the pyplot to contain the new data.

Here is a minimal example:

import numpy as np
import Tkinter as tk

import matplotlib
matplotlib.use('TkAgg')

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt

root = tk.Tk()

fig = plt.figure(1)
t = np.arange(0.0,3.0,0.01)
s = np.sin(np.pi*t)
plt.plot(t,s)

canvas = FigureCanvasTkAgg(fig, master=root)
plot_widget = canvas.get_tk_widget()

def update():
    s = np.cos(np.pi*t)
    plt.plot(t,s)
    plt.draw()

plot_widget.grid(row=0, column=0)
tk.Button(root,text="Update",command=update).grid(row=1, column=0)
root.mainloop()

What I expect to happen is, for a window to pop up with a plot containing a sine wave and a button. When I press the button a cosine wave should appear on the plot.

What actually happens when I run the program is that a window pops up with a plot containing a sine wave and a button. However when I press the button nothing happens. The plot does not seem to be updating.

I'm probably making some newbie mistake but I can't find any examples online of doing this sort of thing. What is going wrong here and how would I get what I want?

Any help would be greatly appreciated!

Upvotes: 7

Views: 17182

Answers (1)

trvrrp
trvrrp

Reputation: 554

I figured it out, I need to call the draw() method on the figure's canvas attribute in order to get it to redraw, the corrected code is below. Also anyone who is encountering this or similar problems should probably look at matplotlib.animate if they need to be dynamically updating their pyplot

import numpy as np
import Tkinter as tk

import matplotlib
matplotlib.use('TkAgg')

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt

root = tk.Tk()

fig = plt.figure(1)
plt.ion()
t = np.arange(0.0,3.0,0.01)
s = np.sin(np.pi*t)
plt.plot(t,s)

canvas = FigureCanvasTkAgg(fig, master=root)
plot_widget = canvas.get_tk_widget()

def update():
    s = np.cos(np.pi*t)
    plt.plot(t,s)
    #d[0].set_ydata(s)
    fig.canvas.draw()

plot_widget.grid(row=0, column=0)
tk.Button(root,text="Update",command=update).grid(row=1, column=0)
root.mainloop()

Upvotes: 9

Related Questions