Plotly, pandas & Cufflinks

Plotly is a cloud-based graphing and analytics platform with Python, R, & MATLAB APIs.

The Python Quant Platform is a platform for browser-based financial analytics and applications. You can combine the two to make interactive graphs in an IPython Notebook.

To access and execute this notebook register under Plotly Registration.

This library binds the power of plotly with the flexibility of pandas for easy plotting.

This library is available on https://github.com/santosjorge/cufflinks

This tutorial assumes that the plotly user credentials have already been configured as stated on the getting started guide. Alternatively, the demo account credentials can be used (see below).

In [1]:
import plotly.plotly as py
import pandas as pd
import cufflinks as cf
import numpy as np
In [2]:
py.sign_in('Python-Demo-Account', 'gwt101uhh0')

We create a set of timeseries

In [3]:
df=pd.DataFrame(np.random.randn(100,5),index=pd.date_range('1/1/15',periods=100),columns=['IBM','MSFT','GOOG','VERZ','APPL'])
df=df.cumsum()

iplot can be used on any DataFrame to plot on a plotly chart. If no filename is specified then a generic Plotly Playground file is created.

All the charts are created as private by default. To make them public you can use world_readable=True

Let's look at the avilable parameters

In [4]:
help(df.iplot)
Help on method _iplot in module cufflinks.plotlytools:

_iplot(self, data=None, layout=None, filename='Plotly Playground', world_readable=False, theme='pearl', xTitle='', yTitle='', colors=None, fill=False, kind='scatter', barmode='', title='', annotations=None, asFigure=False, asImage=False, dimensions=(1116, 587), sortbars=False, keys=False, bestfit=False, bestfit_colors=None, asPlot=False, **kwargs) method of pandas.core.frame.DataFrame instance
    Returns a plotly chart either as inline chart, image of Figure object
    
    Parameters:
    -----------
            data : Data
                    Plotly Data Object.
                    If not entered then the Data object will be automatically
                    generated from the DataFrame.
            layout : Layout
                    Plotly layout Object
                    If not entered then the Layout objet will be automatically
                    generated from the DataFrame.
            filename : string
                    Filename to be saved as in plotly account
            world_readable : bool
                    If False then it will be saved as a private file
            colors : list or dict
                    {key:color} to specify the color for each column
                    [colors] to use the colors in the defined order
            kind : string
                    Kind of chart
                            scatter
                            bar
                            spread
                            ratio
            fill : bool
                    Filled Traces
            sortbars : bool
                    Sort bars in descending order
                    * Only valid when kind='bar'
            keys : list of columns
                    List of columns to chart.
                    Also can be usded for custom sorting.
            bestfit : boolean or list
                    If True then a best fit line will be generated for 
                    all columns. 
                    If list then a best fit line will be generated for 
                    each key on the list. 
            bestfit_colors : list or dict
                    {key:color} to specify the color for each column
                    [colors] to use the colors in the defined order
            theme : string
                    Layout Theme
                            solar
                            pearl
                            white
            title : string
                    Chart Title
            xTitle : string
                    X Axis Title
            yTitle : string
                    Y Axis Title
            barmode : string 
                    Mode when displaying bars
                            group
                            stack
                            overlay
                    * Only valid when kind='bar'
            annotations : dictionary
                    Dictionary of annotations
                    {x_point : text}
            asFigure : bool
                    If True returns plotly Figure
            asImage : bool
                    If True it returns Image
            dimensions : tuple(int,int)
                    Dimensions for image 
                            (width,height)
                    * Only valid when asImage=True


In [5]:
df.iplot(filename='Tutorial 1', world_readable=True)
Out[5]:

Pretty Printing Figures

iplot can return a Plotly Figure if we state asFigure=True

Cufflinks also provides a pretty print pp function that makes any object of type dictionary (figures,layouts) more readable.

In [6]:
fig=df.iplot(filename='Tutorial 1', world_readable=True, asFigure=True)
In [7]:
cf.pp(fig['layout'])
legend :
    bgcolor  =  #F5F6F9
    font :
        color  =  #4D5663
paper_bgcolor  =  #F5F6F9
plot_bgcolor  =  #F5F6F9
xaxis :
    gridcolor  =  #FFFFFF
    tickfont :
        color  =  #4D5663
    title  =  
