Gustavo Louis Montaño

Absolutely and unequivocally living the dream!

A Quick Glipse into Python, Plotly and Dash

Fun with Python, Graphs and HTML

Python continues to surprise me. Long are the days (I'm delayed) where HTML can only be dominated by PHP and Javscript (to name a few).

Seeing is believing - and I had to answer this question - Can Python create graphical web applications? Yes!

Find my quick attempt below - where I scraped 3 sets of commodity data from an API, before graphing them.

The goal of this article is to

  1. Source financial commodity data from Quandl
  2. Use Plotly Express to create an interactive graph
  3. Post our results as HTML using Dash

Getting Started - Python Env and Quandl

First create a new Python environment, and activate it. Using pip install, get the following modules Quandl, dash, dash_core_components, dash_html_components, pandas, plotly, numpy. If upon running this exercise your compiler requires more modules - then go ahead and pip install it.

Next we're going to get access to commodity data (it's free!); sign up to Quandl, perform the trivial verifications and grab your own API key and store it.

How this will work

We're doing quite a bit here - so hang on tight.

The ultimate goal is to create a web application using Dash. This application will have a graph representing commodity data from Quandl. Therefore, there are objects/classes dedicated to the (i) application; (ii) graph; (iii) Quandl.

Every piece of code you'll see should be appended to your file.

Step 1: Imports, Dash App Object, Quandl

First import the required dash modules for our application. import plotly.express provides the graph interface and import quandl allows us to source data from Quandl.

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

import plotly.express as px

import quandl
import pandas as pd

HTML is stlyed using CSS and since Dash is effectively a HTML framework - it too may be styled this way. I found a random CSS external spreadsheet, which I fed into our dash app.

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

The app has been declared and we can move forward with extracting data from Quandl. This is easy. First set your API key

quandl.ApiConfig.api_key = "Put your API Here!"

Next we are going to source 3 frontline futures contracts; Henry Hub, Crude Oil and ICE Sugar. The asset codes are Pythonically declared as constants:

QUANDL_HENRY_HUB = "CHRIS/CME_NN1"
QUANDL_CRUDE_OIL = "CHRIS/CME_CL1"
QUANDL_ICE_SUGAR = "CHRIS/ICE_SB1"

Finally, we'll grab the data using quandl.get. In this case, I started with Henry Hub, and I want data returned as a numpy array.

data = quandl.get(QUANDL_HENRY_HUB, returns="numpy")

Step 2: Graphing with Plotly Express

Plotly is a data-science and machine learning tool. It allows users to create and share interactive visualisations on data. We'll be using the express library to create and quick interactive line graphs.

First - the graphs take in a DataFrame object. As such, we need to transform our data into a DataFrame.

dataDf = dataDf = pd.DataFrame({"Dates": data["Date"], "Prices": data["Settle"]})

Here, we've set a dataframe with 2 columns - Dates and Prices. Therein are the dates and prices of the data extracted from Quandl. Next we graph:

fig = px.line(data_frame=dataDf, x="Dates", y="Prices")

px.line is using Plotly express' line. The DataFrame has been entered, along with x and y coordinates, linked to the DataFrame's columns.

At this stage you can check your work. That is if you add fig.show() and run the Python script via python yourFile.py - then you should see a graph! Great! But at this stage that's all you have - a graph. We want to make it a little more dynamic.

Step 3: Come in Dash

Dash provides a HTML framework allowing us to make a dyanmic and interactive web page.

We'll introduce buttons related to the Quandl asset codes. When clicked - new data will be retrieved, and the graphs updated.

First remove fig.show() if you had previously inserted it. Recall that app has been declared; it can be viewed as a storage for HTML objects. Our webpage will contain

  1. A title
  2. A description
  3. 3 buttons; one for each asset
  4. The graph

This is how it's done

app.layout = html.Div(
    children=[
        html.H1(children = 'Gus quickly working with Ploty Express and Dash!'),
        html.Div(children = "Navigate between API Henry Hub and Crude Oil data; Zoom in & Explore!."),
        html.Br(),
        html.Button("Henry Hub", id="btn-henryHub", n_clicks=0),
        html.Button("Crude Oil", id="btn-crudeOil", n_clicks=0),
        html.Button("Sugar Futures", id="btn-sugar", n_clicks=0),
        dcc.Graph(id='the-graph', figure=fig)
    ]
)

If you have familiarty with HTML, then some of the declarations will make sense. Otherwise, have a read of each line, and try your best guess and what has been inserted. One final note is that dcc.graph will contain the interactive graph made in Step 2!

Step 4: Making Web Interactions - app.callback

While we've declared HTML objects - we need them to respond to our interactions. This is where things get tricky, as we are moving into reactive programming, and Python decorators.

In the grand scheme of things - a function needs to be called when a button is pressed. This is called the input. It must then be followed by a response, called the output. These are all placed as arguments to a decorator on the function app.callback. As such,

@app.callback(
    Output("the-graph", "figure"),
    [Input("btn-henryHub", "n_clicks"),
    Input("btn-crudeOil", "n_clicks"),
    Input("btn-sugar", "n_clicks")])

If you know a thing or two about this - you'll be expecting a function. This is shown below, and is immediately executed upon input activation. Furthrmore, it returns a result to the output - which is our graph!

def updateGraph(btn1, btn2, btn3):
    changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0]
    if "btn-henryHub" in changed_id:
        dataName = QUANDL_HENRY_HUB
    elif "btn-crudeOil" in changed_id:
        dataName = QUANDL_CRUDE_OIL
    elif "btn-sugar" in changed_id:
        dataName = QUANDL_ICE_SUGAR
    else:
        dataName = QUANDL_HENRY_HUB

    data = quandl.get(dataName, returns="numpy")
    dataDf = pd.DataFrame({"Dates": data["Date"], "Prices": data["Settle"]})
    return px.line(data_frame=dataDf, x="Dates", y="Prices")

The code is checking which buttons have changed according to click. Then it enters the if statement, capturing a new Quandl asset short code before repeating the process of data extraction, data framing and line constructing. The final line graph is then returned.

Step 5: The End

The end is finally here. With all of this done - we're ready to execute our code and run a server. This is final piece of code:

if __name__ == '__main__':
   app.run_server(host="0.0.0.0",debug=True)

Simply, the app object's run_server method is called, and the server will be on localhost or 0.0.0.0.

Assuming everything was done correctly, and your libraries/modules are in check - you may run this code using python yourFile.py and see the interactive graph at http://0.0.0.0.