简体   繁体   中英

how to make min-max-mean lineplot on time series in matplotlib?

In my experiment, I want to see rolling correlation on two columns of time series data which is on a weekly basis. I am able to find rolling correlation by week by using pandas.rolling() , but I want to add min , max , mean of rolling correlation in the plot. By doing that, I am hoping I could see how rolling correlation moves each year. I don't know how should I add max , min , mean of rolling correlation in the plot. Does anyone know the possible way of doing this in matplotlib ? Any idea to make this happen easily?

current attempt :

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

url = "https://gist.github.com/adamFlyn/4bce87f36bb7caca309f8ed6e423e939#file-corr_data-csv"
df = pd.read_csv(url)
df['Date'] = pd.to_datetime(df['Date'])
df['week'] = df['Date'].dt.isocalendar().week
df['year'] = df['Date'].dt.year
df['week'] = df['Date'].dt.strftime('%W').astype('uint8')

def find_corr(x):
    dfc = df.loc[x.index]
    tmp = dfc.iloc[:, [1,2]].corr()
    tmp = tmp.iloc[0,1]
    return tmp

roll_windows_ls = [4,8,12,16]
for i in roll_windows_ls:
    df['corr'] = df['week'].rolling(i).apply(find_corr)
    fig, ax = plt.subplots(figsize=(11, 6), dpi=144)
    cmap = plt.get_cmap("tab10")
    for j,y in enumerate(df['year'].unique()):
        tmp = df[df['year'] == y]
        ax.plot(tmp['week'], tmp['corr'], color=cmap(j), label=y)

plt.show()
plt.close()

current output :

here is one of the output that I got:

在此处输入图像描述

based on this attempt, how could we add min, max, mean lineplot of rolling correlation in the plot? Is there any way of doing this in matplotlib ? any idea?

desired output :

This is my example plot where I want to have min, max, mean of rolling correlation in my above attempt:

在此处输入图像描述

Is there any way to get desired plot in matplotlib? can anyone suggest possible way of doing this? Thanks

Here's an example using fill_between to fill the area between min and max, and then separately plotting the mean and the lines for the recent years (year > 2017):

import matplotlib as mpl

...

for i in roll_windows_ls:
    df['corr'] = df['week'].rolling(i).apply(find_corr)
    fig, ax = plt.subplots(figsize=(11, 6), dpi=144)

    # 1. Plot min, max, mean
    # 1.0. Aggregate the data
    z = df.groupby('week')['corr'].agg(['min', 'max', 'mean'])

    # 1.1. Area between min and max
    ax.fill_between(z.index, z['min'], z['max'],
        color=mpl.colors.to_rgba('gray', 0.1))

    # 1.2. Line for mean
    z['mean'].plot(ax=ax, color='black')

    # 2. Plot lines for years > 2017
    sns.lineplot(data=df[df['year'].gt(2017)],
        x='week', y='corr', hue='year', palette='tab10', ax=ax)

    # 3. Extras
    ax.set_title(f'{i} weeks rolling correlation')
    ax.legend(loc='upper center', ncol=5)
    ax.set_xlim(0, 52)
    ax.set_yticklabels([])
    ax.set_ylabel('')
    ax.set_xlabel('')

Output (for i = 16 ):

图表

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM