Visualizing Worldwide COVID-19 data using Python Plotly Maps | by Bee Guan Teo | Towards Data Science

Note from the editors: Towards Data Science is a Medium publication primarily based on the study of data science and machine learning. We are not health professionals or epidemiologists, and the opinions of this article should not be interpreted as professional advice. To learn more about the coronavirus pandemic, you can click here.
On 31 December 2019, an unknown pneumonia type disease was first reported to the World Health Organization (WHO) Country Office in China. This unknown disease was later named COVID-19 on 11 February 2020 as it is genetically related to the coronavirus which caused the SARS outbreak in 2003. COVID-19 is soon widely spread worldwide until WHO declared the outbreak a Public Health Emergency of International Concern on 30 January 2020.
In this article, I am going to introduce two ways of plotting maps using Python Plotly Libraries to show the distribution of COVID-19 cases around the world.
Python Plotly — https://plotly.com/python/
Python Pandas — https://pandas.pydata.org/
The installation guide can be found on the official webpage.
Novel Corona Virus Dataset
In this section, we are going to use plotly.graph_objects from Plotly libraries to create a scatter plot on a world map to show the distribution of COVID-19 confirmed cases around the world.
Code explanation
Line 1–2: import Pandas and Plotly library
Line 3: The worldwide COVID-19 data can be found in one of the CSV files of the Novel Corona Virus Dataset. We can use the Pandas read_csv method to read the file.
Line 4: Use the Pandas head method to show the first five row of records.
From the result above, we can observe the dataset includes the number of reported COVID-19 cases for each country from 22 Jan 2020 till 13 April 2020 (as of this writing). This dataset is updated on a daily basis. Unfortunately, there is a lack of province/state details in the dataset. We can see there are lots of NaN values in the Province/State column.
To ease our subsequent task to manipulate the column and plot the map, this is recommended to simplify some column names (e.g. Country/Region).
Code explanation
Line 5: We can use the Pandas rename method to change the column name “Country/Region” to “Country” and “Province/State” to “Province”.
Line 6: We use the Pandas head method to view the records again after renaming the columns.
We can now proceed to use Python Plotly library to create a scatter plot on a map using plotly.graph_objects.
The codes (Line 8 - 39) can seem daunting in the first place. Don’t worry, they are just the parameters we need to set for the map and the information about the parameters can be found at the Plotly reference page. Here I will only discuss several important parameters.
Code explanation
Line 8: Set text elements that will appear over the data points. This means when we hover over a data point on the map, the predefined text (e.g. Country Name + number of cases on 4 Apr 20) will be poped up.
Line 10–11: lon and lat are the parameters that we set for longitude and latitude of each data point on the map.
Line 14–23: marker is a representation of data points on the map. Here we set the symbol (Line 19) as square. This will render each data point as a square on the map. We can leave the reversescale and autocolorscale as True to enable the color of markers automatically changed by the number of reported COVID-19 cases.
Line 24–26: cmin and cmax are the lower bound and upper bound of the color domain for the data points.
Line 31–37: This is the part where we set the parameter values for the entire map such as the map title (Line 32) and more importantly the scope (Line 34). If we intend to show the worldwide data on the map, we need to set the scope as “world” and Plotly will generate a world map. If our purpose is just to show the data points only on the US, we can set the scope as “usa”. We can pick one of the following scope options:
world
usa
europe
africa
north america
south america
Line 39: fig.write_html will generate a HTML page that shows the scatter map.
Note: This is possible to display the map on Jupyter Notebook or Jupyter Lab instead of on a separate HTML page. To do so, we have to install an extension for our Jupyter Notebook / Jupyter Lab (https://plotly.com/python/getting-started/).
The scatterplot above gives us a general idea of reported cases of COVID-19 around the world on 13 April 2020. The markers with yellowish color reflect the relatively lower reported cases compared with those darker colors. From the map, we can see the US hits the most reported cases and it is followed by some countries in Europe such as Italy, UK, French, etc. When we hover over a data point on the map, we can see a predefined pop-up text which reveals the country name and number of reported cases associated with that data point.
We can also use the same dataset to plot a choropleth map using plotly.graph_objects. However, we will need to preprocess our data before we can proceed to create the choropleth map.
To create the choropleth map, we need to derive two pieces of info from our dataset:
A unique country listTotal reported COVID-19 cases for each country (13 Apr 2020)
A unique country list
Total reported COVID-19 cases for each country (13 Apr 2020)
Unfortunately, we can’t directly extract the two required pieces of info from the original datasets. Just look closely at our dataset again by previewing some records.
We could have two observations from our dataset as below:
There are duplicated country names in our record. This is because the given number of reported COVID-19 cases are broken down into several provinces/states that could belong to the same country.Each row of the reported COVID-19 case on 13 Apr 2020 is just the subtotal of cases that happen in each individual province or state in a country.
There are duplicated country names in our record. This is because the given number of reported COVID-19 cases are broken down into several provinces/states that could belong to the same country.
Each row of the reported COVID-19 case on 13 Apr 2020 is just the subtotal of cases that happen in each individual province or state in a country.
The two observations above can be seen intermittently when we traverse through the records country by country. This means the records on the original dataset are not consistent. There are some records that entail a breakdown of states in a country whereas some others only cover a single row of data for a whole nation.
Fortunately, there is a simple fix here. We can use Pandas library to restructure our data.
Code explanation
Line 1–5: These are the steps to import necessary Plotly and Pandas libraries, to read the CSV file and also to rename some columns.
Line 7: We can use Pandas groupby method to group our data based on the country and apply the sum method to calculate the total of reported cases for each country. The result is a list of sums and we assign it to a variable named total_list.
Line 9–13: We are going to clean the country list and generate a list of unique countries.
Firstly, use tolist method to convert the Country column to a list object and assign it to the variable country_list (Line 9).
Next, use set method to convert the country_list into a Python set object. The set method will automatically remove all the duplicated country names from the country_list. Only the unique country names will be stored in country_set (Line 10).
Next, convert the country_set to a list again and assign it back to country_list (Line 11).
Use sort method to rearrange the country_list following the alphabetical order (Line 12). *This step is required because the previously used set method will randomize the sequence of countries.
Line 14: At last, we create a new dataframe by using the country_list and total_list generated from previous steps as the only two columns in the new dataframe.
We have managed to restructure our data and store it into a new dataframe, new_df. The new_df includes the data we need (unique country list and total cases for each country) to generate a choropleth map and we are now ready to move on to the next step.
A choropleth map is a map that consists of colored polygons to represent spatial variations of a quantity. We are going to use go.Choropleth graph object to create a choropleth map that shows the distribution of reported COVID-19 cases around the world.
Again, the code can seem daunting in the first place. However, they are nothing more than setting parameters to build a choropleth map. We can refer to the reference page on the official website to gain further info about the parameters.
Code explanation
Line 17–19: We can define a color domain for our choropleth map. To define a color domain, we just create a list of Hexa color codes. (*The color codes can be obtained here).
Line 22–33: This is the part where we can set the parameters for the location list, color domain, text info displayed on the map, maker line color, etc.
Since we plot the map to show the COVID-19 cases around the world, we set the locationmode to “country names”. This enables us to set the Country column from new_df to locations parameter (Line 23–24). This is an important step to enable Plotly to map our COVID-19 data to their respective country location on the choropleth map. (*Please note that there is no coordinate, lat & long, are required).
We set the Total_Cases data from new_df to parameter z (Line 25). This is another crucial step to enable Plotly to reveal the frequency of reported cases based on a color domain applied to the choropleth map.
We can also set the “Total_Cases” to the text parameter (Line 26). This will display the total number of cases in a popup text whenever we hover over one of the country regions on the map.
Since we have defined our own color domain (Line 17–19), we can just set the parameter autocolorscale as false (Line 28).
We also set a title for the color bar (Line 30).
Line 33–37: Here, we simply set a title for the map and enable the coastline shown on the map.
Line 40: Output the map to a HTML page.
Finally, we have managed to create a Choropleth Map that shows an overview of the prevalence level of the coronavirus outbreak around the world. When we place our mouse on top of one of the country regions, we can see the number of reported cases shown in a popup text.
Have you ever wondered we can publish our map online? Plotly offers us an option to share our Map with the public free of charge. To do so, we just need to follow several simple steps below:
Open your Terminal (Mac)or Command Prompt (Windows), hit
pip install chart_studioorsudo pip install chart_studio
Visit Chart Studio Page and sign up for a free account. This process will only take less than 3 minutes. A free account allows us to share a maximum of 100 charts with the public.
After signing up a free Chart Studio account, visit the Setting page and look for API Keys. Copy the API Key and paste it at the top of our previous Python code (either Scatter Map or Choropleth Map).
Line 1–2: These two lines of code are to provide credential info to enable our Python program to access the Chart Studio features.
To share our map to the public, all we need is just to add one line of code at the last line (Line 42) of the existing Python program.
Run the code and Plotly will return a URL that redirects us to a web site that hosts our map.
You can view my shared Scatter Map at this link1 and Choropleth Map at this link 2.
Python Plotly is an easy to use chart plotting library that enables us to create stunning charts and share them with the public. This is definitely worthwhile to invest our time in learning Plotly and use it to accomplish our data visualization tasks. If you are interested in learning more about the Plotly library, a useful tutorial can be found on this blog post.
I wish this article can be one of the helpful reference sources for you.
Follow me on MediumConnect and reach me on LinkedIn
Follow me on Medium
Connect and reach me on LinkedIn
All the sources codes presented in this article are available in the GitHub repository.