Article

Plotting Financial Data Chart with Plotly Python

Wasin Waeosri
Developer Advocate Developer Advocate

Overview

Update: June 2021

With the rise of Data Scientists, Financial coders, or Traders (aka Citizen Developers), data visualization is a big part of how to present data, information, and its context to the readers (Financial team, Marketing team, etc.). The good data analysis itself cannot be used with a good graph representation.

The Matplotlib Pyplot is a de-facto library for making interactive plots and data visualization in the Python and Data Scientists world. However, the Matplotlib is a huge library that contains several interfaces, capabilities, and 1000+ pages of documents.

There are a lot of other alternative Plotting libraries such as Seaborn (which is a high-level interface of Matplotlib), Spotify's ChartifyBokehPlotly Python, etc.

This example project demonstrates how to use the Plotly Python library to plot various types of graphs. The demo application uses Corona Virus Disease (COVID-19), Environmental, Social and Governance, and Financial data from Eikon Data API as an example of a dataset.

Note: This article is focusing on the Plotly Python with classic Jupyter Notebook only. There are some minor differences for the Plotly Python with JupyterLab, please see the JupyterLab example in GitHub repository.

Introduction to Plotly Python

Plotly Python is a free and open-source interactive graphing library for Python. The library is built on top of plotly.js JavaScript library (GitHub). Both Plotly Python and Plotly JavaScript are part of Plotly's Dash and Chart Studio applications suites which provide interactively, scientific data visualization libraries/solutions for Data Scientists and Enterprise.

This article Notebook will focus on the Plotly Python open-source library versions 4.14.35.0.0, and 4.5.2 (4.5.2 for the CodeBook environment only).

The example code of Plotly Python is the following:

    	
            

import plotly.express as px

 

fig = px.line(x=["a","b","c"], y=[1,3,2], title="sample figure")

fig.show() 

Introduction to Eikon Data API

The Eikon Data API (aka DAPI) provides access to certain Refinitiv Eikon/Refinitiv Workspace data with seamless workflow with the same data across all applications running on the desktop. The API allows developers to tap into the full breadth of community tools through a modern API with native Python support.

If you are not familiar with Eikon Data API or Python, the following resources are highly recommended to read before you proceed with further steps.

Note:

  • This article is based on Eikon Data API versions 1.1.10 and 1.1.6.post3 (In the CodeBook application).
  • Pleases see Eikon Data API Usage and Limits Guideline regarding the API data coverage and data limit.

Prerequisite

This example requires the following dependencies software and libraries.

  1. Refinitiv Eikon or Refinitiv Workspace application with access to Eikon Data APIs.
  2. Python Anaconda or MiniConda distribution/package manager.
  3. Classic Jupyter Notebook or JupyterLab applications
  4. Internet connection.

Note:

  • This Project has been qualified with Python version 3.8.8 and Conda version 4.10.1

Please contact your Refinitiv's representative to help you to access Refinitiv Workspace/Eikon credentials. You can generate/manage the AppKey by follow the steps in Eikon Data API Quick Start page.

Code Walkthrough

Import Eikon Data API Libraries

The application needs to import Eikon and related libraries in order to interact with the Eikon Data API and Pandas.

    	
            

# Eikon and Application Libraries

 

import eikon as ek

import datetime

import configparser as cp

import numpy as np

import pandas as pd

Then we intialize the Eikon Data API session by passing the app key information to the set_app_key() function.

    	
            

 

# Initializes Eikon Data API session

ek.set_app_key('app_key')

COVID-19 Data

Let's start with the COVID-19 data which is available in the Refinitiv Workspace/Refinitiv Eikon platform via the following instrument's pattern:

  • [Country Code]CCOV=ECI: Covid-19 Total Cases
  • [Country Code]NCOV=ECI: Covid-19 New Cases
  • [Country Code]ACOV=ECI: Covid-19 Active Cases
  • [Country Code]RCOV=ECI: Covid-19 Recovered Cases
  • [Country Code]DCOV=ECI: Covid-19 Death Cases

So, the example instruments of USA Covid-19 data are USCCOV=ECIUSNCOV=ECIUSACOV=ECIUSRCOV=ECI, and USDCOV=ECI instruments.

