Files
coronavis/country_details.py
2021-01-05 10:17:41 +01:00

178 lines
8.6 KiB
Python

"""
Plot detailed figures for each country
"""
import matplotlib.pyplot as pp
from mpl_toolkits.axisartist.parasite_axes import HostAxes, ParasiteAxes
import numpy as np
import time as time_module
import pickle
import logging
logging.getLogger().setLevel(logging.CRITICAL)
import os
def plot(data, countries, pop, metadata, **kwargs):
figsize = (10,5)
for loc in data:
if loc == "International":
continue
if loc == "World":
continue
path = "img/"+f"{loc}".replace(" ", "_").replace("'", "").replace("/", "")
if not os.path.isdir(path):
os.mkdir(path)
if not os.path.isfile(path+"/index.html") or True: # TODO enable html file generation
with open(path+"/index.html", "w") as f:
f.write(f"""
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="https://dukun.de/corona/style.css">
<link rel="icon" type="image/vnd.microsoft.icon" href="favicon.ico">
<meta name="robots" content="noindex,nofollow" />
<title>CoVid19 in {loc}</title>
</head>
<body class=box>
<div class=head>
<h3>Details zu {loc}</h3>
</div>
<a href=https://dukun.de/corona>Zurück</a><br><br>
<details open><summary><h4>Landesspezifische Kennzahlen</h4></summary>
<table>
<tr><td>ISO Code</td><td>{metadata[loc]["iso_code"]}</td></tr>
<tr><td>Continent</td><td>{metadata[loc]["continent"]}</td></tr>
<tr><td>Country name</td><td>{metadata[loc]["location"]}</td></tr>
<tr><td>Population</td><td>{metadata[loc]["population"]}</td></tr>
<tr><td>Population density</td><td>{metadata[loc]["population_density"]}</td></tr>
<tr><td>Median age</td><td>{metadata[loc]["median_age"]}</td></tr>
<tr><td>% older than 65</td><td>{metadata[loc]["aged_65_older"]}</td></tr>
<tr><td>% older than 70</td><td>{metadata[loc]["aged_70_older"]}</td></tr>
<tr><td>GDP per capita</td><td>{metadata[loc]["gdp_per_capita"]}</td></tr>
<tr><td>Extreme poverty</td><td>{metadata[loc]["extreme_poverty"]}</td></tr>
<tr><td>Cardiovascular death rate</td><td>{metadata[loc]["cardiovasc_death_rate"]}</td></tr>
<tr><td>Diabetes prevalence</td><td>{metadata[loc]["diabetes_prevalence"]}</td></tr>
<tr><td>female smokers (%)</td><td>{metadata[loc]["female_smokers"]}</td></tr>
<tr><td>male smokers (%)</td><td>{metadata[loc]["male_smokers"]}</td></tr>
<tr><td>Handwashing facilities</td><td>{metadata[loc]["handwashing_facilities"]}</td></tr>
<tr><td>hospital beds per thousand inhabitants</td><td>{metadata[loc]["hospital_beds_per_thousand"]}</td></tr>
<tr><td>life expectancy</td><td>{metadata[loc]["life_expectancy"]}</td></tr>
<tr><td>human development index</td><td>{metadata[loc]["human_development_index"]}</td></tr>
</table>
</details>
<details open><summary>Übersicht</summary><img src=https://dukun.de/corona/img/ac_all_{loc.replace(" ", "%20")}.png /></details>
<details open><summary>Krankenhaussituation</summary><img src=https://dukun.de/corona/{path}/hospitals.png /></details>
<details open><summary>Testsituation</summary><img src=https://dukun.de/corona/{path}/tests.png /></details>
<br><br>
<a href=https://dukun.de/corona>Zurück</a><br>
</div>
<div class=foot>
Ein Infoservice von <a href=dukun.de>dukun.de</a>; Anregungen gern <a href="mailto:&#099;&#111;&#114;&#111;&#110;&#097;&#105;&#110;&#112;&#117;&#116;&#064;&#100;&#117;&#107;&#117;&#110;&#046;&#100;&#101;">per Mail</a>; Proudly made with Python, Matplotlib, Numpy
</div>
</body>
</html>""")
# extract data
time = data[loc]['time']
new_cases = data[loc]['new_cases']
new_deaths = data[loc]['new_deaths']
total_cases = data[loc]['total_cases']
total_deaths = data[loc]['total_deaths']
total_vaccinations = data[loc]['total_vaccinations']
stringency_index = data[loc]['stringency_index']
reproduction_rate = data[loc]['reproduction_rate']
icu_patients = data[loc]['icu_patients']
hosp_patients = data[loc]['hosp_patients']
weekly_icu_admissions = data[loc]['weekly_icu_admissions']
weekly_hosp_admissions = data[loc]['weekly_hosp_admissions']
new_tests = data[loc]['new_tests']
total_tests = data[loc]['total_tests']
positive_rate = data[loc]['positive_rate']
tests_per_case = data[loc]['tests_per_case']
tests_units = data[loc]['tests_units']
# plots
############### hospital occupation
if True:
fig, ax1 = pp.subplots(num=loc+"_hospitalization", figsize=figsize)
ax2 = ax1.twinx()
icu_map = ~np.isnan(weekly_icu_admissions)
hosp_map = ~np.isnan(weekly_hosp_admissions)
if not np.isnan(icu_patients).all() :
ax2.plot(time, icu_patients, color="blue", label="ICU patients")
if not np.isnan(hosp_patients).all() :
ax2.plot(time, hosp_patients, color="green", label="Hospitalized patients")
if not np.isnan(weekly_icu_admissions).all() :
ax1.plot(np.array(time)[icu_map], np.array(weekly_icu_admissions)[icu_map], color="blue", linestyle="--", label="weekly ICU admissions")
if not np.isnan(weekly_hosp_admissions).all() :
ax1.plot(np.array(time)[hosp_map], np.array(weekly_hosp_admissions)[hosp_map], color="green", linestyle="--", label="weekly hospital admissions")
axbounds = ax2.axis()
if metadata[loc]["hospital_beds_per_thousand"] == "" or metadata[loc]["population"] == "":
pass
else:
hospital_beds = float(metadata[loc]["hospital_beds_per_thousand"]) * float(metadata[loc]["population"]) / 1000
ax2.plot([axbounds[0], axbounds[1]], [hospital_beds]*2, color="k", label=f"total hospital beds: {hospital_beds:1.0f}")
ax2.axis(axbounds)
ax1.set_ylabel("admissions")
ax2.set_ylabel("patients")
fig.legend(frameon=False, loc="upper left", bbox_to_anchor=(0,1), bbox_transform=ax1.transAxes)
ax1.set_title(f"Hospital situation in {loc}")
pp.text(0.002,0.005, f"plot generated {time_module.strftime('%Y-%m-%d %H:%M')}, CC-by-sa-nc, origin: dukun.de/corona, datasource: ourworldindata.org/coronavirus-source-data", color="dimgrey", fontsize=8, transform=fig.transFigure)
pp.savefig(path+"/hospitals.png")
pp.close(fig)
############## test situation
if True:
fig, ax1 = pp.subplots(num=loc+"_tests", figsize=figsize)
ax2 = ax1.twinx()
if set(tests_units) == {''}:
testunit = "unknown"
elif len(set(tests_units).difference({''})) == 1:
testunit = set(tests_units).difference({''}) .pop()
else:
testunit = "changing"
print(loc, set(tests_units))
if np.isnan(new_tests).all() and not np.isnan(total_tests).all():
ttest_map = ~np.isnan(total_tests)
total_tests = np.array(total_tests)
new_tests = (total_tests[ttest_map][1:] - total_tests[ttest_map][:-1])/7.
ax1.plot(np.array(time)[ttest_map][1:], new_tests, color="blue", linestyle="-", linewidth=2, label="new tests")
elif not np.isnan(new_tests).all() :
ntest_map = ~np.isnan(new_tests)
ax1.plot(np.array(time)[ntest_map], np.array(new_tests)[ntest_map]/7, color="grey", linestyle="--", label="new tests")
ax1.plot(np.array(time)[ntest_map][3:-3], np.convolve(np.array(new_tests)[ntest_map], np.ones((7,))/7, mode="valid")/7, color="blue", linewidth=2, label="new tests 7day mean")
if not np.isnan(positive_rate).all():
prate_map = ~np.isnan(positive_rate)
ax2.plot(np.array(time)[prate_map], np.array(positive_rate)[prate_map]*100, color="black", linestyle="-", linewidth=2, label="positive rate (%)")
ax1.set_ylabel(f"tests (unit: {testunit})")
ax2.set_ylabel("positive rate")
fig.legend(frameon=False, loc="upper left", bbox_to_anchor=(0,1), bbox_transform=ax1.transAxes)
ax1.set_title(f"Test situation in {loc}")
pp.text(0.002,0.005, f"plot generated {time_module.strftime('%Y-%m-%d %H:%M')}, CC-by-sa-nc, origin: dukun.de/corona, datasource: ourworldindata.org/coronavirus-source-data", color="dimgrey", fontsize=8, transform=fig.transFigure)
pp.savefig(path+"/tests.png")
pp.close(fig)
if __name__ == "__main__":
import pickle
with open("20201221-data-metadata.dmp", "rb") as f:
data, metadata = pickle.load(f)
plot(data, [], {}, metadata=metadata)