Skip to content Skip to sidebar Skip to footer

Plotly: How To Add Trendline And Parallel Lines To Time Series Data?

My goal is to add 5 fit lines to the exchange index, which is a time series data. Below is what I want to achieve: There should be a plotted (&log2 transformed) index, a best f

Solution 1:

This answer focuses directly on how to add those lines (dynamically) to a plotly figure. How you calculate those lines is another matter. If the lines are in fact straight parallell lines, then the only tricky part you need to calculate are the starting points, or constants, of the line. The slope of the lines should be equal to the slope of the linear trend of your Adj Close.

I've put togehter a suggestion that builds a given number of lines by calculating some necessary parameters from your source data using statsmodels.

mod = sm.OLS(df['Adj Close'],sm.add_constant(df.ix)).fit()
const = mod.params[0]
trend = mod.params[1]

And then I've specified a list of adjustments to the starting points (model constant) like this:

extra_lines = [-0.2,-0.1,0, 0.1,0.2] # add or  remove as you please

The reason why df.ix is included as a continuous index because your original index seemed to have some jumps in it.

I then proceed to add adjusted trendlines to a fig using:

for i, m in enumerate(model):
    df[m['Line']]=[(m['const']) + (trend*i) for i,v in enumerate(df.index)]
    fig.add_traces(go.Scatter(x=df.ix, y=df[m['Line']]))

Here's the result based on your sample data:

enter image description here

Complete code:

import plotly.graph_objects as go
import statsmodels.api as sm
import pandas as pd
import numpy as np
import datetime
from pandas import Timestamp