You can find each country's COVID-19 data from Workspace/Eikon Economic Indicators ("ECONNID") application, and then choosing Country and Indicator values.

The COVID-19 data provides detail with the following fields for users:

  • DSPLY_NMLL: Display Name
  • COUNTRY: Country code
  • CF_DATE: Announcement Date
  • ECON_ACT: Actual value
  • ECON_PRIOR: Previous value

We will use Thailand New Cases history data from 1st January 2021 to 3rd May 2021 with Eikon Data API get_timeseries function as an example data for Plotly.

    	
            

# Thailand New Cases

RIC = 'THNCOV=ECI'

 

df_thailand_historical_new_cases = ek.get_timeseries(RIC, start_date='2021-01-01', end_date='2021-05-03', interval='daily')

df_thailand_historical_new_cases.head()

Plotting Graph with Plotly Python

Like Matplotlib, Plotly also provides various low-level, high-level, helpers interfaces to create, manipulate and render graphical figures such as charts, plots, maps, diagrams, etc based on developer preference.

The Plotly Python figures are represented by tree-like data structures which are automatically serialized to JSON for rendering by the Plotly.js JavaScript library. Plotly provides the Graph Object as the low-level interface that wraps figures into a Python class and Plotly Express as the high-level interface for creating graphs.

Plotly Express

The Plotly Express package is the recommend entry-point to the Plotly Python library. It is the high-level interface for data visualization. The plotly.express module (usually imported as px) contains functions that can create entire figures at once and is referred to as Plotly Express or PX. Plotly Express is a built-in part of the plotly library and is the recommended starting point for creating the most common figures.

    	
            import plotly.express as px
        
        
    

Plotly Express provides more than 30 functions for creating different types of figures. The API for these functions was carefully designed to be as consistent and easy to learn as possible.

We will start with the Line Graph interface.

Line Plot with Plotly Express

The Line Plot interface is the easy-to-use function to create a 2D line graph using px.line() function.

We will plot a single line graph of Thailand COVID-19 new cases historical data with Date value as an X-axis and VALUE as the y-axis. We need to re-structure the Pandas Dataframe to include the Date index as a data column instead.

    	
            

# Reset index to include Date as a data column

 

df_thailand_historical_new_cases.reset_index(level=0, inplace=True)

df_thailand_historical_new_cases.head()

We create the Plotly Figure object for the line chart with Plotly Express px.line() function. We pass the Date column as x-axis, VALUE column as y-axis, and the chart title information to the function.

Then we use the Figure update_traces() method to update figure traces such as line color and update_yaxes() method to update a figure's y-axes information.

Finally, we call the Figure show() function to draw a chart on Jupyter Notebook. Please noticed that we pass 'notebook' to the function to force the classic Jupyter notebook renderer for the classic Jupyter Notebook environment. If you are using JupyterLab, you can use just fig.show() statement.

    	
            

fig = px.line(df_thailand_historical_new_cases, x="Date", y="VALUE", title='Thailand Covid-19 New Cases')

 

fig.update_yaxes(title_text='Number of cases') #Update Y-Axis title

fig.update_traces(line_color='#FF0000') #Update Chart color

fig.show()

Multiple Lines Graph

The Plotly Express Line also supports a multiple-lines graph. We use COVID-19 new cases data for the USA, India, Brazil, France, and Russia as example data to demonstrate the new case trends from 1st January 2021 to 3rd May 2021.

    	
            

# Define RICs list

 

rics = ['USNCOV=ECI','INNCOV=ECI','BRNCOV=ECI','FRNCOV=ECI','RUNCOV=ECI']

 

# Call Eikon Data API get_timeseries function

 

df_historical_total_cases = ek.get_timeseries(rics, start_date='2021-01-01', end_date='2021-04-29', interval='daily')

df_historical_total_cases

The current column names are the RIC names (USNCOV=ECIINNCOV=ECI, etc.) which are hard to read, so we need to rename the column names to be readable Country names first.

    	
            

df_historical_total_cases.rename(

    columns= {'USNCOV=ECI':'USA', 'INNCOV=ECI':'India','BRNCOV=ECI':'Brazil','FRNCOV=ECI':'France','RUNCOV=ECI':'Russia'},

    inplace = True

)

