Seaborn的时间序列图,带有最小/最大阴影

2024-05-17 02:53:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图创建一个基于以下数据的3行时间序列图Long Dataframe,在一个Week x重载图中,每个集群是不同的行。

我对每个(集群,每周)对有多个观察(每个atm有5个,将有1000个)。我希望线上的点是特定(集群,周)对的平均过载值,频带是它的最小/最大值。

当前正在使用以下代码位来绘制它,但我没有得到任何行,因为我不知道要使用当前数据帧指定哪个单元:

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

GIST Data

我有一种感觉,我仍然需要重新塑造我的数据框架,但我不知道如何。寻找像这样的最终结果enter image description here


Tags: 数据代码data时间绘制集群long单元
3条回答

最后,我使用了一个设计(子块)看起来(在我看来)更具可读性的好的旧plot

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

this incredible answer的基础上,我创建了一个猴子补丁,可以很漂亮地完成您正在寻找的任务。

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)

输出图: enter image description here

请注意,阴影区域与线图中的真实最大值和最小值对齐!

如果您知道为什么需要unit变量,请告诉我。


如果不希望它们都在同一个图上,则:

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')

这将产生以下结果(如果您认为比例已禁用,则显然可以使用纵横比) enter image description here

我真的认为我可以用seaborn.tsplot来做。但看起来不太对劲。这是我和西伯恩的结果:

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)

输出:

enter image description here

我真的很困惑为什么unit参数是必要的,因为我的理解是,所有的数据都是基于(time, condition)聚合的,而Seaborn Documentationunit定义为

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.

我不确定“崩溃”的含义,特别是因为我的定义不会将其作为必需的变量。

不管怎么说,如果你想得到你所讨论的内容,这里有一个输出,而不是几乎那么漂亮。我不知道如何在这些地区手动阴影,但请分享,如果你想出来。

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)

输出:enter image description here

相关问题 更多 >