Mathplotlib axlar med datum och tid

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Mathplotlib axlar med datum och tid

Inlägg av Oltronix »

Försöker lära mig lite python, numpy, mathplotlib, PyQt, etc.
Följande får jag fungera

Kod: Markera allt

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime

# Converter function
datefunc = lambda x: mdates.date2num(datetime.strptime(x.decode('ascii'), '%Y-%m-%d-%H:%M:%S'))

def plot_data():
    file1='data4-test.log'
    date, x, y, z=np.loadtxt(file1,
                                 #delimiter=' ',
                                 #delimiter=19,
                                 converters={0: datefunc},
                                # converters={0: decode("utf-8")},    
                                 dtype=float,
                                 unpack=True)
    
    print('date:', type(date))
    print(date)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.set_xticks(date) # Tickmark + label at every plotted point
    pl=ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M:%S'))
    ax.grid(True)
    # Format the x-axis for dates (label formatting, rotation)
    fig.autofmt_xdate(rotation=45)
    fig.tight_layout()
    plt.plot_date(date, z,'go-', label='Tryck')
    plt.show()
    
if __name__ == '__main__':
    plot_data()
 
med följande indata:

Kod: Markera allt

2017-03-13-16:58:26 18.390253067 31.9744606018 1022.59570312
2017-03-13-16:58:27 18.1910896301 31.9562187195 1022.59130859
2017-03-13-16:58:28 18.7267665863 31.8102798462 1022.58642578
2017-03-13-16:58:29 18.2219963074 31.9562187195 1022.57739258

2017-03-13-16:58:34 18.5310401917 31.9744606018 1022.5546875
2017-03-13-16:58:35 18.5379066467 31.9927024841 1022.59692383
2017-03-13-16:58:36 17.562702179 31.8102798462 1022.60131836
2017-03-13-16:58:37 17.6039085388 31.9927024841 1022.59985352
2017-03-13-16:58:38 17.9129524231 31.9927024841 1022.5847168
2017-03-13-16:58:39 18.7439365387 31.8102798462 1022.60131836
2017-03-13-16:58:40 17.0132904053 31.8650054932 1022.59960938
2017-03-13-16:58:41 18.3559150696 32.0291900635 1022.57495117
2017-03-13-16:58:42 17.4390830994 31.9562187195 1022.58984375

2017-03-13-16:58:44 18.4486274719 31.9562187195 1022.60766602
2017-03-13-16:58:45 18.9946060181 31.9379768372 1022.60253906
Problemet är att min indata inte ser ut som ovan utan följande:

Kod: Markera allt

2017-03-13-16:58:26 18.390253067 31.9744606018 1022.59570312
2017-03-13-16:58:27 18.1910896301 31.9562187195 1022.59130859
2017-03-13 16:58:28 18.7267665863 31.8102798462 1022.58642578
2017-03-13 16:58:29 18.2219963074 31.9562187195 1022.57739258
...
Alltså inget "-" mellan datum och tid utan ett mellanslag. Jag har försökt med att ändra på olika "delimeters" och "converters", mm med dåligt resultat. Ofta mycket mystiga grafer.

Några tips?
Användarvisningsbild
hanpa
Utsparkad, på semester
Inlägg: 639
Blev medlem: 22 november 2016, 21:54:43
Ort: Hemort

Re: Mathplotlib axlar med datum och tid

Inlägg av hanpa »

Enklast är väl att scripta in ett "-" på förväntat ställe i ditt indata innan du kör programmet.
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: Mathplotlib axlar med datum och tid

Inlägg av Oltronix »

jo jag har tänkt på det men jag ville lära mig att hantera np.loadtext() sen är jag ganska envis ibland(alltid?)
Är det "sed" som du tycker är passande i detta fall?
Användarvisningsbild
hanpa
Utsparkad, på semester
Inlägg: 639
Blev medlem: 22 november 2016, 21:54:43
Ort: Hemort

Re: Mathplotlib axlar med datum och tid

Inlägg av hanpa »

Och du har provat att bara ändra formatet i datefunc?

Förstår inte exakt hur det fungerar men om du har en default delimiter så blir väl detta problem om du har samma inom datumet enligt ditt eget format. Går säkert att dela upp det i olika converters för datum och tid men annars kanske det funkar bara genom att ändra i datefunc.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Mathplotlib axlar med datum och tid

Inlägg av lillahuset »

Kan du inte bara läsa in en rad åt gången och modifiera den innan du tolkar den. Eftersom jag inte kan Python kan jag inte föreslå exakt hur men i C är det trivialt.
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Mathplotlib axlar med datum och tid

Inlägg av johano »

Du skriver att ditt indata inte har "-" mellan datum och tid, men ditt exempel ser ut att vara blandat.

Om det inte är "-" mellan så borde det väl bara vara att ändra datefunc?

Kod: Markera allt

datefunc = lambda x: mdates.date2num(datetime.strptime(x.decode('ascii'), '%Y-%m-%d %H:%M:%S'))
Om det kan vara blandat så får du nog först "preprocessa" strängen med t.ex. en regex så den ger en
konsekvent datumsträng som sedan kan parse:as av strptime