df_historical_total_cases.head()

Then we reset the Dataframe index to include the Date as a data column.

    	
            df_historical_total_cases.reset_index(level=0, inplace=True)
        
        
    

To plot multiple lines graph, we call the px.line() function by passing a list of column names as y-axis values.

    	
            

fig = px.line(df_historical_total_cases, 

              x="Date", 

              y=['USA','India','Brazil','France','Russia'], 

              title='World COVID-19 2021 News Cases')

 

fig.update_yaxes(title_text='Number of cases')

fig.show()

Please see more detail regarding the Plotly Express Line chart in the following resources:

Pie Chart with Plotly Express

The Pie Chart interface is the easy-to-use function to create a circular statistical chart using px.pie() function.

We will look into the India COVID-19 Today all data(Total Cases, New Cases, Active Cases, Recovered Cases, Death Cases) in detail, and plot data as a Pie Chart.

    	
            

# India COVID-19 Data All Rics

 

rics_india_today = ['INCCOV=ECI','INNCOV=ECI','INACOV=ECI','INRCOV=ECI','INDCOV=ECI']

 

fields = ['DSPLY_NMLL', #Display Name

            'COUNTRY',    #Country code

            'CF_DATE', #Announcement Date

            'ECON_ACT', #Actual value

            'ECON_PRIOR' #Previous value

]

 

df_india_today, err = ek.get_data(rics_india_today, fields)

df_india_today

In some cases, the Today data (ECON_ACT field) may be return (Nullable integer) based on the Day and Time that you execute the get_data function (most likely on the Fist day of the week).

To handle this situation, we need to check if all values in ECON_ACT column are null or not.

    	
            

is_ECON_ACT_null = df_india_today['ECON_ACT'].isnull().all()

is_ECON_ACT_null

 

# If **is_ECON_ACT_null** is **True**, we will plot a Pie Chart with *ECON_PRIOR* value.

 

plot_value = 'ECON_ACT'

if is_ECON_ACT_null: 

    plot_value = 'ECON_PRIOR'

The returned DataFrame object looks fines but it is a bit too hard to read, so we will add a new column named Description to the DataFrame object which contains information about each Instrument definition.

    	
            

# Dictionary Definitiion Pattern

covid19_rics_pattern = {

    'CCOV=ECI': 'Total Cases',

    'NCOV=ECI': 'New Cases',

    'RCOV=ECI': 'Recover Cases',

    'ACOV=ECI': 'Active Cases',

    'DCOV=ECI': 'Death Cases'

}

 

# Get a List of readable Country Name and Event for adding new DataFrame column

def get_events_descriptions(list_rics):

    list_result = []

    for ric in list_rics:

        event = ric[2:]

        list_result.append('India {event}'.format(event = covid19_rics_pattern[event]))

    return list_result

 

df_india_today['Description'] = get_events_descriptions(rics_india_today)

df_india_today

Finally, we call px.pie() function to create a figure object for a pie chart with the value of ECON_ACT (Actual value) field and Description column name.

For this pie chart, we use the Figure update_traces() method to update text display format on a figure.

For CodeBook Users!!

Please note that the CodeBook application has an older version of Plotly Python (version 4.5.2 as of May 2021), so px.pie() function for CodeBook will be slightly different.

    	
            

# codebook_plotly_dapi.ipynb

 

fig = px.pie(df_india_today, 

             values= plot_value, 

             names= 'Description', 

             title= 'India Today Covid-19 Data'

            )

 

fig.update_traces(textposition='auto', textinfo='percent+label')

fig.show() # CodeBook is based on JupyerLab

Please see more detail regarding the Plotly Express Pie chart in the following resources:

Plotly Graph Object

The Plotly Graph Object (plotly.graph_objects, typically imported as go) is the low-level interface that lets developers interact with Plotly Figure and IPYWidgets compatible for plotting graphs and manage data in detail. While the Plotly Express provides a simple way to create and customize graphs, the Plotly Graph Object lets developers create and customize more advanced graphs such as Group Bar Chart, Candlestick, Subplot of different types, etc.

    	
            

