matplotlib plot_date auseinanderziehen

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
pyront
User
Beiträge: 22
Registriert: Donnerstag 28. Juni 2018, 16:04

Huhu Gemeinde,

ich habe ein problem mit der darstellung meines plots(mit matplotlib).
Die werte, auf der zeitachse(ax.plot_date), sind ungleichmaessig verteilt,
sodass sich aufgrund der stauchung einige werte ueberlappen.
Ich moechte aber jeden wert erkennen koennen. Ich wuerde gerne eine art stretch einfuegen.
Das ganze sollte sekunden genau sein.(= keine ueberlappung)
Die Zeiitachsen liegen zwischen min 1 tag und ca. max 2 jahren. (druchnittslaenge 3 monate)
Die anzahl an werten liegt zwischen 1 und ca. max 10 000 (durchschnittsanzahl 350 werte)

Im bsp. sind es ca 2 monate und 50 werte.


ohne alles macht er woechentlich und ueberlappt.
Bild


wenn ich nach stunden einordne(ax.xaxis.set_major_locator(mdates.HourLocator(byhour=[0,1])))
sieht nur die einteilung anders aus immernoch ueberlappung
Bild


bei minuten( ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0,30])) )
gibt es den ticks fehler, wobei ich im beispiel nur ca 50 werte uebergebe.

Code: Alles auswählen

import sqlite3
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
import datetime
from datetime import datetime
import matplotlib.dates as dates
import matplotlib.dates as mdates

import numpy as np

con = sqlite3.connect('ba2c.db3')

def graph_data2(dbname):

    with con:

        try:

            #figsize=(16,6) ev einfuegen
            fig = plt.figure()
            fig, ax = plt.subplots()
            cur = con.cursor()

            for row in cur.execute('select * from {} where send="3294" or rec="3294";' .format(dbname) ):

                sqldate = row[12]
                sqlval = row[11]
                #datetime_object = datetime.strptime('2017-03-01T13:24:02','%Y-%m-%dT%H:%M:%S')
                datetime_object = datetime.strptime(sqldate,'%Y-%m-%dT%H:%M:%S')
                plt_dates1 = dates.date2num(datetime_object)
                ax.plot_date(plt_dates1, sqlval)

            ax.set_title('Plot a lot')
            plt.ylabel('Values')


            #fail section
            #hours = mdates.HourLocator()
            #ax.set_xlim(datemin, datemax)
            #ax.xaxis.set_minor_locator(hours)
            #ax.xaxis.set_major_locator(mdates.HourLocator(byhour=[0,1]))
            #ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0,30]))
            #ax.xaxis.set_major_locator(mdates.HourLocator(byhour=[0,1]))
            #fail   ax.axis('scaled')
            #minor_locator = AutoMinorLocator(2)
            #ax.xaxis.set_minor_locator(minor_locator)
            #hours = mdates.MinuteLocator()
            #ax.xaxis.set_minor_locator(hours)

            fig.autofmt_xdate()
            fig.savefig('z99.png')

        except:
            print ("Fehler in ")
            sys.exit()

graph_data2('tresor')

ich wuerd mich ueber hilfe freuen :)

ps. das bild hab ich auch nicht am rand abgeschnitten..
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@pyront: Mir ist nicht ganz klar was Du da erreichen möchtest. Auf der X-Achse im Schnitt 350 Werte nicht überlappend darstellen und auf die Sekunde genau identifizierbar, im schlimmsten Fall bis zu 10.000 Werte‽ Das halte ich nicht für möglich. Ausser das Diagramm wirklich so breit wie möglich zu machen, sehe ich da nicht was man tun könnte. Und für 10.000 Werte könnte auch DIN A4 quer noch zu wenig sein. Zwei Jahre sind 63.113.852 Sekunden. Selbst wenn man nur einen Zehntelmillimeter pro Sekunde auf der X-Achse verwendet, sind das über sechs Kilometer.

Plots (mit so vielen Werten) sind ja eigentlich auch dazu da eine Übersicht zu geben, und nicht jeden Einzelwert sauber ablesbar zu haben.

Aus jedem Datum einen eigenen Plot zu machen erscheint mir nicht sinnvoll. Mit den Farben kann doch niemand etwas anfangen‽

Beim SELECT solltest Du kein * verwenden, sondern die Spalten explizit benennen. Dann braucht man hinterher auch nicht mit magischen Indexwerten hantieren und bekommt von der Datenbank auch nur die Werte die man braucht. Du hast da ja mindestens 10 Werte in jedem Datensatz die Du einfach ignorierst.

Das der Tabellenname variabel ist, deutet auf ein Problem beim Entwurf der Datenbank hin.

Nummerieren von Funktionsnamen ist auch ein Warnzeichen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Jetzt hätte ich fast das ``except:`` übersehen: Das ist keine sinnvolle Ausnahmebehandlung. Lass das ``try``/``except`` einfach weg, dann bekommt man nicht nur mit wenn etwas nicht funktioniert, sondern auch warum.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
pyront
User
Beiträge: 22
Registriert: Donnerstag 28. Juni 2018, 16:04

hi und danke fuer die antworten....

leider mal wieder posting fehler von mir sorry .... merkt euch leute nur soviel code wie noetig posten!

aber das "Ausser das Diagramm wirklich so breit wie möglich zu machen, sehe ich da nicht was man tun könnte." wuerd ich dankend anehmen.
pyront
User
Beiträge: 22
Registriert: Donnerstag 28. Juni 2018, 16:04

ich konnte zwar kein asueinanderziehen finden, aber mit dem tip "Diagramm wirklich so breit wie möglich zu machen" wird die breite nun ab einen wert mit dem inhalt verbreitert.
Leider ist es so wie du es beschrieben hast. Bei sehr vielen werten im sekunden bereich, kann die fig garnicht breit genug sein.
Mein schlechter ausweg ist ein 2ter graph der die dates als strings plotet,

Bild

dankeee
Antworten