チャコと特性のプロットを示します。Y 軸にはファイルからのデータを表示し、X 軸にはインデックスを表示します。タイマーを使用してデータを更新し、インデックスをインクリメントしますが、インデックスの代わりに日付と時刻を表示したいと思います。やり方がわかりません。説明するコードを示します。
import random
import wx
import time
from numpy import arange, array, hstack, random
# Enthought imports
from chaco.api import Plot, ArrayPlotData, ArrayDataSource, BarPlot, DataRange1D, \
LinearMapper, VPlotContainer, PlotAxis, \
FilledLinePlot, add_default_grids, PlotLabel
#from chaco.api import Plot, ArrayPlotData
from enable.component_editor import ComponentEditor
from numpy import linspace
from traits.api import Array, Bool, Callable, Enum, Float, HasTraits, \
Instance, Int, Trait
from traitsui.api import Group, HGroup, Item, View, spring, Handler
from pyface.timer.api import Timer
# Chaco imports
from chaco.chaco_plot_editor import ChacoPlotItem
from chaco.scales.api import CalendarScaleSystem
from chaco.scales_tick_generator import ScalesTickGenerator
import os
import matplotlib
import matplotlib.pyplot as plt
from datetime import *
#abrimos el fichero de configuracion
_fconf = open('graficas.cfg', 'r')
#obtenemos el directorio de los ficheros_udp
_directorio_in = _fconf.read(40)
#cerramos el fichero de ArithmeticError
_fconf.close()
class Viewer(HasTraits):
""" Esta clase solo contiene los dos arrays que serán actualizados por el controlador. La visualización / edicion para esta clase es una
grafica de chaco.
"""
index = Array
data = Array
# This "view" attribute defines how an instance of this class will
# be displayed when .edit_traits() is called on it. (See MyApp.OnInit()
# below.)
view = View(ChacoPlotItem("index", "data",
resizable=True,
x_label="Fecha",
y_label="Temperatura ($^\circ$C)C",
color="blue",
bgcolor="white",
border_visible=True,
border_width=1,
padding_bg_color="lightgray",
width=800,
height=300,
marker_size=2,
show_label=False),
resizable = True,
buttons = ["OK"],
width=800,
height=500,
title="CECAFLUX"
)
# Funcion encargada de la lectura de los datos del fichero de datos
def get_datos(obj):
datos_hoy = matplotlib.mlab.csv2rec(obj, delimiter=',')
ultimo_reg = datos_hoy[-1]
fecha = ultimo_reg['fecha']
t1 = ultimo_reg['t1']
t2 = ultimo_reg['t2']
t3 = ultimo_reg['t3']
t4 = ultimo_reg['t4']
t5 = ultimo_reg['t5']
f1 = ultimo_reg['f1']
f2 = ultimo_reg['f2']
p = ultimo_reg['peltier']
return (fecha, t1, t2, t3, t4, t5, f1, f2, p)
class Controller(HasTraits):
# A reference to the plot viewer object
viewer = Instance(Viewer)
# El numero maximo de puntos a acumular en la grafica en este caso 288, 24 horas si muestreamos a 5 minutos.
max_num_points = Int(288)
# The number of data points we have received; we need to keep track of
# this in order to generate the correct x axis data series.
num_ticks = Int(0)
def timer_tick(self, *args):
""" Callback function that should get called based on a wx timer
tick. This will generate a new random datapoint and set it on
the .data array of our viewer object.
"""
global _fconf
global _directorio_in
#obtenemos la fecha del sistema
ahora = datetime.utcnow()
anio = datetime.today().year
mes = datetime.today().month
diferencia = timedelta(days=1)
ayer = ahora - diferencia
directorio_fecha = "%d/%d/" % (anio, mes)
#print _directorio_in
directorio_aux = _directorio_in + directorio_fecha
#obtenemos todos los ficheros del directorio
ficheros = os.listdir(directorio_aux)
#ordenamos la lista de ficheros
ficheros.sort()
#obtenemos la longitud
longitud = len(ficheros)
#obtenemos el fichero ultimo que es el que esta abierto
fichero_ultimo = ficheros[longitud-1]
#abrimos el fichero y obtenemos el ultimo dato si ha sido modificado
ahora_noUTC = datetime.now()
dt=ahora_noUTC-timedelta(minutes=1)
path=os.path.join(directorio_aux,fichero_ultimo)
st=os.stat(path)
mtime=datetime.fromtimestamp(st.st_mtime)
print "mtime "+str(mtime)
print "dt "+str(dt)
if mtime>dt:
print "Fichero modificado"
# generamos los nuevos datos e incrementamos el contados de marcas del eje x
fecha, t1, t2, t3, t4, t5, f1, f2, peltier = get_datos(path) # identar
new_val = t1
self.num_ticks += 1
# grab the existing data, truncate it, and append the new point.
# This isn't the most efficient thing in the world but it works.
# almacena el dato actual en cur_data
cur_data = self.viewer.data
cur_data_x = self.viewer.index
# movemos el valor actual una posicion y apilamos el nuevo valor
new_data = hstack((cur_data[-self.max_num_points+1:], [new_val]))
# here I would like to show date and time instead of the index number
new_index = arange(self.num_ticks - len(new_data) + 1, self.num_ticks+0.01)
self.viewer.index = new_index
self.viewer.data = new_data
return
# wxApp used when this file is run from the command line.
class MyApp(wx.PySimpleApp):
def OnInit(self, *args, **kw):
viewer = Viewer()
controller = Controller(viewer = viewer)
# Pop up the windows for the two objects
#viewer.configure_traits()
viewer.edit_traits()
#controller.edit_traits()
# Set up the timer and start it up
self.setup_timer(controller)
return True
def setup_timer(self, controller):
# Create a new WX timer
timerId = wx.NewId()
self.timer = wx.Timer(self, timerId)
# Register a callback with the timer event
self.Bind(wx.EVT_TIMER, controller.timer_tick, id=timerId)
# Start up the timer! We have to tell it how many milliseconds
# to wait between timer events. For now we will hardcode it
# to be 100 ms, so we get 10 points per second.
# ejecutamos cada 1 minuto
self.timer.Start(60000.0, wx.TIMER_CONTINUOUS)
return
# This is called when this example is to be run in a standalone mode.
if __name__ == "__main__":
app = MyApp()
app.MainLoop()
# EOF