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!
3 Answers
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() 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() 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()