/j
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: Mathplotlib axlar med datum och tid

Inlägg av Oltronix »

Ofta(alltid?) i python, numpy läser man in alla värden till en vektor eller matris som man laborer med. (Det tar tid när jag läser in 50000 värden). Men det går säkert att läsa in en rad i taget och ändra mellanslag till något annat. Kan även pröva med att ändra delimeter mellan mätvärden till tex ",". Alt skriva in "-" mellan datum och tid när jag fyller på datafilen. Men men när man använder andras datafiler måste man filtera(scripta) om de använder "space" konsekvent.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Mathplotlib axlar med datum och tid

Inlägg av lillahuset »

Jag har skrivit ett flertal program som behandlar numeriska data i C. Relativt tidigt insåg jag att livet blir bra mycket bekvämare om man hanterar både decimalkomma och decimalpunkt. Enkelt tillägg i programmen.
Användarvisningsbild
hanpa
Utsparkad, på semester
Inlägg: 639
Blev medlem: 22 november 2016, 21:54:43
Ort: Hemort

Re: Mathplotlib axlar med datum och tid

Inlägg av hanpa »

Oltronix skrev:jo jag har tänkt på det men jag ville lära mig att hantera np.loadtext() sen är jag ganska envis ibland(alltid?)
Är det "sed" som du tycker är passande i detta fall?
Sed gör jobbet. Jag brukar blanda eftersom jag inte är jättebra på sed. Föredrar onliners med perl och lämpligt regext.
Är det engångsjobb kan man göra search & replace i emacs eller liknande.

Men har du provat att ändra formatet i första funktionen?
Användarvisningsbild
ahlsten
Inlägg: 659
Blev medlem: 12 november 2005, 00:24:14
Ort: Uppsala

Re: Mathplotlib axlar med datum och tid

Inlägg av ahlsten »

numpy-dokumentationen om loadtxt skrev:This function aims to be a fast reader for simply formatted files. The genfromtxt function provides more sophisticated handling of, e.g., lines with missing values.
Har jag underligt strukturerad data i text så föredrar jag att parsa raderna själv och stoppa i np.array i efterhand. Och kom ihåg att om du inte alltid behöver hela intervallet för att utföra beräkningarna, ibland behöver man bara ett delintervall i taget, så tjänar du massor med tid på att läsa ett stycke och låta python cacha resten av filen medan du räknar (man måste göra rätt tunga beräkningar för att vara slöare än diskaccess).
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Mathplotlib axlar med datum och tid

Inlägg av johano »

np.loadtxt ska ju kunna ta emot en 'generator' också, det öppnar ju för att "jit:a" in en liten 'fixar-funktion':

Kod: Markera allt

def file_process(filename):

    with open(filename, "r") as f:
        for line in f:
            yield line[:10]+"T"+line[11:]

datefunc = lambda x: mdates.date2num(datetime.strptime(x.decode('ascii'), '%Y-%m-%dT%H:%M:%S'))

def plot_data():
    file1='data4-test.log'
    date, x, y, z=np.loadtxt(file_process(file1),
                                 #delimiter=' ',
                                 #delimiter=19,
                                 converters={0: datefunc},
                                # converters={0: decode("utf-8")},    
                                 dtype=float,
                                 unpack=True)

   ...

/j
Användarvisningsbild
ahlsten
Inlägg: 659
Blev medlem: 12 november 2005, 00:24:14
Ort: Uppsala

Re: Mathplotlib axlar med datum och tid

Inlägg av ahlsten »

hanpa: loadtxt separerar kolumnerna innan det körs någon konvertering, så att låta delimitern ingå datatypen är lite besvärligt
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: Mathplotlib axlar med datum och tid

Inlägg av Oltronix »

Tja det ser som jag måste slå ihop mina första 2 kolummner med 'sed', 'regex' eller annat så att det går att konvertera till en float som datetime.strptime() kan tolka. Om jag inte nu kan få loadtxt() eller genfromtxt() att tolka 2 kolumner som 1. Att dela upp i datum och tid och använda tid som x-axeltick har jag försökt men inte heller lyckats med. Det blir mest underliga grafer. Men detta kan bero på att jag inte förstår hur xaxis.set_major_formatter(mdates.DateFormatter() och set_xticks() fungerar.

EDIT:
Nu fick jag till det utan 'sed', regx eller annan filterfunktion. Jag anropade 'genfromtxt' 2 ggr med olika 'delimiters'.

Kod: Markera allt

....
date= np.genfromtxt(file,
                              delimiter=19, 
                              usecols=(0),
                              converters={0: datefunc},
                              dtype=float,   
                              unpack=True)

x, y, z=np.genfromtxt(file,            
                               delimiter='  ',
                               usecols=(2,3,4),
                               dtype=float,
                               unpack=True)
.....
Klart att det sett snyggare ut med "converters={0,1: datefunc}" för att få med de två första kolummnera som en, men alla dydliga försök ger "syntax error"
Skriv svar