yaxis :
    gridcolor  =  #FFFFFF
    tickfont :
        color  =  #4D5663
    title  =  
    titlefont :
        color  =  #4D5663
    zeroline  =  False

Customizing Themes

We can pass a theme to the iplot function. 3 themes are available, but you can create your own * Solar * Pearl (Default) * White

In [8]:
df[['APPL','IBM','VERZ']].iplot(theme='white', filename='Tutorial White', world_readable=True)
Out[8]:

We can also pass common metadata for the chart

In [9]:
df.iplot(theme='pearl', filename='Tutorial Metadata', title='Stock Returns',
         xTitle='Return', yTitle='Dates', world_readable=True)
Out[9]:

Bestfit Lines

We can easily add a bestfit line to any Series

This will automatically add a best fit approximation and the equation as the legend.

In [10]:
df['IBM'].iplot(filename='IBM Returns', bestfit=True, world_readable=True)
Out[10]:

Customizing Colors

We can pass any color (either by Hex, RGB or Text *)

*Text values are specified in the cufflinks.colors modules

In [11]:
df['IBM'].iplot(filename='IBM Returns - colors', bestfit=True, colors=['pink'],
                bestfit_colors=['blue'], world_readable=True)
Out[11]:

Filled Traces

We can add a fill to a trace with fill=True

In [12]:
df['MSFT'].iplot(filename='Tutorial Microsoft', fill=True,colors=['green'], world_readable=True)
Out[12]:

Bar Charts

We can easily create a bar chart with the parameter kind

In [13]:
df.sum().iplot(kind='bar', filename='Tutorial Barchart', world_readable=True)
Out[13]:

Bars can also be stacked by a given dimension

In [14]:
df.resample('M').iplot(kind='bar', barmode='stacked', world_readable=True,
                       filename='Tutorial Bar Stacked')
Out[14]:

Spread and Ratio charts

We can also create spread and ratio charts on the fly with kind='spread' and kind='ratio'

In [15]:
df[['IBM','GOOG']].iplot(filename='Tutorial Spread', kind='spread',
                         world_readable=True)
Out[15]:
In [16]:
df[['IBM','GOOG']].iplot(filename='Tutorial Ratio', kind='ratio',
                         colors=['green','red'], world_readable=True)
Out[16]:

Annotations

Annotations can be added to the chart and these are automatically positioned correctly.

Annotations should be specified in a dictionary form

In [17]:
annotations={'2015-01-15':'Dividends','2015-03-31':'Split Announced'}
df['MSFT'].iplot(filename='Tutorial Annotations', annotations=annotations,
                 world_readable=True)
Out[17]:

Output as Image

The output of a chart can be in an image mode as well.

For this we can use asImage=True

We can also set the dimensions (optional) with dimensions=(width,height)

In [18]:
df[['VERZ','MSFT']].iplot(filename='Tutorial Image', theme='white', 
                          colors=['pink','blue'], asImage=True, 
                          dimensions=(800, 500), world_readable=True)

Advanced Use

It is also possible to get the Plotly Figure as an output to tweak it manually

We can achieve this with asFigure=True

