UK Covid-19 / Coronavirus Data (Python)

Python for looking at UK Covid-19 data

The UK recently lowered the alert level for Covid-19 / Coronavirus pandemic, with the UK at level 3 (at time of writing this blog, 24th June 2020) and there has been discussion in the media about R levels differing at local levels and of the possibility of local lock downs. On the 23rd June 2020 the Prime Minister announced that the daily briefings would becoming to an end.

The UK government publishes the local R rate numbers at: https://www.gov.uk/guidance/the-r-number-in-the-uk and publishes UK Coronavirus figures at: https://coronavirus.data.gov.uk/.

With the Coronavirus causing a lot of changes, and sadly a lot of a deaths, I decided I wanted to look at the data provided via https://coronavirus.data.gov.uk/ to see local figures for the area I live in. To assist me with this task I turned to my favourite language, Python and to use the JSON options of the data.gov.uk website.

The data.gov.uk website can provide data in either CSV or JSON format, and can provide this data for either confirmed cases or deaths. I am currently focusing on looking at the number of confirmed cases.

JSON

The JSON data contains the following sections which may help when sorting/filtering for information:

"areaCode":

"areaName":

"specimenDate":

"dailyLabConfirmedCases":

"previouslyReportedDailyCases":

"changeInDailyCases":

"totalLabConfirmedCases":

"previouslyReportedTotalCases":

"changeInTotalCases":

"dailyTotalLabConfirmedCasesRate":

At the start of my investigation I did not know that areas within the UK had an area code, other than the telephone area code or post code. The area codes can be found at: http://geoportal.statistics.gov.uk/datasets/local-authority-districts-april-2019-names-and-codes-in-the-united-kingdom/data? , however as I did not know of the area codes I went with area name in the current iteration of my program.

Python Program

Please note, as I am trying to improve how I write Python starting with trying to meet PEP-8 standards. Hopefully this will make my code easier to read and to understand.

Python for looking at UK Covid-19 data
Python for looking at UK Covid-19 data

The Python code for this blog post can be found on my GitHub at: https://github.com/geektechdude/python_uk_covid_19_data

I have split my functions into two:

  • local

Reads data from a local JSON file, so that multiple calls do not have to be made to interrogate data, saving on bandwidth and download time.

  • live

Reads the data directly from the government website, which may mean a slower result than the local version as the program has to get the data from the site but does mean the data should be the most up to date version.

For this project I am using three Python modules:
import json

import matplotlib.pyplot as plt

import requests

json to handle the JSON format of the data, MatPlotLib to create a chart (initially a scatter graph) and requests to gather data from the government website.

def covid_live(location="Salford"):

"""Uses latest JSON from data.gov.uk and shows confirmed cases for location from March onwards"""

    json_link = "https://coronavirus.data.gov.uk/downloads/json/coronavirus-cases_latest.json"

    response = requests.get(json_link)

    data = json.loads(response.text)

    for area in data["ltlas"]:

    if area["areaName"]==location:

        print("Date:", area["specimenDate"])

        print("Number of lab confirmed cases:", area["dailyLabConfirmedCases"])

        print("Total number of lab confirmed cases:", area["totalLabConfirmedCases"])

    return



def covid_local(location="Salford"):

"""Uses JSON from local data folder and shows confirmed cases for location from March onwards"""

    withopen("data/coronavirus-cases_latest.json", "r") as data_file:

        data = json.load(data_file)

    for area in data["ltlas"]:

        if area["areaName"] == location:

            print("Date:", area["specimenDate"])

            print("Number of lab confirmed cases:", area["dailyLabConfirmedCases"])

            print("Total number of lab confirmed cases:", area["totalLabConfirmedCases"])

    return

covid_local and covid_live both take a location, and by default I’ve put this in as Salford but it can be any of the locations available via “areaName”. An example would be:

covid_live(“Westminster”)

covid_local(“Westminster”)

def covid_data_download():

"""Downloads latest JSON file from data.gov.uk and saves to data/cornonavirus-cases_latest.json"""

    json_link = "https://coronavirus.data.gov.uk/downloads/json/coronavirus-cases_latest.json"

    response = requests.get(json_link)

    with open("data/coronavirus-cases_latest.json", "w") as data_file:

        json.dump(response.text, data_file)

    return

covid_data_download() downloads the latest JSO/n file and saves it into a folder called data as coronavirus-cases_latest.json

def covid_list_locations_live():

"""Uses latest JSON from data.gov.uk and shows location names"""

    json_link = "https://coronavirus.data.gov.uk/downloads/json/coronavirus-cases_latest.json"

    response = requests.get(json_link)

    data = json.loads(response.text)

    areas = []

    for area in data["ltlas"]:
 
        if area['areaName'] notin areas:

            areas.append(area['areaName'])

            areas_sorted = sorted(areas)

            for location in areas_sorted:

            print(location)

    return



def covid_list_locations_local():

"""Uses JSON from local data folder and shows location names"""

     withopen("data/coronavirus-cases_latest.json", "r") as data_file:

          data = json.load(data_file)

     areas = []

    for area in data["ltlas"]:

         if area['areaName'] notin areas:

             areas.append(area['areaName'])

             areas_sorted = sorted(areas)

    for location in areas_sorted:

         print(location)

    return
covid_list_locations_live()
covid_list_locations_local()

Both return an alphabetically sorted list of areas that can be used as the value for areaName.

def covid_local_chart(location="Salford"):

"""Uses JSON from local data folder, shows confirmed cases in scatter graph for location from March onwards"""

    withopen("data/coronavirus-cases_latest.json", "r") as data_file:

        data = json.load(data_file)

    confirmed_cases = []

    specimen_date = []

    for area in data["ltlas"]:

        if area["areaName"] == location:

            specimen_date.append(area["specimenDate"])

            confirmed_cases.append(area["dailyLabConfirmedCases"])

    plt.scatter(specimen_date, confirmed_cases)

    plt.ylabel('Number of confirmed lab cases')

    plt.xlabel('Date')

    plt.show()

    return



def covid_list_locations_live(location="Salford"):

"""Uses latest JSON from data.gov.uk and shows confirmed cases in scatter graph for location from March onwards"""

    json_link = "https://coronavirus.data.gov.uk/downloads/json/coronavirus-cases_latest.json"

    response = requests.get(json_link)

    data = json.loads(response.text)

    confirmed_cases = []

    specimen_date = []

    for area in data["ltlas"]:

        if area["areaName"] == location:

            specimen_date.append(area["specimenDate"])

            confirmed_cases.append(area["dailyLabConfirmedCases"])

    plt.scatter(specimen_date, confirmed_cases)

    plt.ylabel('Number of confirmed lab cases')

    plt.xlabel('Date')

    plt.show()

    return

covid_list_locations_local()

covid_list_locations_live()

Both take a location (the value for areaName) and default currently default to Salford. Example is covid_list_locations_local(“Westminster”) or covid_list_locations_live(“Westminster”). Both functions use MatPlotLib to output a scatter graph of all daily results. Warning: This can be quite a large chart.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.