Data visualization with Plotly:COVID-19 data
By: Tariq Munir
Tags: Covid 19, Data Visualization, Python, Plotly

Data visualization with Plotly: Covid-19 dataset

Time lapse of COVID-19 spread as at July 27, 2020. Created using Plotly.

Being on a self-learning journey on Data Science and Python, I have been inundated with a plethora of resources which keep on evolving every second. These are all very important sources of information and we are lucky to have access to such a vast and free knowledge resource.

However, sometimes you just need to take a step back and focus on basics by learning, sharing and hence growing it. This article is exactly about that. A very basic and simplistic approach to Plotly visualization using COVID-19 data that I am sharing as part of my stay-at-home Easter break project! As once a mentor of mine said to me:“…if you want to never stop learning, try to teach what you know…”

Here I will share only two things, firstly, the basic coding used for plotting and secondly, reference to documentation so you can go and experiment.

Before I go into the coding part, I just want to clarify that this article is only intended as an educational project. Therefore, I have not tried at all to calculate any mortality, growth or survival rates of the pandemic. As we are all in this together, so it is very important that this kind of sensitive information is calculated and shared with great caution and best handled using appropriate knowledge of the field. Please refer to authentic sources of information for any point of views or information about COVID-19.

What is it about then:

Simply put, “Plotly is an interactive, open-source and browser-based graphing library for Python”. It comes with various cool looking chart types (bar, line scatter, geo map etc.) and I personally found it very user friendly and have plenty of easy to understand documentation. Strongly encourage you to go through it when building any code on https://plotly.com/python/.

First install relevant libraries:

!pip install plotly_express==0.4.1

import plotly.express as px

import plotly.graph_objects as go #for calling graph objects from plotly library.

I used COVID-19 cases data from https://data.humdata.org/ and is compiled by the Johns Hopkins University Center for Systems Science and Engineering (JHU CCSE). Using various techniques the data is simplified into below columns. Please do note that I am assuming a basic Python skills for this.

Data converted into simple form

In the above data x=Dates, y=infected, z= deaths, w= recovered. Now y-z-w gives us active cases as well just for demonstration on bar chart for this article.

We used go.figure() function (imported as ‘go’ normally) to call graphing object in Plotly. Within Plotly graph objects we may divide it into two categories: Traces and Layout. There are then further attributes within both Traces and Layout that define our chart. Do refer https://plotly.com/python/reference/ for list of all attributes and then play around with those.

Bar Charts

To overlay bar charts, I used the go.figure() function from Plotly to call chart objects and then added further bar traces (for each column in my data ) and layered them over the charts:

#call Bar charts and assign to fig_t. Add traces to the same figure

fig_t = go.Figure(go.Bar(x=x, y=y, name='Total Infected', marker_color='indianred', opacity=.8))

fig_t.add_trace(go.Bar(x=x, y=y-z-w, name='Total Active', marker_color='mediumblue', opacity=0.7))

fig_t.add_trace(go.Bar(x=x, y=w, name='Total recovered', marker_color='lightseagreen', opacity=0.8))

fig_t.add_trace(go.Bar(x=x, y=z, name='Total deaths', marker_color='gray', opacity=1)) #here we define layout of the chart

fig_t.update_layout(barmode='overlay', xaxis={'categoryorder':'total ascending'},xaxis_type='category',

title={

'text': 'Cummulative COVID-19 world trend',

'y':0.79,

'x':0.45,

'xanchor': 'center',

'yanchor': 'top'},)

fig_t.update_xaxes(title= '----->Timeline' ,showline=True)

fig_t.update_yaxes(title= '----->Number of cases', showline=True)

fig_t.show()

Output:

An interactive plotly chart. Please do note if you change the trace type in the code above you can add lines, scatter etc. on the same plot.

Line & marker

To analyse a daily change in number of cases I simply used a diff() function on the cumulative data above. Now in order to demonstrate it differently, the ‘Line’ trace is used in this one:

#call Line charts and assign to fig_inc. Add traces to the same figure

fig_inc = go.Figure(go.Line(x=df_diff['Dates'], y=df_diff['Total_infected'],name='Infected', mode='lines+markers',marker=dict(size=10,color='indianred')))

fig_inc.add_trace(go.Line(x=df_diff['Dates'], y=df_diff['Total_recovered'],name='Recovered', mode='lines+markers',marker=dict(size=10,color='lightseagreen')))

fig_inc.add_trace(go.Line(x=df_diff['Dates'], y=df_diff['Total_deaths'], name='Deaths', mode='lines+markers',marker=dict(size=10,color='gray')))

fig_inc.add_trace(go.Line(x=df_diff['Dates'], y=df_diff['Active'], name='Active', mode='lines+markers',marker=dict(size=10,color='Orange'))) #here we define layout of the chart

fig_inc.update_layout(xaxis_showgrid=True, yaxis_showgrid=True, plot_bgcolor='whitesmoke',

title={

'text': 'Incremental COVID-19 world trend',

'y':0.75,

'x':0.5,

'xanchor': 'center',

'yanchor': 'top'},xaxis_type='category')

fig_inc.update_xaxes(title= '------>Timeline' ,showline=False)

fig_inc.update_yaxes(title= '------>Number of incremental cases', showline=False)



fig_inc.show()

Output:

An interactive line chart with various options to analyse.

Animated Geo Scatter map

One of the coolest feature that made me a fan of Plotly is its easy to use animation. You really don’t have to do a lot of coding to animate a simple map like the one shared above in the video. There is a number of built-in features that you can explore through the documentation.

For this one, I imported Plotly Express (as “px”) which is an interface that comes with plotly. This works on what they call “tidy” or “narrow” data and works with Pandas dataframe, lists, numpy arrays, pandas series etc.

Again the basic principle of graph objects and then layout remains the same. However, in this case, the layout attributes are defined in detail further down the configuration and can be changed. Please refer https://plotly.com/python/reference/#layout-sliders and play around with different attributes to see how it changes the map.

The video shared above is basically a time lapse of Covid-19 spread using the narrow data form from the same JHU CCSE data source I shared above.

#call scatter_mapbox function from px. Note the attributes especially normalisation of data and maximum maker size. The animation is done on Dates.

fig_map = px.scatter_mapbox(df_map, lat="Lat", lon="Long", color="Infected", size=df_map['Norm']**0.5*50,

color_continuous_scale="Rainbow", size_max=50, animation_frame='Date',

center=dict({'lat': 32, 'lon': 4}), zoom=0.7, hover_data= ['Country']) #here on wards various layouts have been called in to bring it in the present shape

fig_map.update_layout(mapbox_style="carto-positron",width=900,

height=700)

fig_map.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) #update frame speed

fig_map.layout.updatemenus[0].buttons[0].args[1]["frame"]["duration"] = 200 #update different layouts

fig_map.layout.sliders[0].currentvalue.xanchor="left"

fig_map.layout.sliders[0].currentvalue.offset=-100

fig_map.layout.sliders[0].currentvalue.prefix=""

fig_map.layout.sliders[0].len=.9

fig_map.layout.sliders[0].currentvalue.font.color="indianred"

fig_map.layout.sliders[0].currentvalue.font.size=20

fig_map.layout.sliders[0].y= 1.1

fig_map.layout.sliders[0].x= 0.15

fig_map.layout.updatemenus[0].y=1.27

fig_map.show()

Output:

As you can see above, I have played around the Sliders’ x and y positioning to improvise the Date (i.e. Current value) overlapping on the chart.

Hope you liked the brief overview of Plotly and how you can create some simple but cool looking charts using it.