Plotly Plots of Stock Price Data Retrieved by Pandas from Yahoo! Finance

In this Jupyter (IPython) Notebook we illustrate the evolution of 8 stock market indices (4 from USA and 4 from Asia) over the period from August 7 to August 26, 2015. Data are accessed and retrieved from Yahoo! Finance, with pandas.io.data.DataReader function (pandas 0.16.2).

In [1]:
from datetime import datetime
import numpy as np
import pandas as pd
from pandas.io.data import DataReader
In [2]:
index_symbol = ['^GSPC', '^DJI','^NDX', '^NYA', '000001.SS', '^N225','^HSI', '^STI' ]
explicit_name=['S&P 500', 'DOW JONES', 'NASDAQ', 'NYSE', 'SHANGHAI', 'NIKKEI', 'HKSE', 'SES']

d = {}
for symb in index_symbol:
    d[symb] = DataReader(symb, "yahoo", start=datetime( 2015, 8, 7 ), end=datetime( 2015, 8, 26 ))
panel = pd.Panel(d)# Panel of data
df = panel.minor_xs('Adj Close') #df is a dataframe containing adjusted closing price for each index
print df
            000001.SS          ^DJI        ^GSPC          ^HSI         ^N225  \
Date                                                                           
2015-08-07    3744.21  17373.380859  2077.570068  24552.470703  20724.560547   
2015-08-10    3928.42  17615.169922  2104.179932  24521.119141  20808.689453   
2015-08-11    3927.91  17402.839844  2084.070068  24498.210938  20720.750000   
2015-08-12    3886.32  17402.509766  2086.050049  23916.019531  20392.769531   
2015-08-13    3954.56  17408.250000  2083.389893  24018.800781  20595.550781   
2015-08-14    3965.33  17477.400391  2091.540039  23991.029297  20519.449219   
2015-08-17        NaN  17545.179688  2102.439941  23814.650391  20620.259766   
2015-08-18    3748.16  17511.339844  2096.919922  23474.970703  20554.470703   
2015-08-19    3794.11  17348.730469  2079.610107  23167.849609  20222.630859   
2015-08-20    3664.29  16990.689453  2035.729980  22757.470703  20033.519531   
2015-08-21    3507.74  16459.750000  1970.890015  22409.619141  19435.830078   
2015-08-24    3209.91  15871.349609  1893.209961  21251.570312  18540.679688   
2015-08-25    2964.97  15666.440430  1867.609985  21404.960938  17806.699219   
2015-08-26    2927.29  16285.509766  1940.510010  21080.390625  18376.830078   

                   ^NDX          ^NYA         ^STI  
Date                                                
2015-08-07  4520.080078  10763.150391          NaN  
2015-08-10  4573.109863  10906.049805          NaN  
2015-08-11  4513.990234  10802.089844  3153.060059  
2015-08-12  4528.189941  10779.459961  3061.489990  
2015-08-13  4519.319824  10745.309570  3091.780029  
2015-08-14  4530.740234  10782.240234  3114.250000  
2015-08-17  4566.370117  10818.570312  3067.350098  
2015-08-18  4542.069824  10792.799805  3049.649902  
2015-08-19  4510.899902  10687.019531  3041.250000  
2015-08-20  4385.129883  10475.740234  3009.780029  
2015-08-21  4197.270020  10195.690430  2971.010010  
2015-08-24  4038.600098   9789.940430  2843.389893  
2015-08-25  4016.320068   9692.379883  2886.290039  
2015-08-26  4219.600098   9979.669922  2873.000000  

For each index we generate a Plotly Scatter plot displayed into a subplot:

In [3]:
import plotly.plotly as py
import plotly.tools as tls
from plotly.graph_objs import *
In [4]:
fig = tls.make_subplots(
    rows=4,
    cols=2,
    shared_xaxes=False,
    subplot_titles=('S&P 500', 'SHANGHAI',  'DOW JONES', 'NIKKEI', 'NASDAQ','HKSE', 'NYSE', 'SES')
)
This is the format of your plot grid:
[ (1,1) x1,y1 ]  [ (1,2) x2,y2 ]
[ (2,1) x3,y3 ]  [ (2,2) x4,y4 ]
[ (3,1) x5,y5 ]  [ (3,2) x6,y6 ]
[ (4,1) x7,y7 ]  [ (4,2) x8,y8 ]

