How to combine two subplots in one tkinter window? - python
I would like to display two matplotlib plots below each other in one tkinter window. I have needed two different codes so far. How can I combine the codes in one? I have created the desired result with powerpoint below. I have already tried it with subplot, unfortunately without success: plt.subplots(2,1, figsize=(20,10)) and plt.subplots(1,1, figsize=(20,10))
My first code:
# ___________________________________________________________________________
# Library
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
import tkinter as tk
import numpy as np
# ___________________________________________________________________________
# Carwash Array
Carwash_km = np.array([1,4,500,1500,2800,2960,2700,5,2000,2000,3100,4000,4150,4150])
Carwash_cost = np.array([5,1000,1000,2100,3000,3150,3150,20,50,600,3500,3800,3960,3700])
# Fuel Array
Fuel_km = np.array([2,5,600,2600,3900,3970,3800,6,3000,3000,4200,5000,5260,5260])
Fuel_cost = np.array([6,2000,2000,3200,4000,4260,4260,30,60,700,4600,4900,4070,4800])
# Maintenance Array
Maintenance_km = np.array([0,3,400,400,1700,1850,1600,4,1000,1000,2000,3000,3040,3040])
Maintenance_cost = np.array([4,500,500,1000,2000,2040,2040,10,40,500,2400,2700,2850,2600])
# ___________________________________________________________________________
# Main
Vis = tk.Tk()
Vis.title("Main") # titel
# ___________________________________________________________________________
# Plot
fig, ax = plt.subplots(1, 1, figsize=(20,5), facecolor = "white")
Plot_Carwash_cost = plt.bar(Carwash_km, Carwash_cost,
bottom=0,
color="#BDD7EE",
ec="black",
width=100,
label="Carwash_cost")
Plot_Carwash_cost2 = plt.bar(Maintenance_km, -Maintenance_cost,
bottom=-0,
color="#C5E0B4",
ec="black",
width=100,
label="Maintenance_cost")
Plot_Fuel = plt.scatter(Fuel_km, Fuel_cost,
marker="^",
s=150,
color="#C00000",
edgecolors="black",
zorder=3,
label="Fuel_cost")
ax.spines["bottom"].set_position("zero")
ax.spines["top"].set_color("none")
ax.spines["right"].set_color("none")
ax.spines["left"].set_color("none")
ax.tick_params(axis="x", length=20)
_, xmax = ax.get_xlim()
ymin, ymax = ax.get_ylim()
ax.set_xlim(-15, xmax)
ax.set_ylim(ymin, ymax+10) # legend
ax.text(xmax, -5, "km", ha="right", va="top", size=14)
plt.legend(ncol=5, loc="upper left")
plt.tight_layout()
# ___________________________________________________________________________
# Canvas, Toolbar
canvas = FigureCanvasTkAgg(fig, master=Vis)
canvas.draw() # TK-Drawingarea
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
canvas._tkcanvas.pack(side = tk.TOP, fill = tk.BOTH, expand = True)
toolbar = NavigationToolbar2Tk(canvas, Vis)
toolbar.update()
Vis.mainloop()
My second code:
# ___________________________________________________________________________
# Library
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
import tkinter as tk
import numpy as np
# ___________________________________________________________________________
# 1 Array
Beg1 = np.array([1,4,500,1500,2800,2960,2700,5,2000,2000,3100,4000,4150,4150])
End1 = np.array([2,5,600,2600,3900,3970,3800,6,3000,3000,4200,5000,5260,5260])
# 2 Array
Beg2 = np.array([5,1000,1000,2100,3000,3150,3150,20,50,600,3500,3800,3960,3700])
End2 = np.array([6,2000,2000,3200,4000,4260,4260,30,60,700,4600,4900,4070,4800])
# 3 Array
Beg3 = np.array([0,3,400,400,1700,1850,1600,4,1000,1000,2000,3000,3040,3040])
End3 = np.array([4,500,500,1000,2000,2040,2040,10,40,500,2400,2700,2850,2600])
# ___________________________________________________________________________
# detail
Vis2 = tk.Tk()
Vis2.title("detail") # titel
# ___________________________________________________________________________
# Plot
fig, ax = plt.subplots(2, 1, figsize=(20,10), facecolor = "white")
Plot_1 = plt.barh(len(Beg1)+np.arange(len(Beg2)), End2-Beg2+500,
left=Beg2,
height=0.9,
color='red',
alpha=0.5)
Plot_2 = plt.barh(range(len(Beg1)), End1-Beg1,
left=Beg1,
height=0.9,
color='#BDD7EE')
Plot_3 = plt.barh(len(Beg1)+len(Beg2)+np.arange(len(Beg3)), End3-Beg3+500,
left=Beg3,
height=0.9,
color="#C5E0B4")
plt.tight_layout()
# ___________________________________________________________________________
# Canvas, Toolbar
canvas = FigureCanvasTkAgg(fig, master = Vis2)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
canvas._tkcanvas.pack(side = tk.TOP, fill = tk.BOTH, expand = True)
toolbar = NavigationToolbar2Tk(canvas, Vis2)
toolbar.update()
Vis2.mainloop()
The short answer is to create two Frame widget, and have your FigureCanvasTkAgg master set to each Frame.
...
frame1 = tk.Frame(Vis)
frame2 = tk.Frame(Vis)
frame1.pack()
frame2.pack()
...
canvas = FigureCanvasTkAgg(fig, master = frame1)
...
canvas2 = FigureCanvasTkAgg(fig, master = frame2)
...
Vis.mainloop()
A better way is to create a class which inherits from Frame and handles the creation of Figure and NavigationToolBar. Depending on your need, it could be something like this:
from matplotlib.figure import Figure #use Figure instead of pyplot if you are embedding into tkinter
class GraphFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
super().__init__(master, **kwargs)
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
self.canvas = FigureCanvasTkAgg(self.fig, master=self)
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
self.toolbar = NavigationToolbar2Tk(self.canvas, self)
self.toolbar.update()
Then you can easily create new plotting areas under the same root window Vis:
Vis = tk.Tk()
graph1 = GraphFrame(Vis)
graph1.pack()
graph1.ax.bar(Carwash_km, Carwash_cost, ...)
graph1.ax.bar(Maintenance_km, -Maintenance_cost, ...)
graph1.ax.scatter(Fuel_km, Fuel_cost, ...)
graph2 = GraphFrame(Vis)
graph2.pack()
graph2.ax.barh(...)
graph2.ax.barh(...)
graph2.ax.barh(...)
Vis.mainloop()
#excuse me
#in
class GraphFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
super().__init__(master, **kwargs)
self.fig = Figure()
I think the correct sintax is :
class GraphFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
super().__init__(master, **kwargs)
self.fig = plt.figure()
Am I right?
Related
How to run a function concurrently with matplotlib animation?
I am building a GUI that takes in sensor data from the raspberry pi and displays it onto a window via matplotlib animation. The code works fine, except when being run on raspberry pi, the matplotlib animation takes some time to execute, which momentarily blocks the sensor reading GetCPM that I'm interested in. How can I make both these programs run simultaneously without one clogging the other, I've tried the multiprocessing library, but I can't seem to get it to work. Note: The sensor data that I'm plotting does not have to have a high sample rate, its the sensor that I'm displaying on label that does. Here is my code import matplotlib matplotlib.use("TkAgg") import numpy as np import tkinter as tk from tkinter import ttk from tkinter import * import math import datetime as dt import time from collections import Counter import random as rn from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk from matplotlib.figure import Figure import matplotlib.animation as animation from matplotlib import style import matplotlib.pyplot as plt import threading as td import multiprocessing as mp from multiprocessing import Process, Queue style.use('seaborn') limit = np.array([5]) # Initialize Pressure Figure fig1, ax1 = plt.subplots() fig2, ax2 = plt.subplots() x1, y1 = [], [] x2, y2 = [], [] TOT = [] CPM = 0 def GetValues(i, x, y, ax): volts2 = rn.uniform(3,6) x.append(dt.datetime.now().strftime('%H: %M: %S.%f')) y.append(float(volts2)) x = x[-50:] y = y[-50:] ax.clear() ax.plot(x, y, linewidth=1, color= 'k') ax.fill_between(x, y, limit[0], where=(y > limit[0]), facecolor='forestgreen', alpha=0.7, interpolate=True) ax.fill_between(x, y, limit[0], where=(y < limit[0]), facecolor='darkred', alpha=0.7, interpolate=True) ax.set_xticklabels([]) def animate(i, x, y, ax): volts = rn.uniform(2,8) x.append(dt.datetime.now().strftime('%H: %M: %S.%f')) y.append(float(volts)) x = x[-50:] y = y[-50:] ax.clear() ax.plot(x, y, linewidth=1, color= 'k') ax.fill_between(x, y, limit[0], where=(y > limit[0]), facecolor='forestgreen', alpha=0.7, interpolate=True) ax.fill_between(x, y, limit[0], where=(y < limit[0]), facecolor='darkred', alpha=0.7, interpolate=True) ax.set_xticklabels([]) def GetCPM(): global TOT, CPM temp = 1 # Test Case if temp == True: TOT.append(True) else: TOT.append(False) TOT = TOT[-2750:] count = Counter(TOT) CPM = count[True] return CPM class App(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) # If you want to customize the icon of the tk window, only accepts .ico #tk.Tk.iconbitmap(self, default="iconname.ico") tk.Tk.wm_title(self, "Pressure") container = tk.Frame(self) container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0,weight=1) container.grid_columnconfigure(0,weight=1) self.frames = {} frame = GUI(container, self) self.frames[GUI] = frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame(GUI) def show_frame(self,cont): frame = self.frames[cont] frame.tkraise() class GUI(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) canvas1 = FigureCanvasTkAgg(fig1, self) canvas1.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True) canvas2 = FigureCanvasTkAgg(fig2, self) canvas2.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True) #Initialize label as self. lbl = tk.Label(self, font = ('Sans Serif', 40, 'bold'), background = 'purple', foreground = 'White') lbl.place(relx=0.5, rely=0.5, anchor=CENTER) def update(): ll = GetCPM() lbl.config(text = "CPM = {}".format(ll)) print(dt.datetime.now().strftime('%H: %M: %S.%f')) lbl.after(20, update) update() # interval determines the speed at which data is recorded, 1000 = 1 second if __name__ == '__main__': app = App() t1 = mp.Process(target=GetCPM) t1.start() t1.join() ani_1 = animation.FuncAnimation(fig1, animate, interval = 500, fargs=(x1, y1, ax1)) ani_2 = animation.FuncAnimation(fig2, GetValues, interval = 500, fargs=(x2, y2, ax2)) app.mainloop()
Is it possible to control a matplotlib graph using a Tkinter Scrollbar?
I would like to make an equivalent of the function FuncAnimation from matplotlib.animation, in which I could control the current plotted data using the scrollbar. Say you have a data array which contains data points to be plotted at each time i. When using FuncAnimation, you first need to define a function ( here animate(i) ) which will be called for each time i = 1 to len(data[:,0]) : def animate(i): ax.plot(data[i,:]) anim = FuncAnimation(fig, animate, interval=100, frames=len(data[:,0])) plt.draw() plt.show() but you cannot control the time i, like with a play/stop functionality. What I would like to do is to call the function animate(i), with i being the position of the scrollbar. I found this example ( using the events from matplotlib: https://matplotlib.org/3.2.1/users/event_handling.html ) but the mpl_connect doesn't have a "scrollbar_event". import tkinter from random import randint import matplotlib as plt import numpy as np from matplotlib.backends.backend_tkagg import ( FigureCanvasTkAgg, NavigationToolbar2Tk) # Implement the default Matplotlib key bindings. from matplotlib.backend_bases import key_press_handler from matplotlib.figure import Figure root = tkinter.Tk() root.wm_title("Embedding in Tk") #create figure fig = Figure(figsize=(5, 4), dpi=100) ax = fig.add_axes([0,0,1,1]) ax.imshow(np.array([[0,10],[23,40]])) #create canvas with figure canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea. canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) def on_key_press(event): ax.clear() ax.imshow(np.array([[randint(0,30),randint(0,30)],[randint(0,30),randint(0,30)]])) canvas.draw_idle() key_press_handler(event, canvas) print("you pressed {}".format(event.key)) #connect canvas to event function canvas.mpl_connect("key_press_event", on_key_press) def _quit(): root.quit() # stops mainloop root.destroy() # this is necessary on Windows to prevent # Fatal Python Error: PyEval_RestoreThread: NULL tstate button = tkinter.Button(master=root, text="Quit", command=_quit) button.pack(side=tkinter.BOTTOM) tkinter.mainloop()
Actually the scroll functionality is given by matplotlib widgets !! The example below works fine : import matplotlib import tkinter as Tk import matplotlib.pyplot as plt from matplotlib.widgets import Slider from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from myPytHeader import * matplotlib.use('TkAgg') root = Tk.Tk() root.wm_title("Embedding in TK") fig = plt.Figure(figsize=(8, 6)) canvas = FigureCanvasTkAgg(fig, root) canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) nDt = nbLines("grid.dat") nDx = nbGridPoints("grid.dat") grid = np.zeros( (nDt,nDx) ) ; loadData("grid.dat", grid) valu = np.zeros( (nDt,nDx) ) ; loadData("valu.dat", valu) ax=fig.add_subplot(111) fig.subplots_adjust(bottom=0.25) ax_time = fig.add_axes([0.12, 0.1, 0.78, 0.03]) s_time = Slider(ax_time, 'Time', 0, nDt, valinit=0, valstep=1) def update(val): frame = int(s_time.val) ax.clear() ax.set(xlim=(-0.05, 1.05), ylim=(-0.05, 1.25)) ax.grid() ax.scatter(grid[frame,:], valu[frame,:], color='b', marker='.') fig.canvas.draw_idle() s_time.on_changed(update) Tk.mainloop()
After all these years I've found solutions to my problems here, I am in debt !!! Here is the final solution I came with. I hope it can be useful to someone someday somehow !! import matplotlib import numpy as np import tkinter as tk import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.widgets import Slider from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # load data nDt = 1000 nDx = 400 grd = np.zeros( (nDt,nDx) ) val = np.zeros( (nDt,nDx) ) for t in np.arange(nDt): for x in np.arange(nDx): grd[t,x] = x / nDx val[t,x] = (x / nDx) * (t/nDt) * np.sin(10 * 2*np.pi * (t-x)/nDt) matplotlib.use('TkAgg') root = tk.Tk() root.wm_title("Embedding in TK") fig = plt.Figure(figsize=(8, 6)) canvas = FigureCanvasTkAgg(fig, root) canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) ax=fig.add_subplot(111) fig.subplots_adjust(bottom=0.25) ax.set(xlim=(-0.05, 1.05), ylim=(-1.05, 1.05)) ax.grid() scat = ax.scatter(grd[0,:], val[0,:], color='b', marker='.') ax_time = fig.add_axes([0.12, 0.1, 0.78, 0.03]) s_time = Slider(ax_time, 'Time', 0, nDt, valinit=0, valstep=1) i_anim = 0 i_relative = 0 i_current = 0 def updateGraph(i): y_i = val[i,:] scat.set_offsets(np.c_[grd[i,:], y_i]) def updateFromAnim(i): global i_anim global i_current global i_relative i_anim = i i_current = i + i_relative s_time.set_val(i_current) updateGraph(i_current) def updateFromScroll(val): global i_anim global i_current global i_relative i_relative = int(s_time.val) - i_anim i_current = int(s_time.val) updateGraph(i_current) def onClick(): global anim_running if anim_running: anim.event_source.stop() anim_running = False else: anim.event_source.start() anim_running = True start_button = tk.Button(root, text="START/STOP", command=onClick) start_button.pack() anim_running = True anim = FuncAnimation(fig, updateFromAnim, interval=100, frames=nDt) s_time.on_changed(updateFromScroll) tk.mainloop()
How to show label into barh plot?
I would like to label my bars from the barh-plot. Therefore I have created a text numpy.array=Maintenance_component, which I want to display next to each bar. Unfortunately I did not find a quick solution. The desired result should be as follows. # ___________________________________________________________________________ # Library import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk import tkinter as tk import numpy as np # ___________________________________________________________________________ # Maintenance Array Maintenance_km = np.array([30,400,400,1700,1850,1600]) Maintenance_cost = np.array([500,500,1000,2000,2040, 1800]) Maintenance_component = np.array(['engine','spoiler','diffusor','radio','window','fueltank']) # ___________________________________________________________________________ # Main Vis = tk.Tk() Vis.title("Main") # titel # ___________________________________________________________________________ # Plot fig, ax = plt.subplots(1, 1, figsize=(20,5), facecolor = "white") Plot_Maintenace_cost2 = plt.barh(range(len(Maintenance_km)), Maintenance_km-Maintenance_cost+500, left=Maintenance_km, height=0.9, color='#C5E0B4') ax.spines["bottom"].set_position("zero") ax.spines["top"].set_color("none") ax.spines["right"].set_color("none") ax.spines["left"].set_color("none") ax.tick_params(axis="x", length=20) _, xmax = ax.get_xlim() ymin, ymax = ax.get_ylim() ax.set_xlim(-15, xmax) ax.set_ylim(ymin, ymax+10) # legend ax.text(xmax, -5, "km", ha="right", va="top", size=14) plt.legend(ncol=5, loc="upper left") plt.tight_layout() # ___________________________________________________________________________ # Canvas, Toolbar canvas = FigureCanvasTkAgg(fig, master=Vis) canvas.draw() # TK-Drawingarea canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True) canvas._tkcanvas.pack(side = tk.TOP, fill = tk.BOTH, expand = True) toolbar = NavigationToolbar2Tk(canvas, Vis) toolbar.update() Vis.mainloop()
Maintenance_km = np.array([30,400,400,1700,1850,1600]) Maintenance_cost = np.array([500,500,1000,2000,2040, 1800]) Maintenance_component = np.array(['engine','spoiler','diffusor','radio','window','fueltank']) fig, ax = plt.subplots() Plot_Maintenace_cost2 = plt.barh(range(len(Maintenance_km)), Maintenance_km-Maintenance_cost+500, left=Maintenance_km, height=0.9, color='#C5E0B4') for x,y,t in zip(Maintenance_km+Maintenance_km-Maintenance_cost+500,range(len(Maintenance_km)),Maintenance_component): ax.annotate(t, xy=(x,y))
How to use Line Collection with pyplot
When you run the code the error should be pretty obvious, just click your mouse in the black space and move it around. I'm not sure how the line segments are being created, I pulled it from the library and its kind of confusing. How can I get the line segments to plot along my scatter plot? When I looks at the segments array being generated I believe it’s creating pairs of x,x and y,y instead of x,y and x,y import tkinter as tk import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.collections import LineCollection from matplotlib.colors import ListedColormap import numpy as np import random class Mouse_Game: '''Creates a matplotlib canvas object that plot mouse coordinates when animated.''' def __init__(self, root, width=400, height=400): self.frame = tk.Frame(master=root) self.status = False self.fig = plt.Figure(dpi=100, facecolor='black') self.ax = self.fig.add_axes([0,0,1,1], fc='black') self.width = width self.height = height self.ax.axis('off') #set up the canvas object and bind commands self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame, resize_callback=self.configure) # A tk.DrawingArea. self.canvas.draw() self.canvas.get_tk_widget().pack(side='top', fill='both', expand=True) self.fig.canvas.mpl_connect('button_press_event', self.animate) self.fig.canvas.mpl_connect('motion_notify_event', self.motion) def animate(self, event): #Check if currently running if not self.status: self.status = True self.capture = np.array([(event.xdata, event.ydata)]*40) else: self.status = False #plot a line that follows the mouse around while self.status: self.ax.clear() self.ax.set_xlim(0, self.width) self.ax.set_ylim(0, self.height) x = self.capture[:,0] y = self.capture[:,1] ############################################################ points = self.capture.T.reshape(-1, 1, 2) segments = np.concatenate([points[:-1], points[1:]], axis=1) ########################################################### lc = LineCollection(segments, cmap='magma') lc.set_array(x) lc.set_linewidth(2) self.ax.add_collection(lc) self.ax.scatter(x, y, marker='o') self.fig.canvas.draw() self.fig.canvas.flush_events() def motion(self, event): if self.status: #Append mouse coordinates to array when the mouse moves self.capture = self.capture[1:40] self.capture = np.append(self.capture, [(event.xdata, event.ydata)], axis=0) def configure(self, event): #Used to adjust coordinate setting when the screen size changes self.width, self.height = self.canvas.get_width_height() def _quit(): #destroy window root.quit() root.destroy() root = tk.Tk() root.wm_title("Mouse Plot") MG = Mouse_Game(root=root) MG.frame.pack(expand=True, fill='both') button = tk.Button(root, text="Quit", command=_quit) button.pack(side='bottom', pady=10) tk.mainloop()
I'm not sure why you transpose the array. If you leave the transposition out, it'll work just fine points = self.capture.reshape(-1, 1, 2)
applying the matplotlib draw() freezes window solution to special case
Being new to python, I've come upon the matplotlib draw() freezes window problem myself and found the solution on this site: import matplotlib matplotlib.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg from matplotlib.figure import Figure from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import random import numpy as np import sys import Tkinter as tk import time def function1(fig, ax): ax.cla() color_grade_classes = ['#80FF00','#FFFF00','#FF8000', '#FF0000'] varsi = random.randint(1, 100) for colors, rows in zip(color_grade_classes, [3,2,1,0] ): indexs = np.arange(5) heights = [varsi,varsi/2,varsi/3,0,0] ax.bar(indexs, heights, zs = rows, zdir='y', color=colors, alpha=0.8) return fig class App(): def __init__(self): self.root = tk.Tk() self.root.wm_title("Embedding in TK") self.fig = plt.figure() self.ax = self.fig.add_subplot(111, projection='3d') self.ax.set_xlabel('X') self.ax.set_ylabel('Y') self.fig = function1(self.fig, self.ax) self.canvas = FigureCanvasTkAgg(self.fig, master=self.root) self.toolbar = NavigationToolbar2TkAgg( self.canvas, self.root ) self.toolbar.update() self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) self.label = tk.Label(text="") self.label.pack() self.update_clock() self.root.mainloop() def update_clock(self): self.fig = function1(self.fig,self.ax) self.canvas.show() self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) now = time.strftime("%H:%M:%S") self.label.configure(text=now) self.root.after(1000, self.update_clock) app=App() My problem is incorporating the following plotting code into it. It's not quite the same as the example given. Not sure how to split this up between the function definition and the class declaration. Can anyone help me on this? t0 = time.time() while time.time() - t0 <= 10: data = np.random.random((32, 32)) plt.clf() im = plt.imshow(data,cmap=cm.gist_gray, interpolation='none') plt.ion() cbar = plt.colorbar(im) cbar.update_normal(im) cbar.set_clim(0, np.amax(data)) plt.draw() time.sleep(0.5) plt.show(block=True)
this seems to work. Basically the __init__ part initialises the plot and draws the first "frame". Then the function self.update_clockis called every 1000ms, and that function calls function1() which generates new data and redraws the plot. I moved things around a bit because of the colorbar in your example, but the idea remains the same. import matplotlib matplotlib.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg from matplotlib.figure import Figure from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import matplotlib.cm as cm import random import numpy as np import sys import Tkinter as tk import time class App(): def __init__(self): self.root = tk.Tk() self.root.wm_title("Embedding in TK") self.fig = plt.figure() self.ax = self.fig.add_subplot(111) self.ax.set_xlabel('X') self.ax.set_ylabel('Y') data = np.random.random((32, 32)) im = self.ax.imshow(data,cmap=cm.gist_gray, interpolation='none') self.cbar = self.fig.colorbar(im) self.cbar.update_normal(im) self.cbar.set_clim(0, np.amax(data)) self.fig = self.function1(self.fig, self.ax) self.canvas = FigureCanvasTkAgg(self.fig, master=self.root) self.toolbar = NavigationToolbar2TkAgg( self.canvas, self.root ) self.toolbar.update() self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) self.label = tk.Label(text="") self.label.pack() self.update_clock() self.root.mainloop() def update_clock(self): self.fig = self.function1(self.fig,self.ax) self.canvas.show() self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) now = time.strftime("%H:%M:%S") self.label.configure(text=now) self.root.after(1000, self.update_clock) def function1(self, fig, ax): ax.cla() data = np.random.random((32, 32)) im = ax.imshow(data,cmap=cm.gist_gray, interpolation='none') self.cbar.update_normal(im) self.cbar.set_clim(0, np.amax(data)) return fig app=App()