In [19]:
df['GOOG'].iplot(asFigure=True)
Out[19]:
{'data': [{'line': {'color': 'rgba(255, 153, 51, 1.0)', 'width': 3},
   'name': 'Series1',
   'type': u'scatter',
   'x': ['2015-01-01',
    '2015-01-02',
    '2015-01-03',
    '2015-01-04',
    '2015-01-05',
    '2015-01-06',
    '2015-01-07',
    '2015-01-08',
    '2015-01-09',
    '2015-01-10',
    '2015-01-11',
    '2015-01-12',
    '2015-01-13',
    '2015-01-14',
    '2015-01-15',
    '2015-01-16',
    '2015-01-17',
    '2015-01-18',
    '2015-01-19',
    '2015-01-20',
    '2015-01-21',
    '2015-01-22',
    '2015-01-23',
    '2015-01-24',
    '2015-01-25',
    '2015-01-26',
    '2015-01-27',
    '2015-01-28',
    '2015-01-29',
    '2015-01-30',
    '2015-01-31',
    '2015-02-01',
    '2015-02-02',
    '2015-02-03',
    '2015-02-04',
    '2015-02-05',
    '2015-02-06',
    '2015-02-07',
    '2015-02-08',
    '2015-02-09',
    '2015-02-10',
    '2015-02-11',
    '2015-02-12',
    '2015-02-13',
    '2015-02-14',
    '2015-02-15',
    '2015-02-16',
    '2015-02-17',
    '2015-02-18',
    '2015-02-19',
    '2015-02-20',
    '2015-02-21',
    '2015-02-22',
    '2015-02-23',
    '2015-02-24',
    '2015-02-25',
    '2015-02-26',
    '2015-02-27',
    '2015-02-28',
    '2015-03-01',
    '2015-03-02',
    '2015-03-03',
    '2015-03-04',
    '2015-03-05',
    '2015-03-06',
    '2015-03-07',
    '2015-03-08',
    '2015-03-09',
    '2015-03-10',
    '2015-03-11',
    '2015-03-12',
    '2015-03-13',
    '2015-03-14',
    '2015-03-15',
    '2015-03-16',
    '2015-03-17',
    '2015-03-18',
    '2015-03-19',
    '2015-03-20',
    '2015-03-21',
    '2015-03-22',
    '2015-03-23',
    '2015-03-24',
    '2015-03-25',
    '2015-03-26',
    '2015-03-27',
    '2015-03-28',
    '2015-03-29',
    '2015-03-30',
    '2015-03-31',
    '2015-04-01',
    '2015-04-02',
    '2015-04-03',
    '2015-04-04',
    '2015-04-05',
    '2015-04-06',
    '2015-04-07',
    '2015-04-08',
    '2015-04-09',
    '2015-04-10'],
   'y': array([  1.13000052,   1.34327714,   2.43505824,   2.57301497,
            2.24064499,   2.47047837,   2.65233339,   3.78538858,
            3.49477275,   3.83009202,   3.5503755 ,   4.26997682,
            4.19348046,   4.48969966,   3.6933641 ,   3.53404366,
            4.15312929,   4.9262186 ,   4.91619336,   4.76761014,
            4.6100601 ,   5.62557885,   4.63076887,   3.51184762,
            3.38096225,   3.68234466,   3.38179146,   2.78317051,
            2.56062181,   2.46231942,   2.2351866 ,   3.07082756,
            2.95942581,   3.55786256,   3.20582322,   3.63980631,
            4.18125601,   3.90433908,   3.5805334 ,   3.39525294,
            4.60788823,   4.36424664,   5.03691721,   5.22787781,
            4.49188026,   3.81360387,   2.99849437,   3.72560702,
            4.31602097,   5.78324974,   3.47936072,   4.1427845 ,
            5.45384866,   6.97903737,   5.97549527,   6.14533732,
            4.9742281 ,   4.38643844,   4.33071319,   3.33806516,
            3.66064363,   3.26279388,   5.57670862,   6.33198666,
            6.50615707,   6.35528056,   7.21530164,   8.69543388,
           10.14035052,   9.00244561,   9.3070568 ,   9.2898009 ,
            8.73340328,  11.41208958,  10.5203993 ,   9.95546243,
           10.33233216,   9.86337904,  10.60276212,  12.86928744,
           12.53680173,  11.80323041,  11.21274753,  11.87975838,
           12.61174102,  14.14714926,  13.77054767,  15.30757634,
           11.77048691,  11.27010499,  10.76961153,  11.04676865,
            9.32461077,   8.76791439,   8.02569101,   7.26447625,
            6.16042775,   6.35423218,   6.48057318,   6.5280786 ])}],
 'layout': {'legend': {'bgcolor': '#F5F6F9', 'font': {'color': '#4D5663'}},
  'paper_bgcolor': '#F5F6F9',
  'plot_bgcolor': '#F5F6F9',
  'xaxis': {'gridcolor': '#FFFFFF',
   'tickfont': {'color': '#4D5663'},
   'title': ''},
  'yaxis': {'gridcolor': '#FFFFFF',
   'tickfont': {'color': '#4D5663'},
   'title': '',
   'titlefont': {'color': '#4D5663'},
   'zeroline': False}}}

We can also get the Data object directly

In [20]:
data=df.to_iplot()
In [21]:
data[0]['name']='My Custom Name'

And pass this directly to iplot

In [22]:
df.iplot(data=data,filename='Tutorial Custom Name',world_readable=True)
Out[22]: