2016-06-11 11 views
5

Ich versuche, ein 3-Zeilen-Zeitreihendiagramm basierend auf den folgenden Daten Long Dataframe, in einer Woche x Überladung Grafik erstellen, wo jeder Cluster eine andere Zeile ist.Zeitseriendiagramm mit Min/Max-Schattierung mit Seaborn

Ich habe mehrere Beobachtungen für jedes Paar (Cluster, Woche) (5 für jeden ATM, wird 1000 haben). Ich möchte, dass die Punkte auf der Linie der durchschnittliche Überlastwert für das spezifische Paar (Cluster, Woche) sind, und das Band die Min/Max-Werte davon sind.

derzeit mit dem folgende Stück Code, es zu zeichnen, aber ich bin keine Linien bekommen, wie ich weiß nicht, welche Einheit des aktuellen Datenrahmen angeben mit:

ax14 = sns.tsplot(data = long_total_cluster_capacity_overload_df, value = "Overload", time = "Week", condition = "Cluster") 

GIST Data

Ich habe das Gefühl, dass ich meinen Datenrahmen noch verändern muss, aber ich habe keine Ahnung wie. Sie sucht ein endgültigen Ergebnisse, die wie dies enter image description here

+0

Best I weit mit so kommen könnte, ist sns.pointplot verwenden und diese bekommen: https://gyazo.com/425b31b23f9d5009c12502f3113361ef –

+0

ehrlich, ist das Grundstück nicht genau das, was Sie suchen zum? Möchten Sie, dass die Interliner-Schattierung kleiner und die Kantenlinien dunkler sind? –

+0

Das sieht ähnlich aus wie ich es suche, aber wenn ich es erweitere, sind das tatsächliche Vertrauensintervalle (vertikale Linien für jeden Punkt), also keine durchgehenden Zeitreihen sozusagen. Und ja, ich möchte, dass die Inter-Line-Schattierung weniger ist. –

Antwort

3

this incredible answer Basiert weg, ich war in der Lage, einen Affen-Patch zu erstellen, um schön zu tun, was Sie suchen.

import pandas as pd 
import seaborn as sns  
import seaborn.timeseries 

def _plot_range_band(*args, central_data=None, ci=None, data=None, **kwargs): 
    upper = data.max(axis=0) 
    lower = data.min(axis=0) 
    #import pdb; pdb.set_trace() 
    ci = np.asarray((lower, upper)) 
    kwargs.update({"central_data": central_data, "ci": ci, "data": data}) 
    seaborn.timeseries._plot_ci_band(*args, **kwargs) 

seaborn.timeseries._plot_range_band = _plot_range_band 

cluster_overload = pd.read_csv("TSplot.csv", delim_whitespace=True) 
cluster_overload['Unit'] = cluster_overload.groupby(['Cluster','Week']).cumcount() 

ax = sns.tsplot(time='Week',value="Overload", condition="Cluster", unit="Unit", data=cluster_overload, 
       err_style="range_band", n_boot=0) 

Ausgang Graph: enter image description here

Beachten Sie, dass die schattierten Bereiche mit dem wahren Maximum und Minimum in der Liniengrafik in eine Reihe aufstellen!

Wenn Sie herausfinden, warum die Variable unit erforderlich ist, lassen Sie es mich bitte wissen.


Wenn Sie wollen, dass sie nicht alle in der gleichen Grafik dann:

import pandas as pd 
import seaborn as sns 
import seaborn.timeseries 


def _plot_range_band(*args, central_data=None, ci=None, data=None, **kwargs): 
    upper = data.max(axis=0) 
    lower = data.min(axis=0) 
    #import pdb; pdb.set_trace() 
    ci = np.asarray((lower, upper)) 
    kwargs.update({"central_data": central_data, "ci": ci, "data": data}) 
    seaborn.timeseries._plot_ci_band(*args, **kwargs) 

seaborn.timeseries._plot_range_band = _plot_range_band 

cluster_overload = pd.read_csv("TSplot.csv", delim_whitespace=True) 
cluster_overload['subindex'] = cluster_overload.groupby(['Cluster','Week']).cumcount() 

def customPlot(*args,**kwargs): 
    df = kwargs.pop('data') 
    pivoted = df.pivot(index='subindex', columns='Week', values='Overload') 
    ax = sns.tsplot(pivoted.values, err_style="range_band", n_boot=0, color=kwargs['color']) 

g = sns.FacetGrid(cluster_overload, row="Cluster", sharey=False, hue='Cluster', aspect=3) 
g = g.map_dataframe(customPlot, 'Week', 'Overload','subindex') 

, die die folgenden erzeugt, (Sie können natürlich mit dem Seitenverhältnis spielen, wenn man die Proportionen sind weg denken) enter image description here

+0

Vielen Dank für Ihre Hilfe, das funktioniert perfekt! Was die Einheit betrifft, werde ich viele ähnliche Plots für mein aktuelles Projekt erstellen, und wenn ich herausfinden werde, warum "Einheit" Pflicht ist, melde ich mich bei Ihnen. –

+0

Ich denke, die zweite Handlung ist viel besser. Gut gemacht. – Romain

+0

Danke für das Update! Ich hoffe, dass andere das auch nützlich finden. –

1

sehen ich dachte wirklich, dass ich in der Lage sein, es zu tun mit seaborn.tsplot. Aber es sieht nicht ganz richtig aus. Hier ist das Ergebnis, das ich mit Seaborn erhalten:

cluster_overload = pd.read_csv("TSplot.csv", delim_whitespace=True) 
cluster_overload['Unit'] = cluster_overload.groupby(['Cluster','Week']).cumcount() 
ax = sns.tsplot(time='Week',value="Overload", condition="Cluster", ci=100, unit="Unit", data=cluster_overload) 

Ausgänge:

enter image description here

Ich bin wirklich verwirrt, warum die unit Parameter ist notwendig, da mein Verständnis ist, dass alle Daten aggregiert basiert auf (time, condition) Die Seaborn Documentation definiert unit als

Field in the data DataFrame identifying the sampling unit (e.g. subject, neuron, etc.). The error representation will collapse over units at each time/condition observation. This has no role when data is an array.

ich bin Ich bin mir nicht sicher, was "kollabieren" bedeutet - vor allem, weil meine Definition es nicht zu einer erforderlichen Variablen machen würde.

Wie auch immer, hier ist der Ausgang, wenn Sie genau wollen, was Sie besprochen haben, nicht annähernd so schön. Ich bin nicht sicher, wie man in diesen Regionen manuell schattiert, aber teilen Sie es bitte, wenn Sie es herausfinden.

cluster_overload = pd.read_csv("TSplot.csv", delim_whitespace=True) 
grouped = cluster_overload.groupby(['Cluster','Week'],as_index=False) 
stats = grouped.agg(['min','mean','max']).unstack().T 
stats.index = stats.index.droplevel(0) 

colors = ['b','g','r'] 
ax = stats.loc['mean'].plot(color=colors, alpha=0.8, linewidth=3) 
stats.loc['max'].plot(ax=ax,color=colors,legend=False, alpha=0.3) 
stats.loc['min'].plot(ax=ax,color=colors,legend=False, alpha=0.3) 

Ausgänge: enter image description here

4

Ich habe endlich die gute alte plot mit einem Design (Subplots), die (für mich) besser lesbar scheint.

df = pd.read_csv('TSplot.csv', sep='\t', index_col=0) 
# Compute the min, mean and max (could also be other values) 
grouped = df.groupby(["Cluster", "Week"]).agg({'Overload': ['min', 'mean', 'max']}).unstack("Cluster") 

# Plot with sublot since it is more readable 
axes = grouped.loc[:,('Overload', 'mean')].plot(subplots=True) 

# Getting the color palette used 
palette = sns.color_palette() 

# Initializing an index to get each cluster and each color 
index = 0 
for ax in axes: 
    ax.fill_between(grouped.index, grouped.loc[:,('Overload', 'mean', index + 1)], 
        grouped.loc[:,('Overload', 'max', index + 1)], alpha=.2, color=palette[index]) 
    ax.fill_between(grouped.index, 
        grouped.loc[:,('Overload', 'min', index + 1)] , grouped.loc[:,('Overload', 'mean', index + 1)], alpha=.2, color=palette[index]) 
    index +=1 

enter image description here

+0

Vielen Dank dafür, ich werde ein ähnliches dazu machen, und konsultiere meinen Vorgesetzten, um zu sehen, auf welches wir uns einigen. Schnelle Frage zu diesem Thema: Aus irgendeinem Grund, wenn der DF im Speicher gespeichert wird, wird es nicht ausgeführt. KeyError bekommen: ('Overload', 'mean', 1). Wenn ich es jedoch in csv speichern und dann mit dem Parameter index_col = 0 erneut importieren, funktioniert es. Irgendeine Idee, warum das passiert? Danke noch einmal. –

+0

Danke für deinen Kommentar, ich bin mir sicher, dass dein Vorgesetzter auf meiner Seite sein wird ;-). Sag mir ! Keine Idee für den 'DataFrame' im Speicher gespeichert, da ich das Problem nicht reproduzieren kann. Es ist nicht mit dem Index verwandt, da das Beispiel ohne 'index_col = 0' ausgeführt werden kann. Ich denke, Sie sollten den "DataFrame" überprüfen (drucken). – Romain

+0

Ich habe mehrfach Druckanweisungen und in PyCharm verwendet. Ich verpasse definitiv etwas, aber ich kann kaum einen Eindruck von PyCharms Ausgabe machen https://gyazo.com/1a362bd8f2031f9bb88bed386888e7b6 (DF wird von CSV gelesen, DF1 ist der aus dem Speicher gespeicherte). Es ist jedoch sehr seltsam, als ob ich es speichern würde, und es wieder laden (mit delim = ',' und col_index = 0 als params), es funktioniert ... Ich melde mich morgen Abend, um Sie wissen zu lassen, welche Grafik mein Vorgesetzter dachte, war besser! Danke nochmal für die Hilfe. –