Search code examples
pythonpandastime-seriesseaborn

Plot time-series data with a line for each year


I have a dataframe containing stock data over 20 years.

Open    High    Low Close   Adj Close   Volume
Date                        
2001-01-02  1.062500    1.089286    1.040179    1.062500    0.930781    113078000
2001-01-03  1.035714    1.191964    1.031250    1.169643    1.024641    204268400
2001-01-04  1.295759    1.321429    1.200893    1.218750    1.067660    184849000
2001-01-05  1.209821    1.241071    1.147321    1.169643    1.024641    103089000
2001-01-08  1.209821    1.213170    1.138393    1.183036    1.036374    93424800

What I want is to plot every year(price) separately in the same chart, Starting in January ending in December.

I try something like this, but plots one year after another

  for year in range(2001,2019):
    aapl['Close'].loc[str(year)].plot(figsize=(18,8), label=str(year), secondary_y=True)
plt.legend()
plt.show()

Solution

  • As commented by Scott, you can plot the series against dayofyear, and seaborn helps you do by using the hue parameter to separate the data by the 'Year'.

    Tested in python 3.12.0, pandas 2.1.1, matplotlib 3.8.0, seaborn 0.13.0

    Extract or create additional data

    # Date is in the index, so reset
    df = df.reset_index()
    
    # verify column is a datetime dtype
    df['Date'] = pd.to_datetime(df['Date'])
    
    # extract the Year, which will be used for the color
    df['Year'] = df.Date.dt.year
    
    # extract the day of the year for the x-axis
    df['DoY'] = df.Date.dt.day_of_year
    

    Plot with an Axes-level method

    fig, ax = plt.subplots(figsize=(8, 5))
    sns.lineplot(data=df, x='DoY', y='Close', hue='Year', legend='full', ax=ax)
    sns.move_legend(ax, bbox_to_anchor=(1, 0.5), loc='center left', frameon=False, ncols=3)
    

    enter image description here

    Plot with a Figure-level method

    g = sns.relplot(kind='line', data=df, x='DoY', y='Open', hue='Year', legend='full', height=7, aspect=1)
    

    enter image description here