15

I wanna update a matplotlib plot in a tkinter GUI. I tried to do so in the following code example.

import matplotlib
matplotlib.use('TkAgg')
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkinter as tk
import tkinter.ttk as ttk
import sys
class Application(tk.Frame):
 def __init__(self, master=None):
 tk.Frame.__init__(self,master)
 self.createWidgets()
 def createWidgets(self):
 fig=plt.figure(figsize=(8,8))
 ax=fig.add_axes([0.1,0.1,0.8,0.8],polar=True)
 canvas=FigureCanvasTkAgg(fig,master=root)
 canvas.get_tk_widget().grid(row=0,column=1)
 canvas.show()
 self.plotbutton=tk.Button(master=root, text="plot", command=self.plot)
 self.plotbutton.grid(row=0,column=0)
 def plot(self):
 for line in sys.stdout: #infinite loop, reads data of a subprocess
 theta=line[1]
 r=line[2]
 ax.plot(theta,r,linestyle="None",maker='o')
 plt.show(block=False)
 plt.pause(0.001)
 plt.cla()
 #here set axes
root=tk.Tk()
app=Application(master=root)
app.mainloop()

At the moment the problem is, that the ax object is not known in the plot function. If I try plot(self,canvas,ax) the GUI does not open. Only a figure that plots the data.

I wanna plot the data in the figure that is seen in the GUI. At least with a refresh rate round about 3-5Hz. Cause I am an absolute beginner this code solution is probably not the best way to do so. So I would be happy, if someone could show me a smarter solution.

Thanks!

asked Jun 11, 2015 at 7:26

4 Answers 4

7

Ok I could solve it myself. Here the solution:

import matplotlib
matplotlib.use('TkAgg')
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkinter as tk
import tkinter.ttk as ttk
import sys
class Application(tk.Frame):
 def __init__(self, master=None):
 tk.Frame.__init__(self,master)
 self.createWidgets()
 def createWidgets(self):
 fig=plt.figure(figsize=(8,8))
 ax=fig.add_axes([0.1,0.1,0.8,0.8],polar=True)
 canvas=FigureCanvasTkAgg(fig,master=root)
 canvas.get_tk_widget().grid(row=0,column=1)
 canvas.show()
 self.plotbutton=tk.Button(master=root, text="plot", command=lambda: self.plot(canvas,ax))
 self.plotbutton.grid(row=0,column=0)
 def plot(self,canvas,ax):
 for line in sys.stdout: #infinite loop, reads data of a subprocess
 theta=line[1]
 r=line[2]
 ax.plot(theta,r,linestyle="None",maker='o')
 canvas.draw()
 ax.clear()
 #here set axes
root=tk.Tk()
app=Application(master=root)
app.mainloop()
answered Jun 11, 2015 at 14:00
7

Thanks Abishek for taking the time to post the answer to your own problem.

I've just modified your answer a bit so that it runs as a standalone module without needing input from sys.stdout. Also changed the tkinter imports for python 2.7

import matplotlib
matplotlib.use('TkAgg')
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import Tkinter as tk # python 2.7
import ttk # python 2.7
import sys
class Application(tk.Frame):
 def __init__(self, master=None):
 tk.Frame.__init__(self,master)
 self.createWidgets()
 def createWidgets(self):
 fig=plt.figure(figsize=(8,8))
 ax=fig.add_axes([0.1,0.1,0.8,0.8],polar=True)
 canvas=FigureCanvasTkAgg(fig,master=root)
 canvas.get_tk_widget().grid(row=0,column=1)
 canvas.show()
 self.plotbutton=tk.Button(master=root, text="plot", command=lambda: self.plot(canvas,ax))
 self.plotbutton.grid(row=0,column=0)
 def plot(self,canvas,ax):
 c = ['r','b','g'] # plot marker colors
 ax.clear() # clear axes from previous plot
 for i in range(3):
 theta = np.random.uniform(0,360,10)
 r = np.random.uniform(0,1,10)
 ax.plot(theta,r,linestyle="None",marker='o', color=c[i])
 canvas.draw()
root=tk.Tk()
app=Application(master=root)
app.mainloop()
answered Nov 26, 2016 at 10:44
7

I don't know if it will be useful to anybody, but I updated the code to run with matplotlib 3.1.x+ and python 3.


import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk 
import numpy as np
class Application(tk.Frame):
 def __init__(self, master=None):
 tk.Frame.__init__(self,master)
 self.createWidgets()
 def createWidgets(self):
 fig=plt.figure(figsize=(8,8))
 ax=fig.add_axes([0.1,0.1,0.8,0.8],polar=True)
 canvas=FigureCanvasTkAgg(fig,master=root)
 canvas.get_tk_widget().grid(row=0,column=1)
 canvas.draw()
 self.plotbutton=tk.Button(master=root, text="plot", command=lambda: self.plot(canvas,ax))
 self.plotbutton.grid(row=0,column=0)
 def plot(self,canvas,ax):
 c = ['r','b','g'] # plot marker colors
 ax.clear() # clear axes from previous plot
 for i in range(3):
 theta = np.random.uniform(0,360,10)
 r = np.random.uniform(0,1,10)
 ax.plot(theta,r,linestyle="None",marker='o', color=c[i])
 canvas.draw()
root=tk.Tk()
app=Application(master=root)
app.mainloop()
answered Mar 9, 2022 at 15:44
0
0

With 3 extra code lines can animate the plot updates. To highlight the essence, I simplified the code by removing some pieces (like 'master=') related to multi-instance cases.

import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
import numpy as np
class Application(tk.Tk):
 def __init__(self):
 super().__init__()
 self.create_widgets()
 def create_widgets(self):
 fig = plt.figure(figsize=(8, 8))
 ax = plt.axes((0.1, 0.1, 0.8, 0.8), polar=True)
 canvas = FigureCanvasTkAgg(fig, self)
 canvas.get_tk_widget().grid(row=0, column=1)
 plotbutton = tk.Button(self, text="plot", command=lambda: self.auto_plot(ax))
 plotbutton.grid(row=0, column=0)
 def auto_plot(self, ax):
 c = ['r', 'b', 'g']
 for j in range(5):
 ax.clear()
 for i in range(3):
 theta = np.random.uniform(0, 360, 10)
 r = np.random.uniform(0, 1, 10)
 plt.polar(theta, r, linestyle="None", marker='o', color=c[i])
 plt.draw()
 self.after(500) # display plot keeping button responsive
 self.update() # redraw plot
Application().mainloop()
answered Dec 2, 2023 at 18:43

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.