# Import plotly.graph_objects module

 

import plotly.graph_objects as go

"Exploded" Pie Chart with Plotly Graph Object

The above pie chart has some sections that hard to read, so we will re-create that pie chart with Plotly Graph Object to pull out some sectors from the chart.

    	
            

fig = go.Figure(data = [ go.Pie(

    labels=df_india_today['Description'], 

    values=df_india_today[plot_value],

    pull=[0, 0.2, 0, 0,0.2] #pull only some of the sectors

)])

 

fig.update_traces(textposition='auto', textinfo='percent+label')

fig.update_layout(title = 'India Today Covid-19 Data') # Set Title

fig.show()

Please notice that you can set the chart title via the title property of fig.update_layout function when using the Graph Object.

Please see more detail regarding Plotly Graph Object Bar Chart in the following resources:

Bar Chart with Plotly Graph Object

We will use the Environmental, social and corporate governance (ESG) data of the Telecommunication companies as an example data for the Bar Chart example.

The ESG Data is available in Eikon/Refinitiv Workspace desktop application by a query for ESG in the menu.

You can find ESG data fields from Eikon/Refinitiv Workspace Data Item Browser ("DIB") application and then choosing "Environmental, social and corporate governance" content classification.

Firstly, we get the ESG Score data from the TR.TRESGScore field via Eikon Data API get_data() function.

    	
            

# Define RICs list

 

universe = ['VOD.L','TEF.MC','TEL.OL','DTEGn.DE']

 

df_esg,eff = ek.get_data(universe, ['TR.TRESGScore'])

df_esg

Then we create a Plotly Figure for the bar chart with go.Figure interface and go.Bar() class, then pass DataFrame Instrument column as the x-axis and ESG Score column as the y-axis.

Please notice that now we use the Figure update_layout() method to update figure's layout for the chart title.

    	
            

colors = ['#E60000','#003145','#00ACE7','#E10075']

 

fig = go.Figure(go.Bar(x=df_esg['Instrument'], 

                       y=df_esg['ESG Score'],

                       marker_color = colors

                      )) # Create Figure

 

fig.update_xaxes(title_text='Company') # Set X-Axis title

fig.update_yaxes(title_text='ESG Score') # Set &-Axis title

fig.update_layout(title = 'Telecommunication Companies: ESG Score')

fig.show()

However, the ESG Score data alone cannot be used without comparing it with the EST Controversies Score (field TR.TRESGCControversiesScore) and ESG Combined Score (field TR.TRESGCScore).

We will request the Company Name (TR.CompanyName), the ESG Scores to plot a group bar chart.

    	
            

df_esg,eff = ek.get_data(universe, ['TR.CompanyName',

                                    'TR.TRESGScore',

                                    'TR.TRESGCControversiesScore',

                                    'TR.TRESGCScore',

                                    'TR.TRESGCScoreGrade'])

df_esg

Then we create multiple go.Bar objects for each ESG score and pass it to go.Figure. Please notice that we need to set the layout to be a group bar chart via fig.update_layout(barmode='group') statement.

    	
            

fig = go.Figure(data=[

    go.Bar(name='ESG Score', x=df_esg['Company Name'], y=df_esg['ESG Score']),

    go.Bar(name='ESG Controversies Score', x=df_esg['Company Name'], y=df_esg['ESG Controversies Score']),

    go.Bar(name='ESG Combined Score', x=df_esg['Company Name'], y=df_esg['ESG Combined Score'])

])

 

fig.update_layout(barmode='group') # Change the bar mode

fig.update_xaxes(title_text='Company')

fig.update_yaxes(title_text='Environmental, Social and Corporate Governance')

fig.update_layout(title = 'Telecommunication Companies: ESG Scores')

fig.show()

Please see more detail regarding Plotly Graph Object Bar Chart in the following resources:

Candlestick Chart with Plotly Graph Object

The last example is the Candlestick charts using Plotly Graph Object. We will use Bitcoin/US Dollar FX Spot Rate as an example dataset that is suitable for the candlestick chart.

The Bitcoin/US Dollar FX Spot Rate data is available in Eikon/Workspace and Refinitiv Real-Time as BTC= instrument name.

