pythonpandasseabornconfidence-intervalerrorbar

Lineplot with Seaborn and ci="sd" function


I'm trying to produce some snazzy charts in seaborn and need some help.

I have some stock data, consisting of 5 stocks. I'm basically trying to visually display how Stock A has performed in comparison to the others. To do this I am looking at cumulative returns, and have also calculated the average cumulative returns for the other 4 stocks. I have split this data up in to the following 2 df:

Stock A's data let's call df:

Date              Stock A               
2019-04-24 07:59  0.433366
2019-04-24 08:59  0.397984
2019-04-24 09:59  0.403971
2019-04-24 10:59  0.399131
2019-04-24 11:59  0.386641
2019-04-24 12:59  0.388572
2019-04-24 13:59  0.396266
2019-04-24 14:59  0.391609
2019-04-24 15:59  0.399412
2019-04-24 16:59  0.401715

And then Stocks B, C, D & E, PLUS the calculated average let's call df2 (I can't print all 5 columns):

Date              Stock B   Stock C    Stock E   Average                                             
2019-04-24 07:59  0.273965  0.000982    0.409717  0.472029
2019-04-24 08:59  0.235606  -0.076309   0.345047  0.407299
2019-04-24 09:59  0.240826  -0.059274   0.346769  0.413197
2019-04-24 10:59  0.234849  -0.056013   0.338185  0.407962
2019-04-24 11:59  0.230158  -0.062947   0.331907  0.397927
2019-04-24 12:59  0.237573  -0.055506   0.334907  0.412206
2019-04-24 13:59  0.239994  -0.047875   0.334213  0.413846
2019-04-24 14:59  0.230461  -0.059781   0.312962  0.395924
2019-04-24 15:59  0.236968  -0.054398   0.320990  0.406967
2019-04-24 16:59  0.239918  -0.049522   0.328713  0.412818

What I am ultimately looking to do is chart all 5 stocks plus the average on one graph, that has a nice grey background and perhaps some grid lines etc (at the minute I can only chart with ugly white backgrounds), but I would like the line for Stock A and for Average to be slightly different and make use of seaborns standard deviation line plot.

I found this example code sns.relplot(x="timepoint", y="signal", kind="line", ci="sd", data=fmri) but when I tried to alter it to my needs I got error messages and couldn't get all the data to appear on the same chart.

Here is a near perfect example of what I'm aiming for, but I would like to include Stock B, C, D & E from df2 and change the axis labeling of course.

Any help greatly appreciated. Cheers

enter image description here


Solution

  • This should produce what you asked for:

    sns.set() #This sets the style to the seaborn default (gray background with white grid on)
    fig,ax = plt.subplots() #create your figure and ax objects
    sns.lineplot('Date', 'Stock A', ci="sd", data=df,ax=ax) #plot lines
    sns.lineplot('Date', 'Stock B', ci="sd", data=df2,ax=ax)
    sns.lineplot('Date', 'Stock C', ci="sd", data=df2,ax=ax)
    sns.lineplot('Date', 'Stock E', ci="sd", data=df2,ax=ax)
    sns.lineplot('Date', 'Average', ci="sd", data=df2,ax=ax)
    plt.xticks(rotation=-45) #makes ticks visible (a long date would be unreadable otherwise)
    

    EDIT

    Answering OP questions from comments:

    Transform your dates from strings to datetime objects, then matplotlib will take care of the ticks and tickslabels.
    As they are right now they are interpreted as strings and they all get plotted.

    df['Date']=pd.to_datetime(df['Date'])
    df2['Date']=pd.to_datetime(df2['Date'])
    

    Use the following line to change the ylabel

    ax.set_ylabel('Returns')