2016-11-01 4 views
14

Wie kann ich ein ähnliches timewheel mit Anmelde-/Abmeldeereigniszeiten erstellen? Konkret versuchen, die durchschnittliche An-/Abmeldezeit, die mit dem Wochentag korreliert ist, im Zeitrad zu korrelieren? Das Bild unten ist ein Beispiel, aber ich suche nach Zeiten, die rund um die Uhr mit Tagen der Woche gehen, wo die Zeiten jetzt im Bild sind. Ich habe Python für mich verfügbar und Datensätze, die Anmeldezeiten enthalten. Ich möchte auch Farben mit Benutzertypen wie Admins gegen normale Benutzer oder etwas dieser Art korrelieren. Irgendwelche Gedanken darüber, wie das zu erreichen wäre, wären großartig.Time Wheel in python3 pandas

Einige Beispieldaten unter in einem Pandas Datenrahmen

df:

TimeGenerated  EventID Username Message 
2012-04-01 00:00:13 4624  Matthew This guy logged onto the computer for the first time today 
2012-04-01 00:00:14 4624  Matthew This guy authenticated for some stuff 
2012-04-01 00:00:15 4624  Adam  This guy logged onto the computer for the first time today 
2012-04-01 00:00:16 4624  James  This guy logged onto the computer for the first time today 
2012-04-01 12:00:17 4624  Adam  This guy authenticated for some stuff 
2012-04-01 12:00:18 4625  James  This guy logged off the computer for the last time today 
2012-04-01 12:00:19 4624  Adam  This guy authenticated for some stuff 
2012-04-01 12:00:20 4625  Adam  This guy logged off the computer for the last time today 
2012-04-01 12:00:21 4625  Matthew This guy logged off the computer for the last time today 

Time Wheel

enter image description here

+0

Ist dies nicht genug ist Esprits zu starten, kann ich einige Daten aufzuräumen morgen @https: //stackoverflow.com/users/3877338/johne – johnnyb

+0

Vielleicht [diese] (https: //stackoverflow.com/a/25266569/3941704), von @Weir_Doe, eine Quelle der Inspiration sein? –

+0

Sie können solch ein Diagramm aus konzentrischen Donut-Diagrammen erstellen, wie hier: https://stackoverflow.com/questions/33019879/hierarchic-pie-donut-chart-from-pandas-dataframe-using-bokeh-or-matplotlib –

Antwort

12

Grundsätzlich benötigen Sie 2 disjunkte Aufgaben:

  • einer Häufigkeitstabelle erstellen Sie
  • definieren eine Funktion zur Visualisierung werden eine bestimmte Tabelle

Für die erste Aufgabe zu visualisieren, ich nehme an, Sie mit Wochentagen und Stunden nur eine Pivot-Tabelle benötigen. Ich erzeuge ein zufälliges:

import pandas as pd 
import matplotlib.pyplot as plt 
import numpy as np 
import pandas as pd 
import matplotlib as mpl 
import matplotlib.cm as cm 
import calendar 

# generate the table with timestamps 
np.random.seed(1) 
times = pd.Series(pd.to_datetime("Nov 1 '16 at 0:42") + pd.to_timedelta(np.random.rand(10000)*60*24*40, unit='m')) 
# generate counts of each (weekday, hour) 
data = pd.crosstab(times.dt.weekday, times.dt.hour.apply(lambda x: '{:02d}:00'.format(x))).fillna(0) 
data.index = [calendar.day_name[i][0:3] for i in data.index] 
print(data.T) 

Es sieht so aus. Jede Nummer ist ein Zähler von Anmeldungen zu dieser Zeit:

 Mon Tue Wed Thu Fri Sat Sun 
col_0         
00:00 55 56 67 60 60 62 45 
01:00 51 65 70 65 60 59 40 
02:00 47 76 67 68 61 63 51 
.... 

Jetzt wollen wir das Rad für diese Tabelle zeichnen! Es besteht aus mehreren Kreisdiagramme:

# make a heatmap building function 
def pie_heatmap(table, cmap=cm.hot, vmin=None, vmax=None,inner_r=0.25, pie_args={}): 
    n, m = table.shape 
    vmin= table.min().min() if vmin is None else vmin 
    vmax= table.max().max() if vmax is None else vmax 

    centre_circle = plt.Circle((0,0),inner_r,edgecolor='black',facecolor='white',fill=True,linewidth=0.25) 
    plt.gcf().gca().add_artist(centre_circle) 
    norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax) 
    cmapper = cm.ScalarMappable(norm=norm, cmap=cmap) 
    for i, (row_name, row) in enumerate(table.iterrows()): 
     labels = None if i > 0 else table.columns 
     wedges = plt.pie([1] * m,radius=inner_r+float(n-i)/n, colors=[cmapper.to_rgba(x) for x in row.values], 
      labels=labels, startangle=90, counterclock=False, wedgeprops={'linewidth':-1}, **pie_args) 
     plt.setp(wedges[0], edgecolor='white',linewidth=1.5) 
     wedges = plt.pie([1], radius=inner_r+float(n-i-1)/n, colors=['w'], labels=[row_name], startangle=-90, wedgeprops={'linewidth':0}) 
     plt.setp(wedges[0], edgecolor='white',linewidth=1.5) 



plt.figure(figsize=(8,8)) 
pie_heatmap(data, vmin=-20,vmax=80,inner_r=0.2) 

plt.show(); 

Time wheel Ich hoffe, das Ihnen hilft.

+0

Kannst du 'plt.setp (pie, width = width, edgecolor = 'white')' hinzufügen, um es gleichmäßig aussehen zu lassen besser? [Verweislink] (https: // stackoverflow.com/Fragen/44153457/Doppel-Donut-Diagramm-in-Matplotlib) –

+1

@UdayrajDeshmukh, fühlen sich frei, die Antwort zu bearbeiten! –

+0

Danke. Ich habe den inneren Kreis hinzugefügt und die Linienbreite erhöht. Jetzt ist es viel schöner und lesbarer! –

6

Ausgehend von der Datengenerierung aus @ DavidDales Antwort kann eine pcolormesh Darstellung der Tabelle auf einer polaren Achse gezeichnet werden. Dies würde direkt die gewünschte Handlung ergeben.

import pandas as pd 
import matplotlib.pyplot as plt 
import numpy as np 
import calendar 

# generate the table with timestamps 
np.random.seed(1) 
times = pd.Series(pd.to_datetime("Nov 1 '16 at 0:42") + 
        pd.to_timedelta(np.random.rand(10000)*60*24*40, unit='m')) 
# generate counts of each (weekday, hour) 
data = pd.crosstab(times.dt.weekday, 
        times.dt.hour.apply(lambda x: '{:02d}:00'.format(x))).fillna(0) 
data.index = [calendar.day_name[i][0:3] for i in data.index] 
data = data.T 

# produce polar plot 
fig, ax = plt.subplots(subplot_kw=dict(projection='polar')) 
ax.set_theta_zero_location("N") 
ax.set_theta_direction(-1) 

# plot data 
theta, r = np.meshgrid(np.linspace(0,2*np.pi,len(data)+1),np.arange(len(data.columns)+1)) 
ax.pcolormesh(theta,r,data.T.values, cmap="Reds") 

# set ticklabels 
pos,step = np.linspace(0,2*np.pi,len(data),endpoint=False, retstep=True) 
pos += step/2. 
ax.set_xticks(pos) 
ax.set_xticklabels(data.index) 

ax.set_yticks(np.arange(len(data.columns))) 
ax.set_yticklabels(data.columns) 
plt.show() 

enter image description here