Plotly & Dash — MultiIndex Currency Dashboard

Parag Kar
6 min readMar 4, 2023

--

The purpose of this note is to create a Multi-Index interactive Dashboard for global currencies using Plotly and Dash and deploy the same on the web for anywhere to view and use. Now before we dive into the details first let's understand what we mean by Multi-Indexing.

Multi-Indexing

Multi-Indexing is a process that enables us to choose the absolute value of selected global currencies vs US dollars for a particular date and then (using that as a reference) calculate their percentage change over time. Using this approach, we can compare the performance of various currencies on an apple-to-apple basis without having to look at their absolute values. For example, let’s say INR was Rs 73.21 vs US dollar on 5th Mar 2021, then the % change wrt this value can be calculated for all times. Similarly, if we pick other currencies' values for the same date, then the comparison becomes even and ready for plotting in the same graph. But the key benefit comes from our ability to dynamically change this reference date and observe the changes on the same graph using python, Plotly, and Dash.

Data Preparation

Currency data used in this project has been picked up from the IMF website and looks something like this.

Figure 1 — Raw Data

You can clearly see that the values of these currencies wrt USD are remarkably different in absolute terms for being useful for comparison on the same graph.

Processing Data

The code used for the above purpose is reproduced below.

import pandas as pd

#loading basic data into dataframe

df = pd.read_csv("currencyratesimf.csv")
df = df.iloc[:,1:]
df['Date'] = pd.to_datetime(df['Date'])
df = df.set_index("Date")›

#function used to return a dataframe (df1)
#using absolute values in the chosen date of reference

def processed_data(date_value):
closest_date_index = df.index.get_loc(date_value, method="nearest")
ref_values = df.iloc[closest_date_index]
df1 = df/ref_values
df1 = df.div(ref_values)*100-100
df1 = df1.iloc[closest_date_index:,:]
df1 = df1.reset_index()
df1 = pd.melt(df1, id_vars="Date")
df1.columns = ["Date", "Country", "%Change"]
#Curating the names of the country by removing extra blank spaces
for i, country in enumerate(df1["Country"]):
country = country.split()
country = " ".join(country)
df1.loc[i,"Country"] = country
return df1

Plotting Data

The idea is to make the plots interactive and allow the users to choose the date for picking reference values dynamically. For this purpose, we plan to use Dash, which will help us to create a plot that will get rendered into an HTML page. The code that we used to enable this is listed below. This code is placed in a comprehensive manner by including pieces that have been listed earlier in this note.

from datetime import date
from dash import Dash, html, dcc
from dash.dependencies import Input, Output
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
from plotly.offline import init_notebook_mode, iplot
import dash_bootstrap_components as dbc
import os

os.chdir("Path of the working dir") #working dir
print(os.getcwd())

#incoporate data in the app

df = pd.read_csv("currencyratesimf.csv")
df = df.iloc[:,1:]
df['Date'] = pd.to_datetime(df['Date'])
df = df.set_index("Date")

#procesing dataframe based on chosen value of date

def processed_data(date_value):
closest_date_index = df.index.get_loc(date_value, method="nearest")
ref_values = df.iloc[closest_date_index]
df1 = df/ref_values
df1 = df.div(ref_values)*100-100
df1 = df1.iloc[closest_date_index:,:]
df1 = df1.reset_index()
df1 = pd.melt(df1, id_vars="Date")
df1.columns = ["Date", "Country", "%Change"]
for i, country in enumerate(df1["Country"]):
country = country.split()
country = " ".join(country)
df1.loc[i,"Country"] = country
return df1

#main application

app = Dash(__name__, external_stylesheets=[dbc.themes.VAPOR])

#Building Dash Components
datepicker = html.Div(dcc.DatePickerSingle(
id='my-date-picker-single',
min_date_allowed=date(2000,1, 1),
max_date_allowed=date(2023,3, 31),
initial_visible_month=date(2022,1,31),
date=date(2022, 1, 31)
))
mygraph = dcc.Graph(figure={})

mytext = dcc.Markdown(children='')

# Customizing the Layout

app.layout = dbc.Container([datepicker, mygraph, mytext])

# Allowing Callback to interact with components

@app.callback(
Output(mygraph, component_property='figure'),
Output(mytext, component_property='children'),
Input("my-date-picker-single", 'date'))

def update_output(date_value):

df1 = processed_data(date_value)

fig = px.line(df1, x="Date", y="%Change", color="Country",
title='% Change in the value of currencies with reference to a selected reference date [+(dep),-(app)]',
height = 600)

string_prefix = 'You have selected: '
if date_value is not None:
date_object = date.fromisoformat(date_value)
date_string = date_object.strftime('%B %d, %Y')
date_string = "Selected Reference Date is -> "+date_string
return fig, date_string


# Runing the application
if __name__ == '__main__':
app.run_server(debug=True,use_reloader=False)

The following is the snapshot of the output that we get after we run this code.

Figure 2 — Output of the Ploty & Dash Interactive Code

Note that the output is a snapshot of the web interface. Clicking the top left corner renders a calendar, which allows the user to pick a date dynamically used for updating the chart. Also note, all currencies % changes emanate from the origin (Zero) — enabling an integrated view. This interface also allows the user to identify the countries and their values by hovering the mouse over the plotted lines. The user can also pick an individual country (or multiple of them) from the legend table placed on the right-hand side of the chart.

Figure 3 — Output with Calender & Tool Tip

Now the following picture is a snapshot where the same output is used to compare the performance of the Brazilian real, and Indian Rupee from 31st Jan 2022 till 1st March 23.

Figure 4 — Indian Rupee vs Brazilian Real.

Rendering Chart on Web

Now in order for everyone to be able to use this interface we need to render this on the web. This is slightly complicated as we have to go through some steps.

  1. Copy the python code into a new directory into a folder named “src”.
  2. Using the terminal install dash-tools (pip install dash-tools).
  3. Using the terminal switch to the directory containing the “src” folder.
  4. Using the terminal execute a command — git init
  5. Using the terminal command execute — dashtools gui

The dashtools GUI looks something like this.

Figure 5 — Dashtools GUI

6. Ensure that the app.py (where our code exists) is inside the source folder.

7. Pick a render app name before you execute to create “render.yaml” file.

8. After this generate the requirements.txt file.

9. In the file named app.py, plug in the following “server = app.server” just below the line “app = Dash(__name__, external_stylesheets=[dbc.themes.VAPOR])”

10. Sign in to GitHub and create a “New Repository” as described below in the picture.

Figure 6 — Creating New GitHub Repository

11. Load all the files from your main directory into the GitHub repository using the “Add file” menu.

12. Make changes in the code app.py by removing the directory path and also upload the datafile “currenyratesimf.csv”.

13. Finally run the rendering process to create a web link to the file that can be shared with all.

Note that the above link is a little slow, the reason could be due to the volume of data involved. Will figure out a way to resolve this soon. Hope you found this useful. Thanks for reading.

(I am aggregating all the articles on this topic here, for easy discovery and reference.)

--

--

Parag Kar
Parag Kar

Written by Parag Kar

EX Vice President, Government Affairs, India and South Asia at QUALCOMM

No responses yet