1

我展示了一个带有 chaco 和特征的情节。在 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
4

0 回答 0