tls.make_subplots defines an object Figure with 8 subplots, and makes default subplot annotations. The annotations for the third subplot are retrieved as follows:

In [5]:
fig['layout']['annotations'][2]
Out[5]:
{'font': {'size': 16},
 'showarrow': False,
 'text': 'DOW JONES',
 'x': 0.225,
 'xanchor': 'center',
 'xref': 'paper',
 'y': 0.71875,
 'yanchor': 'bottom',
 'yref': 'paper'}

!!!! We have to avoid overwriting these annotations with fig['layout']['annotations'] = Annotations(...). We can make updates instead.

Update figure with collected data:

In [6]:
def make_trace(y, sbplt):# this function creates the trace for each subplot
    # y stock index value
    # stock index name
    # sbplt - subplot
    return Scatter(
        x=df.index,  
        y=y,            
        name='',     
        
        line=Line(
        color= '#2c7fb8',
        width=0.75
    ),
         
        xaxis='x{}'.format(sbplt),                    
        yaxis='y{}'.format(sbplt)     
    )
In [7]:
sbplt=1
for symb in index_symbol[:4]: #make traces for left subplots (first column)
    fig['data'] +=[make_trace(df[symb], sbplt)]
    sbplt+=2              
sbplt=2

for symb in  index_symbol[4:]: #make traces for the second  column
    fig['data']+=[make_trace(df[symb], sbplt)]
    sbplt+=2              

Layout settings:

In [8]:
axis_style = dict(
    zeroline=False,     
    showgrid=True, 
    gridwidth=1,
    gridcolor='#FFFFFF')  
In [9]:
def make_XAxis():
    xaxis = XAxis(zeroline=False,  
                  nticks=4,
                 )   
    return xaxis


def make_YAxis():
    yaxis = YAxis()  
    yaxis.update(axis_style)                     
    return yaxis

Update layout:

In [10]:
title = 'Stock market indices (left USA, right ASIA)'
fig['layout'].update(title=title,                                 
                     font= Font(size=12))  
                    
In [11]:
fig['layout'].update(
    showlegend=False, 
    hovermode='closest',
    autosize=False,   
    height=800,       
    width=700,       
    margin=Margin(
        t=100,    
        b=100,     
        r=25,      
        l=70       
    ),
    plot_bgcolor='#EFECEA',  
    
)
In [12]:
subpts=range(1,9)# list of subplots, 
In [13]:
for sbplt in subpts:
    fig['layout'].update({'xaxis{}'.format(sbplt): make_XAxis()})
    fig['layout'].update({'yaxis{}'.format(sbplt): make_YAxis()})
In [14]:
anno_text="Data source:\
<a href='http://finance.yahoo.com/stock-center/'> [1]</a>. \
Access via <a href='http://pandas.pydata.org/pandas-docs/stable/remote_data.html'> [2] </a>"

fig['layout']['annotations']+=[
    Annotation(
            showarrow=False, 
            text=anno_text,  
            xref='paper',     
            yref='paper',     
            x=0,  
            y=-0.15,  
            xanchor='left',   
            yanchor='bottom',  
            font=Font(
            size=11 )
            )
] 
for sbplt in subpts: #change the default font size for  subplots title
    fig['layout']['annotations'][sbplt-1]['font']= {'size': 12}
In [15]:
 fig['layout']['annotations'][0]# check the update
Out[15]:
{'font': {'size': 12},
 'showarrow': False,
 'text': 'S&P 500',
 'x': 0.225,
 'xanchor': 'center',
 'xref': 'paper',
 'y': 1.0,
 'yanchor': 'bottom',
 'yref': 'paper'}
In [16]:
py.sign_in("empet", "my_api_key")
py.iplot(fig, filename='stock-indices-7-26') 
Out[16]:
In [17]:
from IPython.core.display import HTML
def  css_styling():
    styles = open("./custom.css", "r").read()
    return HTML(styles)
css_styling()
Out[17]: