Zeichnen eines Diagramms mithilfe von Arrays

Nov 20 2020

Ich habe eine Reihe von Daten, die ich in einem Diagramm darstellen möchte. Ich habe eine Liste von Zeitstempeln, die ich pro Stunde gruppieren möchte, und dann möchte ich die Anzahl der Punkte pro Stunde in einem Liniendiagramm anzeigen (über einen Tag, wo ich Daten von mehreren Tagen habe, die ich in einem Diagramm pro Tag haben möchte ).

Ich habe den Wert der Punkte pro Stunde und ich habe die Stunden, an denen sie auftreten. Ich bekomme es nicht zum Laufen, dass es eine Linie in meinem Diagramm gibt und ich denke, ich vermisse eine einfache Lösung. Ich habe auch ein Bild gepostet, damit Sie die Ausgabe sehen können. Was ist der folgende Schritt, um die Linie anzuzeigen?

Ich habe folgenden Code:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import csv
from datetime import timedelta
import datetime as dt
 
data= pd.read_csv('test2.csv', header=0, index_col=None, parse_dates=True, sep=';', usecols=[0,1])
df=pd.DataFrame(data, columns=['Date', 'Time'])
df['DateTime'] = df['Date'] + df['Time']

#for date in df['DateTime']:


def RemoveMilliSeconds(x):
    return x[:-5]

df['Time'] = df['Time'].apply(RemoveMilliSeconds)

df['DateTime'] = df['Date'] + df['Time']
df['DateTime'] = pd.to_datetime(df['DateTime'], format="%Y:%m:%d %H:%M:%S")
df['TimeDelta'] = df.groupby('Date')['DateTime'].apply(lambda x: x.diff())

#print(df['TimeDelta'] / np.timedelta64(1, 'h'))
df['HourOfDay'] = df['DateTime'].dt.hour
df['Day'] = df['DateTime'].dt.day

grouped_df = df.groupby('Day')

for key, item in grouped_df:
    print(grouped_df.get_group(key)['HourOfDay'].value_counts(), "\n\n")


res=[]
for i in df['DateTime'].dt.hour:
    if i not in res:
        res.append(i)
print("enkele lijst:" + str(res))
#range = (0,24)
#bins = 2
#plt.hist(df['DateTime'].dt.hour, bins, range)

x=np.array([res])

y=np.array([df['HourOfDay'].value_counts()])
plt.plot(x,y)
plt.show()

#times = pd.DatetimeIndex(df.Time)
#grouped = df.groupby([times.hour])

Das Bild, das die Ausgabe zeigt

Meine Beispieldaten:

Date;Time
2020:02:13 ;12:39:02:913 
2020:02:13 ;12:39:42:915 
2020:02:13 ;13:06:20:718 
2020:02:13 ;13:18:25:988 
2020:02:13 ;13:34:02:835 
2020:02:13 ;13:46:35:793 
2020:02:13 ;13:59:10:659 
2020:02:13 ;14:14:33:571 
2020:02:13 ;14:25:36:381 
2020:02:13 ;14:35:38:342 
2020:02:13 ;14:46:04:006 
2020:02:13 ;14:56:57:346 
2020:02:13 ;15:07:39:752 
2020:02:13 ;15:19:44:868 
2020:02:13 ;15:32:31:438 
2020:02:13 ;15:44:44:928 
2020:02:13 ;15:56:54:453 
2020:02:13 ;16:08:21:023 
2020:02:13 ;16:19:17:620 
2020:02:13 ;16:29:56:944 
2020:02:13 ;16:40:11:132 
2020:02:13 ;16:49:12:113 
2020:02:13 ;16:57:26:652 
2020:02:13 ;16:57:26:652 
2020:02:13 ;17:04:22:092 
2020:02:17 ;08:58:08:562 
2020:02:17 ;08:58:42:545 

Antworten

Mr.T Nov 20 2020 at 11:51

Sie haben Ihre xy-Daten nicht so vorbereitet, dass matplotlibihre Beziehung verstanden wird.

Die einfache „Antwort“ wäre zu plotten resund df['HourOfDay'].value_counts()direkt gegeneinander:

#.....
#range = (0,24)
#bins = 2
#plt.hist(df['DateTime'].dt.hour, bins, range)

plt.plot(res, df['HourOfDay'].value_counts())
plt.show()

Die Beispielausgabe zeigt Ihnen jedoch das Problem:

matplotlibbestellt die x-Werte nicht für Sie (dies würde die Daten in einem anderen Kontext falsch darstellen). Also müssen wir dies tun, bevor wir planen:

#.....
#range = (0,24)
#bins = 2
#plt.hist(df['DateTime'].dt.hour, bins, range)

xy=np.stack((res, df['HourOfDay'].value_counts()))
xy = xy[:, np.argsort(xy[0,:])]
plt.plot(*xy)
plt.show()

Jetzt sind die x-Werte in der richtigen Reihenfolge und die y-Werte wurden mit ihnen in dem kombinierten xyArray sortiert , das wir zu diesem Zweck erstellt haben:

Natürlich wäre es besser vorbereiten resund df['HourOfDay'].value_counts()direkt, so dass wir sie zusammen keine kombinierten Arrays erstellen müssen , um zu sortieren. Da Sie keine Erklärung gegeben haben, was Ihr Code tun soll, können wir das Problem, das der Code erstellt hat, nur nachträglich beheben. Sie sollten ihn anders strukturieren, damit dieses Problem überhaupt nicht auftritt. Aber nur Sie können dies tun (oder Leute, die die Absicht Ihres Codes verstehen - ich nicht).

Ich schlage auch vor, einige Zeit mit den lehrreichen matplotlib-Tutorials zu verbringen - diese Zeit wird nicht verschwendet.

Update
Es scheint, als würden Sie versuchen, für jeden Tag eine Nebenhandlung zu erstellen und die Anzahl der Einträge pro Stunde zu zählen. Ich würde es so angehen (aber ich bin sicher, einige Panda-Experten haben bessere Möglichkeiten dafür):

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
 
#read your data and create datetime index
df= pd.read_csv('test1.txt', sep=";") 
df.index = pd.to_datetime(df["Date"]+df["Time"].str[:-5], format="%Y:%m:%d %H:%M:%S")

#group by date and hour, count entries
dfcounts = df.groupby([df.index.date, df.index.hour]).size().reset_index()
dfcounts.columns = ["Date", "Hour", "Count"]
maxcount = dfcounts.Count.max()

#group by date for plotting
dfplot = dfcounts.groupby(dfcounts.Date)

#plot each day into its own subplot
fig, axs = plt.subplots(dfplot.ngroups, figsize=(6,8))

for i, groupdate in enumerate(dfplot.groups):
    ax=axs[i]
    #the marker is not really necessary but has been added in case there is just one entry per day
    ax.plot(dfplot.get_group(groupdate).Hour, dfplot.get_group(groupdate).Count, color="blue", marker="o")
    ax.set_title(str(groupdate))
    ax.set_xlim(0, 24)
    ax.set_ylim(0, maxcount * 1.1)
    ax.xaxis.set_ticks(np.arange(0, 25, 2))

plt.tight_layout()
plt.show()

Beispielausgabe:

Update 2
Um sie in einzelne Figuren zu zeichnen, können Sie die Schleife ändern:

#...
dfplot = dfcounts.groupby(dfcounts.Date)

for groupdate in dfplot.groups:
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
    fig.suptitle("Date:"+str(groupdate), fontsize=16)

    #scaled for comparability among graphs
    ax1.plot(dfplot.get_group(groupdate).Hour, dfplot.get_group(groupdate).Count, color="blue", marker="o")
    ax1.set_xlim(0, 24)
    ax1.xaxis.set_ticks(np.arange(0, 25, 2))
    ax1.set_ylim(0, maxcount * 1.1)
    ax1.set_title("comparable version")

    #scaled to maximize visibility per day
    ax2.plot(dfplot.get_group(groupdate).Hour, dfplot.get_group(groupdate).Count, color="red", marker="x")
    ax2.set_xlim(0, 24)
    ax2.xaxis.set_ticks(np.arange(0, 25, 2))
    ax2.set_title("expanded version")
    
    plt.tight_layout()
    #save optionally 
    #plt.savefig("MyDataForDay"+str(groupdate)+".eps")

print("All figures generated")
plt.show()

Beispielausgabe für einen der Tage:

erstellt mit folgenden Testdaten:

Date;Time
2020:02:13 ;12:39:02:913 
2020:02:13 ;12:39:42:915 
2020:02:13 ;13:06:20:718 
2020:02:13 ;13:18:25:988 
2020:02:13 ;13:34:02:835 
2020:02:13 ;13:46:35:793 
2020:02:13 ;13:59:10:659 
2020:02:13 ;14:14:33:571 
2020:02:13 ;14:25:36:381 
2020:02:13 ;14:35:38:342 
2020:02:13 ;14:46:04:006 
2020:02:13 ;14:56:57:346 
2020:02:13 ;15:07:39:752 
2020:02:13 ;15:19:44:868 
2020:02:13 ;15:32:31:438 
2020:02:13 ;15:44:44:928 
2020:02:13 ;15:56:54:453 
2020:02:13 ;16:08:21:023 
2020:02:13 ;16:19:17:620 
2020:02:13 ;16:29:56:944 
2020:02:13 ;16:40:11:132 
2020:02:13 ;16:49:12:113 
2020:02:13 ;16:57:26:652 
2020:02:13 ;16:57:26:652 
2020:02:13 ;17:04:22:092 
2020:02:17 ;08:58:08:562 
2020:02:17 ;08:58:42:545 
2020:02:17 ;15:19:44:868 
2020:02:17 ;17:32:31:438 
2020:02:17 ;17:44:44:928 
2020:02:17 ;17:56:54:453 
2020:02:17 ;18:08:21:023 
2020:03:19 ;06:19:17:620 
2020:03:19 ;06:29:56:944 
2020:03:19 ;06:40:11:132 
2020:03:19 ;14:49:12:113 
2020:03:19 ;16:57:26:652 
2020:03:19 ;16:57:26:652 
2020:03:19 ;17:04:22:092 
2020:03:19 ;18:58:08:562 
2020:03:19 ;18:58:42:545