I have an application that should get data from a sensor into a live graph, a subplot that is added into a Figure. I have now a problem after adding the subplot that I don't know how to change the plot parameters as xlabel, ylabel. This works if I import plt, but not if I import a Figure that will be further added to the window in Tkinter.
#file livegraph.py
import matplotlib.animation as animation
import datetime
#this is a draft for the liveGraph class
#the objective is to get live data from a sensor
class liveGraph:
#by default define the interval as being 1000 mSec
intervalAnim = 1000
def __init__(self,fig):
self.xax = 0
self.xs = []
self.ys = []
self.ax = fig.add_subplot(111)
self.ax.set_xlabel('teeeest')
#fig.title('Graph test')
#fig.set_xlabel("Time")
#fig.ylabel("% SMS")
self.anim = animation.FuncAnimation(fig, self.animate, interval = self.intervalAnim)
def animate(self,i):
self.xs.append(self.xax)
self.ys.append(datetime.datetime.now().second)
self.xax+=1
self.ax.clear()
self.ax.plot(self.xs,self.ys)
if self.xax > 90:
self.anim.event_source.stop()
from tkinter import *
from matplotlib import style
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from livegraph import liveGraph
# Define the main_screen as a tkinter
app_screen = Tk() # create a GUI window
app_screen.geometry("1920x1080") # set the configuration of GUI window
app_screen.resizable(width=True,height=True)
app_screen.title("Testare izolator") # set the title of GUI window
style.use('bmh')
#figure represents the graphic part of the system
figure = Figure(figsize=(10, 5), facecolor='white',frameon=True)
figure.suptitle('This is the figure title', fontsize=12)
#figure.add_gridspec(10,10)
#this are some parameters that I can easily change if I am using plt
# plt.title('Graph test')
#plt.xlabel("Time")
#plt.ylabel("% SMS")
#x = [ 0, 1, 2, 3, 4 ]
#y = [ 0, 1, 2, 3, 4 ]
#lines = plt.plot(x, y)
#plt.grid()
#plt.axis([0,10,0,10])
#plt.setp(lines, color= "b")
canvas = FigureCanvasTkAgg(figure, app_screen)
canvas.get_tk_widget().pack(side=TOP, anchor =NW, padx=100, pady=10)
newAnimation = liveGraph(figure)
app_screen.mainloop() # start the GUI
You should use self.ax.
to add elements
self.ax.set_xlabel('teeeest')
self.ax.set_title('Graph test')
self.ax.set_xlabel("Time")
self.ax.set_ylabel("% SMS")
but then there is other problem because self.ax.clear()
removes these elements.
First method:
If you use self.ax.clear()
then you remove labels and you have to put labels again and again
def animate(self, i):
self.xs.append(self.xax)
#self.ys.append(datetime.datetime.now().second)
self.ys.append(random.randint(0, 10))
self.xax += 1
self.ax.clear()
self.ax.plot(self.xs,self.ys)
if self.xax > 90:
self.anim.event_source.stop()
self.ax.set_xlabel('teeeest')
self.ax.set_title('Graph test')
self.ax.set_xlabel("Time")
self.ax.set_ylabel("% SMS")
Second method:
To add elements only once you have to remove self.ax.clear()
and instead of plot()
you should create empty plot in `init
self.ax = fig.add_subplot(111)
self.ax.set_xlabel('teeeest')
self.ax.set_title('Graph test')
self.ax.set_xlabel("Time")
self.ax.set_ylabel("% SMS")
self.line, = self.ax.plot([], [])
and in animation use set_data()
to update data in existing plot
self.line.set_data(self.xs, self.ys)
but it will not rescale plot and you will have to do it manually (if you want to rescale it)
self.ax.relim() # recalculate limits
self.ax.autoscale_view(True,True,True) # rescale using limits
Full code for first method
import matplotlib.animation as animation
import datetime
import random
#this is a draft for the liveGraph class
#the objective is to get live data from a sensor
class liveGraph:
#by default define the interval as being 1000 mSec
intervalAnim = 1000
def __init__(self, fig):
self.xax = 0
self.xs = []
self.ys = []
self.ax = fig.add_subplot(111)
self.ax.set_xlabel('teeeest')
self.anim = animation.FuncAnimation(fig, self.animate, interval=self.intervalAnim)
def animate(self, i):
self.xs.append(self.xax)
#self.ys.append(datetime.datetime.now().second)
self.ys.append(random.randint(0, 10))
self.xax += 1
self.ax.clear()
self.ax.plot(self.xs,self.ys)
if self.xax > 90:
self.anim.event_source.stop()
self.ax.set_title('Graph test')
self.ax.set_xlabel("Time")
self.ax.set_ylabel("% SMS")
from tkinter import *
from matplotlib import style
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
#from livegraph import liveGraph
# Define the main_screen as a tkinter
app_screen = Tk() # create a GUI window
app_screen.geometry("1920x1080") # set the configuration of GUI window
app_screen.resizable(width=True, height=True)
app_screen.title("Testare izolator") # set the title of GUI window
style.use('bmh')
#figure represents the graphic part of the system
figure = Figure(figsize=(10, 5), facecolor='white', frameon=True)
figure.suptitle('This is the figure title', fontsize=12)
#figure.add_gridspec(10,10)
#this are some parameters that I can easily change if I am using plt
#plt.title('Graph test')
#plt.xlabel("Time")
#plt.ylabel("% SMS")
#x = [ 0, 1, 2, 3, 4 ]
#y = [ 0, 1, 2, 3, 4 ]
#lines = plt.plot(x, y)
#plt.grid()
#plt.axis([0,10,0,10])
#plt.setp(lines, color= "b")
canvas = FigureCanvasTkAgg(figure, app_screen)
canvas.get_tk_widget().pack(side=TOP, anchor=NW, padx=100, pady=10)
newAnimation = liveGraph(figure)
#canvas.draw()
app_screen.mainloop() # start the GUI
Full code for second method
import matplotlib.animation as animation
import datetime
import random
#this is a draft for the liveGraph class
#the objective is to get live data from a sensor
class liveGraph:
#by default define the interval as being 1000 mSec
intervalAnim = 1000
def __init__(self, fig):
self.xax = 0
self.xs = []
self.ys = []
self.ax = fig.add_subplot(111)
self.ax.set_xlabel('teeeest')
self.ax.set_title('Graph test')
self.ax.set_xlabel("Time")
self.ax.set_ylabel("% SMS")
# create empty plot at start
self.line, = self.ax.plot([], [])
self.anim = animation.FuncAnimation(fig, self.animate, interval=self.intervalAnim)
def animate(self, i):
self.xs.append(self.xax)
#self.ys.append(datetime.datetime.now().second)
self.ys.append(random.randint(0, 2))
self.xax += 1
# update data in existing plot
self.line.set_data(self.xs, self.ys)
# rescale plot (if you need it)
self.ax.relim() # recalculate limits
self.ax.autoscale_view(True,True,True) # rescale using limits
if self.xax > 90:
self.anim.event_source.stop()
from tkinter import *
from matplotlib import style
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
#from livegraph import liveGraph
# Define the main_screen as a tkinter
app_screen = Tk() # create a GUI window
app_screen.geometry("1920x1080") # set the configuration of GUI window
app_screen.resizable(width=True, height=True)
app_screen.title("Testare izolator") # set the title of GUI window
style.use('bmh')
#figure represents the graphic part of the system
figure = Figure(figsize=(10, 5), facecolor='white', frameon=True)
figure.suptitle('This is the figure title', fontsize=12)
#figure.add_gridspec(10,10)
#this are some parameters that I can easily change if I am using plt
#plt.title('Graph test')
#plt.xlabel("Time")
#plt.ylabel("% SMS")
#x = [ 0, 1, 2, 3, 4 ]
#y = [ 0, 1, 2, 3, 4 ]
#lines = plt.plot(x, y)
#plt.grid()
#plt.axis([0,10,0,10])
#plt.setp(lines, color= "b")
canvas = FigureCanvasTkAgg(figure, app_screen)
canvas.get_tk_widget().pack(side=TOP, anchor=NW, padx=100, pady=10)
newAnimation = liveGraph(figure)
#canvas.draw()
app_screen.mainloop() # start the GUI