We request 180 daily historical data of BTC= via Eikon Data API get_timeseries function.

    	
            

df_bitcoin = ek.get_timeseries(rics = 'BTC=',interval = 'daily',count = 180)

 

df_bitcoin.head()

Then we re-structure the DataFrame index to change the *Date* column from an index column to a data column.

    	
            

df_bitcoin.reset_index(level=0, inplace=True)

df_bitcoin.head()

Finally, we use the go.Candlestick object to create the candlestick chart from Dataframe, and pass it to go.Figure to create a Plotly Figure object to plot a graph.

    	
            

fig = go.Figure(data=[go.Candlestick(x=df_bitcoin['Date'],

                open=df_bitcoin['OPEN'],

                high=df_bitcoin['HIGH'],

                low=df_bitcoin['LOW'],

                close=df_bitcoin['CLOSE'])])

 

fig.update_xaxes(title_text='Date')

fig.update_yaxes(title_text='Prices')

fig.update_layout(xaxis_rangeslider_visible=True, # Set Range Slider Bar

                 title = 'Bitcoin/US Dollar FX Spot Rate') # Set Title

fig.show()

We can interact with the chart range slider bar too.

Please see more detail regarding Plotly Graph Object Candlestick Chart in the following resources:

Eikon Data API Setup

Please follow a step-by-step guide to set up your Eikon Data API and your AppKey in Eikon Data API Quick Start page.

How to run the example Notebooks

Please note that the Refinitiv Workspace/Eikon application integrates a Data API proxy that acts as an interface between the Eikon Data API Python library and the Eikon Data Platform. For this reason, the Refinitiv Workspace/Eikon application must be running when you use the Eikon Data API Python library.

The first step is to unzip or download the example project folder from GitHub into a directory of your choice, then follow the step-by-step guide in the GitHub repository:

Troubleshooting

Sometimes the classic Jupyter Notebook encounters the problem when you close the notebook window and re-open it, your plots render as blank spaces.

You can check if the notebook document is trusted on the top-right menu of the notebook application.

Please click that button to enable JavaScript for display in this notebook.

As a last resort, you can "Restart & Clear Output" from the Kernel menu and rerun your notebook. You can find more detail on Jupyter Classic Notebook Problems and Troubleshooting pages.

Conclusion

Data visualization is the first impression of data analysis for the readers. Data Scientists, Financial coders, and Developers take time on the data visualization process longer than the time they use for getting the data. It means the data visualization/chart library need to be easy to use, flexible and have a good document.

Plotly Python provides both ease-of-use/high-level and low-level interfaces for supporting a wide range of Developers' skills. Developers can pick the Plotly Chart object (line, bar, scatter, candlestick, etc) that match their requirements, check the Plotly example code and community page to create a nice chart with readable and easy to maintain source code.

When compare to the Matplotlib Pyplot (which is the main player in the Charting library), the Plotly advantages and disadvantages are the following:

Pros

  1. Use a few lines of code to create and customize the graph.
  2. Provide more than 30 ease-of-use various chart object types for Developers.
  3. Experience Developers can use the low-level chart object types to create a more powerful and flexible chart.
  4. Simplify documents and example code.
  5. Provide a dedicated paid support program for both individual and corporate developers.

Cons

  1. Some API Interface and installation processes for Classic Jupyter Notebook and Jupyter Lab are different.
  2. Matplotlib Pyplot has larger users based on developer community websites (such as StackOverflow). It means a lot of Pyplot questions, problems will be easy to find the answers or solutions than Plotly.
  3. Matplotlib Pyplot has larger documents, tutorials, step-by-step guide resources from both official and user-based websites.
  4. The plots render as blank spaces sometimes when you reopen the classic Jupyter Notebook (see troubleshooting page)

At the same time, the Eikon Data API lets developers rapidly access Refinitiv Eikon/Refinitiv Workspace data and our latest platform capabilities with a few lines of code that easy to understand and maintain.

References

You can find more detail regarding the Plotly, Eikon Data APIs, and related technologies from the following resources:

For any question related to this example or Eikon Data API, please use the Developers Community Q&A Forum.

GitHub

 

Plotting Financial Data Chart with Plotly Python GitHub repository.