working dynamic graph using matplotlib

This commit is contained in:
Kienan Stewart 2014-12-10 22:38:40 -05:00
parent 290fb94a9d
commit bf5a6c6920
2 changed files with 107 additions and 7 deletions

View File

@ -1,6 +1,8 @@
<MyLabel@Label>:
text: 'Current Temperature: n/a'
# on_lastTemperature: self.update_current_temperature_label()
<PlotWidget@Image>:
allow_stretch: True
<MainWindow>:
label_wid: "Temperature Monitor"
@ -17,5 +19,5 @@
text: 'No File Chosen'
Label:
text: 'Data Source'
Label:
text: 'Graph placeholder'
PlotWidget:
id: 'mainplot'

106
main.py
View File

@ -1,13 +1,23 @@
import kivy
from kivy.app import App
from kivy.clock import Clock
import kivy.core.image
from kivy.core.image.img_pygame import ImageLoaderPygame
import kivy.graphics.texture
from kivy.logger import Logger
from kivy.properties import ObjectProperty, StringProperty
from kivy.properties import ListProperty, NumericProperty, ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.uix.label import Label
import kivy.lang
import numpy
import matplotlib
matplotlib.use('Agg')
import matplotlib.image
import matplotlib.pyplot
import Queue
import StringIO
import temp_log
import threading
@ -36,7 +46,8 @@ class MainApp(App):
class MainWindow(FloatLayout):
"""Main Window class"""
dataSource = StringProperty('/dev/ttyACM0')
lastTemperature = StringProperty('n/a')
lastTemperature = NumericProperty(-1000.)
lastTime = NumericProperty(-1.)
def update_last_temperature(self, dt):
global dataThreadDataQueue
@ -44,20 +55,48 @@ class MainWindow(FloatLayout):
try:
data = dataThreadDataQueue.get_nowait()
if data is not None:
self.lastTemperature = str(data['data']['temperature'])
Logger.debug('Data: ' + str(data))
if 'data' in data and 'temperature' in data['data']:
self.lastTemperature = float(data['data']['temperature'])
if 'time' in data:
self.lastTime = float(data['time'])
except Queue.Empty:
pass
def on_lastTemperature(self, instance, value):
Logger.debug('lastTemperature has changed to: ' + str(value))
children = self.children[:]
while children:
child = children.pop()
children.extend(child.children)
if child is self:
continue
try:
child.on_lastTemperature(instance, value)
except Exception, e:
#Logger.debug('Called on_lastTemperature for child: ' + str(child))
except AttributeError:
pass
except Exception, e:
Logger.exception(str(e))
def on_lastTime(self, instance, value):
Logger.debug('lastTime has changed to: ' + str(value))
children = self.children[:]
while children:
child = children.pop()
children.extend(child.children)
if child is self:
continue
#Logger.debug(str(child))
try:
child.on_lastTime(instance, value)
#Logger.debug('Called on_lastTime for child: ' + str(child))
except AttributeError, e:
pass
except Exception, e:
Logger.exception(str(e))
class MyLabel(Label):
@ -66,6 +105,65 @@ class MyLabel(Label):
self.text = 'Current temperature: ' + str(value)
class PlotWidget(Image):
def __init__(self, **kwargs):
super(Image, self).__init__(**kwargs)
self.data = numpy.array([], dtype=float);
self.lastTime = 0
self.lastTemperature = 0
self.figure = matplotlib.pyplot.figure()
self.plot_axes = self.figure.add_subplot(1, 1, 1)
self.plot_axes.hold(False)
self.plot_axes.set_ylabel('Temperature (deg C)')
self.plot_axes.set_xlabel('Time')
self.plot_axes.set_title('Recorded Temperature')
def update(self):
if not self.data.any():
return
#Logger.debug('self.data: ' + str(self.data))
#Logger.debug('self.data shape: ' + str(self.data.shape))
data = numpy.copy(self.data)
data = data.transpose()
#Logger.debug('transpoed data: ' + str(data))
#Logger.debug('transposed data shape: ' + str(data.shape))
t, temperature = numpy.split(data, 2, axis = 0)
#Logger.debug('time: ' + str(t[0]))
#Logger.debug('temperature: ' + str(temperature[0]))
self.plot_axes.plot(t[0], temperature[0])
image_data = StringIO.StringIO()
self.figure.savefig(image_data, format = 'png')
image_data.seek(0)
self.texture = ImageLoaderPygame(image_data, nocache = True).texture
def on_lastTemperature(self, instance, value):
self.lastTemperature = value
self.update_data()
def on_lastTime(self, instance, value):
self.lastTime = value
self.update_data()
def update_data(self):
if self.lastTime == 0 or self.lastTemperature == 0:
return
newpoint = numpy.array([(self.lastTime, self.lastTemperature)], dtype=float, ndmin = 2)
if not self.data.any():
self.data = newpoint
return
#Logger.debug('self.data: ' + str(self.data))
#Logger.debug('newpoint: ' + str(newpoint))
self.data = numpy.vstack((self.data, newpoint))
self.update()
#self.data = numpy.concatenate((self.data, newpoint), axis = 0)
#self.data = numpy.copy(self.data) # This will cause ObjectProperty to fire a change event
if __name__ == '__main__':
dataThread = threading.Thread(None, temp_log.threaded_reader, None, ['/dev/ttyACM0', dataThreadDataQueue, dataThreadCommandQueue])
MainApp().run()