df = pd.DataFrame({'Date': {3762: Timestamp('2001-06-01 00:00:00'),
  3763: Timestamp('2001-06-04 00:00:00'),
  3764: Timestamp('2001-06-05 00:00:00'),
  3765: Timestamp('2001-06-06 00:00:00'),
  3766: Timestamp('2001-06-07 00:00:00'),
  3767: Timestamp('2001-06-08 00:00:00'),
  3768: Timestamp('2001-06-11 00:00:00'),
  3769: Timestamp('2001-06-12 00:00:00'),
  3770: Timestamp('2001-06-13 00:00:00'),
  3771: Timestamp('2001-06-14 00:00:00'),
  3772: Timestamp('2001-06-15 00:00:00'),
  3773: Timestamp('2001-06-18 00:00:00'),
  3774: Timestamp('2001-06-19 00:00:00'),
  3775: Timestamp('2001-06-20 00:00:00'),
  3776: Timestamp('2001-06-21 00:00:00'),
  3777: Timestamp('2001-06-22 00:00:00'),
  3779: Timestamp('2001-06-26 00:00:00'),
  3780: Timestamp('2001-06-27 00:00:00'),
  3781: Timestamp('2001-06-28 00:00:00'),
  3782: Timestamp('2001-06-29 00:00:00'),
  3784: Timestamp('2001-07-03 00:00:00'),
  3785: Timestamp('2001-07-04 00:00:00'),
  3786: Timestamp('2001-07-05 00:00:00'),
  3788: Timestamp('2001-07-09 00:00:00'),
  3789: Timestamp('2001-07-10 00:00:00'),
  3790: Timestamp('2001-07-11 00:00:00'),
  3791: Timestamp('2001-07-12 00:00:00'),
  3792: Timestamp('2001-07-13 00:00:00'),
  3793: Timestamp('2001-07-16 00:00:00'),
  3794: Timestamp('2001-07-17 00:00:00'),
  3795: Timestamp('2001-07-18 00:00:00'),
  3796: Timestamp('2001-07-19 00:00:00'),
  3797: Timestamp('2001-07-20 00:00:00'),
  3798: Timestamp('2001-07-23 00:00:00'),
  3799: Timestamp('2001-07-24 00:00:00'),
  3801: Timestamp('2001-07-26 00:00:00'),
  3802: Timestamp('2001-07-27 00:00:00'),
  3803: Timestamp('2001-07-30 00:00:00'),
  3804: Timestamp('2001-07-31 00:00:00'),
  3805: Timestamp('2001-08-01 00:00:00'),
  3806: Timestamp('2001-08-02 00:00:00'),
  3807: Timestamp('2001-08-03 00:00:00'),
  3808: Timestamp('2001-08-06 00:00:00'),
  3809: Timestamp('2001-08-07 00:00:00'),
  3810: Timestamp('2001-08-08 00:00:00'),
  3811: Timestamp('2001-08-09 00:00:00'),
  3812: Timestamp('2001-08-10 00:00:00'),
  3813: Timestamp('2001-08-13 00:00:00'),
  3814: Timestamp('2001-08-14 00:00:00'),
  3815: Timestamp('2001-08-15 00:00:00'),
  3816: Timestamp('2001-08-16 00:00:00'),
  3817: Timestamp('2001-08-17 00:00:00'),
  3818: Timestamp('2001-08-20 00:00:00'),
  3819: Timestamp('2001-08-21 00:00:00'),
  3820: Timestamp('2001-08-22 00:00:00'),
  3821: Timestamp('2001-08-23 00:00:00'),
  3822: Timestamp('2001-08-24 00:00:00'),
  3823: Timestamp('2001-08-27 00:00:00'),
  3824: Timestamp('2001-08-28 00:00:00'),
  3825: Timestamp('2001-08-29 00:00:00'),
  3826: Timestamp('2001-08-30 00:00:00'),
  3827: Timestamp('2001-08-31 00:00:00'),
  3828: Timestamp('2001-09-03 00:00:00'),
  3829: Timestamp('2001-09-04 00:00:00'),
  3830: Timestamp('2001-09-05 00:00:00'),
  3831: Timestamp('2001-09-06 00:00:00'),
  3832: Timestamp('2001-09-07 00:00:00'),
  3833: Timestamp('2001-09-10 00:00:00'),
  3834: Timestamp('2001-09-11 00:00:00'),
  3835: Timestamp('2001-09-12 00:00:00'),
  3836: Timestamp('2001-09-13 00:00:00'),
  3837: Timestamp('2001-09-14 00:00:00'),
  3838: Timestamp('2001-09-17 00:00:00'),
  3839: Timestamp('2001-09-18 00:00:00'),
  3840: Timestamp('2001-09-19 00:00:00'),
  3841: Timestamp('2001-09-20 00:00:00'),
  3842: Timestamp('2001-09-21 00:00:00'),
  3843: Timestamp('2001-09-24 00:00:00'),
  3844: Timestamp('2001-09-25 00:00:00'),
  3845: Timestamp('2001-09-26 00:00:00'),
  3846: Timestamp('2001-09-27 00:00:00'),
  3847: Timestamp('2001-09-28 00:00:00'),
  3850: Timestamp('2001-10-03 00:00:00'),
  3851: Timestamp('2001-10-04 00:00:00'),
  3852: Timestamp('2001-10-05 00:00:00'),
  3853: Timestamp('2001-10-08 00:00:00'),
  3854: Timestamp('2001-10-09 00:00:00'),
  3855: Timestamp('2001-10-10 00:00:00'),
  3856: Timestamp('2001-10-11 00:00:00'),
  3857: Timestamp('2001-10-12 00:00:00'),
  3858: Timestamp('2001-10-15 00:00:00'),
  3859: Timestamp('2001-10-16 00:00:00'),
  3860: Timestamp('2001-10-17 00:00:00'),
  3861: Timestamp('2001-10-18 00:00:00'),
  3862: Timestamp('2001-10-19 00:00:00'),
  3863: Timestamp('2001-10-22 00:00:00'),
  3864: Timestamp('2001-10-23 00:00:00'),
  3865: Timestamp('2001-10-24 00:00:00'),
  3866: Timestamp('2001-10-25 00:00:00'),
  3867: Timestamp('2001-10-26 00:00:00')},
 'Adj Close': {3762: 9.483521300451965,
  3763: 9.488539389609842,
  3764: 9.506873417520655,
  3765: 9.516059526271494,
  3766: 9.52540142267562,
  3767: 9.533067841143405,
  3768: 9.523360475569014,
  3769: 9.512419287352929,
  3770: 9.512170110321078,
  3771: 9.491669027751996,
  3772: 9.480558330676322,
  3773: 9.468756875278643,
  3774: 9.48293369128291,
  3775: 9.466431924131614,
  3776: 9.487020913528825,
  3777: 9.486001951740908,
  3779: 9.469774943465724,
  3780: 9.473028427171643,
  3781: 9.459371553309266,
  3782: 9.475970855997938,
  3784: 9.486816137667164,
  3785: 9.488542421142602,
  3786: 9.472664671722018,
  3788: 9.448623120188204,
  3789: 9.450451192873874,
  3790: 9.435713467289014,
  3791: 9.446218508764293,
  3792: 9.442466660552066,
  3793: 9.443397047352386,
  3794: 9.433103851072097,
  3795: 9.427642127580112,
  3796: 9.41571256910222,
  3797: 9.417491092037041,
  3798: 9.412174497254961,
  3799: 9.4103462690634,
  3801: 9.39597479458201,
  3802: 9.407728679911855,
  3803: 9.399857656975392,
  3804: 9.418710567070383,
  3805: 9.431781694039891,
  3806: 9.430789907045172,
  3807: 9.414837561626188,
  3808: 9.404986466190781,
  3809: 9.39326095182,
  3810: 9.389156606132271,
  3811: 9.368776387849374,
  3812: 9.372953110523751,
  3813: 9.366855970805329,
  3814: 9.391912461823267,
  3815: 9.404395312850555,
  3816: 9.378600227328686,
  3817: 9.37201776092802,
  3818: 9.34650456280641,
  3819: 9.344901824694107,
  3820: 9.32264802844274,
  3821: 9.33656588127212,
  3822: 9.315627867418097,
  3823: 9.326764237890817,
  3824: 9.332604930413563,
  3825: 9.327448527151956,
  3826: 9.333940224481115,
  3827: 9.313842403932533,
  3828: 9.29676020844021,
  3829: 9.318015638210596,
  3830: 9.300468022736998,
  3831: 9.27465889826041,
  3832: 9.248040717937537,
  3833: 9.246317398619535,
  3834: 9.25122895807117,
  3835: 9.158375285355174,
  3836: 9.166305927329747,
  3837: 9.175277821947487,
  3838: 9.13984812080253,
  3839: 9.1386188229253,
  3840: 9.165149513582218,
  3841: 9.139701196323891,
  3842: 9.097641909876808,
  3843: 9.13610162204065,
  3844: 9.128051597198034,
  3845: 9.145455124069166,
  3846: 9.169600669798987,
  3847: 9.205398199033475,
  3850: 9.200001069931528,
  3851: 9.238576907009563,
  3852: 9.237700631328401,
  3853: 9.207118194132338,
  3854: 9.245604198507314,
  3855: 9.23972830855306,
  3856: 9.26128158783136,
  3857: 9.237384352858927,
  3858: 9.223314822990815,
  3859: 9.225080227987517,
  3860: 9.236087021069979,
  3861: 9.198329565352042,
  3862: 9.192770913389573,
  3863: 9.189886616720194,
  3864: 9.23208619279342,
  3865: 9.23439472833901,
  3866: 9.23439472833901,
  3867: 9.250016773018734},
 'Volume': {3762: 0.0,
  3763: 0.0,
  3764: 0.0,
  3765: 0.0,
  3766: 0.0,
  3767: 0.0,
  3768: 0.0,
  3769: 0.0,
  3770: 0.0,
  3771: 0.0,
  3772: 0.0,
  3773: 0.0,
  3774: 0.0,
  3775: 0.0,
  3776: 0.0,
  3777: 0.0,
  3779: 0.0,
  3780: 0.0,
  3781: 0.0,
  3782: 0.0,
  3784: 0.0,
  3785: 0.0,
  3786: 0.0,
  3788: 257038800.0,
  3789: 134407800.0,
  3790: 195057600.0,
  3791: 174767800.0,
  3792: 211230200.0,
  3793: 113928800.0,
  3794: 139890800.0,
  3795: 134535000.0,
  3796: 204987000.0,
  3797: 147662000.0,
  3798: 166057200.0,
  3799: 139913800.0,
  3801: 221039000.0,
  3802: 124388600.0,
  3803: 153086200.0,
  3804: 227109800.0,
  3805: 243126000.0,
  3806: 194471600.0,
  3807: 168728800.0,
  3808: 141753200.0,
  3809: 208445200.0,
  3810: 178200800.0,
  3811: 231948800.0,
  3812: 148634200.0,
  3813: 137231600.0,
  3814: 172713800.0,
  3815: 191067400.0,
  3816: 422805600.0,
  3817: 330698600.0,
  3818: 256960200.0,
  3819: 225189800.0,
  3820: 272482800.0,
  3821: 215469200.0,
  3822: 241046000.0,
  3823: 145020400.0,
  3824: 179275400.0,
  3825: 188285800.0,
  3826: 246490800.0,
  3827: 265702000.0,
  3828: 185143200.0,
  3829: 303746000.0,
  3830: 206642600.0,
  3831: 239079600.0,
  3832: 399700800.0,
  3833: 367156400.0,
  3834: 0.0,
  3835: 0.0,
  3836: 0.0,
  3837: 0.0,
  3838: 0.0,
  3839: 0.0,
  3840: 333256200.0,
  3841: 284966400.0,
  3842: 519940400.0,
  3843: 442181500.0,
  3844: 367545800.0,
  3845: 390860600.0,
  3846: 296667600.0,
  3847: 320775600.0,
  3850: 333197400.0,
  3851: 358779000.0,
  3852: 576213400.0,
  3853: 511535600.0,
  3854: 409534200.0,
  3855: 370696800.0,
  3856: 398527200.0,
  3857: 388528000.0,
  3858: 275161200.0,
  3859: 192816600.0,
  3860: 414838800.0,
  3861: 365696000.0,
  3862: 297211400.0,
  3863: 236566000.0,
  3864: 344018800.0,
  3865: 287418600.0,
  3866: 0.0,
  3867: 346798600.0}})

# line parameters using statsmodels
df['Date'] = pd.to_datetime(df['Date'])
df['ix']=np.arange(0, len(df))
mod = sm.OLS(df['Adj Close'],sm.add_constant(df.ix)).fit()
const = mod.params[0]
trend = mod.params[1]

# dict that stores adjusted constants (starting points)
extra_lines = [-0.2,-0.1,0, 0.1,0.2] # add or  remove as you please
model = [{'Line': 'Line_'+str(i+1), 'value': k, 'const': const+k} for i, k in enumerate(extra_lines)]

# plotly
fig = go.Figure(go.Scatter(x=df.ix, y=df['Adj Close']))
for i, m in enumerate(model):
    df[m['Line']]=[(m['const']) + (trend*i) for i,v in enumerate(df.index)]
    fig.add_traces(go.Scatter(x=df.ix, y=df[m['Line']]))
    
fig.show()

Post a Comment for "Plotly: How To Add Trendline And Parallel Lines To Time Series Data?"