Diagrams commissioned for the paper: *The Operational Loops of a Pandemic.* by T. D. Sampson and J. Parikka.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
2.8 KiB

# %%
import pandas as pd
import requests
import matplotlib.pyplot as plt
import matplotlib
import json
from scipy import interpolate
import numpy as np
# %% Use LaTeX, XXX might not need this
plt.rc('text', usetex=True)
plt.rc('font', family='serif')
# %% Function to convert sizes in cm for figure size
def cm2inch(*tupl):
inch = 2.54
if isinstance(tupl[0], tuple):
return tuple(i/inch for i in tupl[0])
return tuple(i/inch for i in tupl)
# %% Countries
countries = {
'uk': {'name': 'UK'}
# %% Data
for country_code, country_data in countries.items():
request_url = 'https://disease.sh/v3/covid-19/historical/' + country_code + '?lastdays=all'
r = requests.get(request_url)
x = r.json()
df = pd.DataFrame(x['timeline'])
df.index = pd.to_datetime(df.index)
# Process data
df['daily_cases'] = df['cases'].diff().abs() # .abs() dirty trick to prevent negative outliers
df['daily_cases_avg'] = df['daily_cases'].rolling(7).mean()
df['cases_change'] = df['daily_cases_avg'].diff()
# Smoothing
df = df.resample('4H').asfreq()
df = df.interpolate(method='spline', order=5)
country_data['dataframe'] = df
# %% Plotting
fig, ax = plt.subplots(figsize=cm2inch(15,15))
for country_code, country_data in countries.items():
df = country_data['dataframe']
line, = ax.plot(
lw=0.5, c='b', label=country_data['name'])
# select which dates to label
df['month'] = df.index.month
df['month_change'] = df['month'].diff()
month_start = df['month_change'] == 1
mar_onwards = df['month'] >= 3
labeldates = pd.concat([df[month_start & mar_onwards], df.tail(1)])
# date labels
for index, row in labeldates.iterrows():
date_text = row.name.strftime(format='%d/%m')
xy=(row['cases_change'], row['daily_cases_avg']),
textcoords='offset points',
# to use same color as current cuvre: color=line.get_color()
# to add background: bbox=dict(boxstyle='square, pad=0.5', alpha=0.7, fc='white', ec='white')
# date markers
ax.scatter(row['cases_change'], row['daily_cases_avg'], color='k', s=10)
# Date legend
ax.scatter(1150, 0, color='k', s=10)
ax.annotate('Dates: day/month 2020', xy=(220,12), xycoords='axes points')
# Line at x=0
plt.axvline(x=0, c='black', lw=1, ls=':')
# remove frame
ax.set(ylabel="UK Daily COVID-19 Cases", xlabel="Increase or decrease in cases per day")
#ax.legend(loc='upper center', ncol=3, bbox_to_anchor=(0.5,1.15))
# %%