From b15718ec88e4ba471a2d3c4059218e946882d4d6 Mon Sep 17 00:00:00 2001 From: fordprefect Date: Mon, 21 Dec 2020 16:59:47 +0100 Subject: [PATCH] add a separate page for each country with information on testing and hospitalization, link these pages in the index. also required some fixing in the data aquisition --- .gitignore | 2 + coronavis.py | 16 +- country_details.py | 177 +++++++++++++++ index.html | 530 ++++++++++++++++++++++----------------------- 4 files changed, 451 insertions(+), 274 deletions(-) create mode 100644 country_details.py diff --git a/.gitignore b/.gitignore index ca42f8f..9a578c6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ *png *xz __pycache__ +img/* +data/* diff --git a/coronavis.py b/coronavis.py index 129b0b6..adea930 100644 --- a/coronavis.py +++ b/coronavis.py @@ -40,7 +40,6 @@ metadata_fields = [ "hospital_beds_per_thousand", "life_expectancy", "human_development_index", - "tests_units", ] ### manual data @@ -128,6 +127,7 @@ def get_data(): total_tests = tofloat(total_tests) positive_rate = tofloat(positive_rate) tests_per_case = tofloat(tests_per_case) + tests_units = tests_units if location not in data: data[location] = [] @@ -138,7 +138,7 @@ def get_data(): new_cases, new_deaths, total_cases, total_deaths, total_vaccinations, stringency_index, reproduction_rate, icu_patients, hosp_patients, weekly_icu_admissions, weekly_hosp_admissions, new_tests, - total_tests, positive_rate, tests_per_case,] + total_tests, positive_rate, tests_per_case, tests_units,] ) @@ -152,7 +152,6 @@ def get_data(): else: if metadata[location][field] != row[n]: print(f"{location}: {field} seems not to be a constant ({metadata[location][field]} vs {row[n]})") - # reorganize data data2 = {} for loc in data: @@ -167,8 +166,9 @@ def get_data(): total_tests = [] positive_rate = [] tests_per_case = [] + tests_units = [] for entry in data[loc]: - t_, new_cases_, new_deaths_, total_cases_, total_deaths_, total_vaccinations_, stringency_index_, reproduction_rate_, icu_patients_, hosp_patients_, weekly_icu_admissions_, weekly_hosp_admissions_, new_tests_, total_tests_, positive_rate_, tests_per_case = entry + t_, new_cases_, new_deaths_, total_cases_, total_deaths_, total_vaccinations_, stringency_index_, reproduction_rate_, icu_patients_, hosp_patients_, weekly_icu_admissions_, weekly_hosp_admissions_, new_tests_, total_tests_, positive_rate_, tests_per_case_, tests_units_ = entry time.append(t_) new_cases.append(toint(new_cases_)) @@ -177,15 +177,16 @@ def get_data(): total_deaths.append(toint(total_deaths_)) total_vaccinations.append(toint(total_vaccinations_)) stringency_index.append(toint(stringency_index_)) - reproduction_rate.append(toint(reproduction_rate_)) + reproduction_rate.append(reproduction_rate_) icu_patients.append(toint(icu_patients_)) hosp_patients.append(toint(hosp_patients_)) weekly_icu_admissions.append(toint(weekly_icu_admissions_)) weekly_hosp_admissions.append(toint(weekly_hosp_admissions_)) new_tests.append(toint(new_tests_)) total_tests.append(toint(total_tests_)) - positive_rate.append(toint(positive_rate_)) - tests_per_case.append(toint(tests_per_case_)) + positive_rate.append(positive_rate_) + tests_per_case.append(tests_per_case_) + tests_units.append(tests_units_) data2[loc] = {'time': time, 'new_cases': new_cases, 'new_deaths': new_deaths, @@ -202,6 +203,7 @@ def get_data(): 'total_tests': total_tests, 'positive_rate': positive_rate, 'tests_per_case': tests_per_case, + 'tests_units': tests_units, } return data2, metadata diff --git a/country_details.py b/country_details.py new file mode 100644 index 0000000..a212bf3 --- /dev/null +++ b/country_details.py @@ -0,0 +1,177 @@ +""" +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, **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""" + + + + + + +CoVid19 in {loc} + + +
+

Details zu {loc}

+
+Zurück

+ +

Landesspezifische Kennzahlen

+ + + + + + + + + + + + + + + + + + + +
ISO Code{metadata[loc]["iso_code"]}
Continent{metadata[loc]["continent"]}
Country name{metadata[loc]["location"]}
Population{metadata[loc]["population"]}
Population density{metadata[loc]["population_density"]}
Median age{metadata[loc]["median_age"]}
% older than 65{metadata[loc]["aged_65_older"]}
% older than 70{metadata[loc]["aged_70_older"]}
GDP per capita{metadata[loc]["gdp_per_capita"]}
Extreme poverty{metadata[loc]["extreme_poverty"]}
Cardiovascular death rate{metadata[loc]["cardiovasc_death_rate"]}
Diabetes prevalence{metadata[loc]["diabetes_prevalence"]}
female smokers (%){metadata[loc]["female_smokers"]}
male smokers (%){metadata[loc]["male_smokers"]}
Handwashing facilities{metadata[loc]["handwashing_facilities"]}
hospital beds per thousand inhabitants{metadata[loc]["hospital_beds_per_thousand"]}
life expectancy{metadata[loc]["life_expectancy"]}
human development index{metadata[loc]["human_development_index"]}
+
+ +
Übersicht
+
Krankenhaussituation
+
Testsituation
+ +

+Zurück
+ +
+Ein Infoservice von dukun.de; Anregungen gern per Mail; Proudly made with Python, Matplotlib, Numpy +
+ +""") + + # 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) diff --git a/index.html b/index.html index d968f75..2b53ba6 100644 --- a/index.html +++ b/index.html @@ -29,28 +29,6 @@ Von den extrem reichhaltigen Daten dort verarbeite ich nur die Zahl der Neufäll

Aktuelle Daten aus Deutschland mit vielen Hintergründen finden sich im Lagebericht des RKI. -
-

Basics

-
- Absolute Fälle - -
- -
Neue Fälle - -
- -
- Absolute Todesfälle - -
- -
- Neue Todesfälle - -
-
-

Ausgewählte Länder

@@ -70,44 +48,44 @@ Di Plots werden immer komplexer, daher hier eine kurze Zusammenfassung der sicht
Deutschland und europäische Nachbarn -
Germany
-
Austria
-
Belgium
-
Czech Republic
-
Denmark
-
France
-
Italy
-
Liechtenstein
-
Luxembourg
-
Netherlands
-
Norway
-
Poland
-
Russia
-
Spain
-
Sweden
-
Switzerland
+
Germany
+
Austria
+
Belgium
+
Czech Republic
+
Denmark
+
France
+
Italy
+
Liechtenstein
+
Luxembourg
+
Netherlands
+
Norway
+
Poland
+
Russia
+
Spain
+
Sweden
+
Switzerland
-
Argentina
-
Australia
-
Bolivia
-
Brazil
-
Canada
-
Chile
-
China
-
Ecuador
-
India
-
Indonesia
-
Iran
-
Israel
-
Japan
-
New Zealand
-
Nigeria
-
Singapore
-
South Korea
-
Turkey
-
United Kingdom
-
United States
+
Argentina
+
Australia
+
Bolivia
+
Brazil
+
Canada
+
Chile
+
China
+
Ecuador
+
India
+
Indonesia
+
Iran
+
Israel
+
Japan
+
New Zealand
+
Nigeria
+
Singapore
+
South Korea
+
Turkey
+
United Kingdom
+
United States
World
@@ -116,216 +94,215 @@ Di Plots werden immer komplexer, daher hier eine kurze Zusammenfassung der sicht Achtung! Die Datenqualität variiert zwischen den Ländern enorm, damit sind einzelne Länder auch nur schwer miteinander zu vergleichen!
-
Afghanistan
-
Albania
-
Algeria
-
Andorra
-
Angola
-
Anguilla
-
Antigua and Barbuda
-
Argentina
-
Armenia
-
Aruba
-
Australia
-
Austria
-
Azerbaijan
-
Bahamas
-
Bahrain
-
Bangladesh
-
Barbados
-
Belarus
-
Belgium
-
Belize
-
Benin
-
Bermuda
-
Bhutan
-
Bolivia
-
Bonaire Sint Eustatius and Saba
-
Bosnia and Herzegovina
-
Botswana
-
Brazil
-
British Virgin Islands
-
Brunei
-
Bulgaria
-
Burkina Faso
-
Burundi
-
Cambodia
-
Cameroon
-
Canada
-
Cape Verde
-
Cayman Islands
-
Central African Republic
-
Chad
-
Chile
-
China
-
Colombia
-
Comoros
-
Congo
-
Costa Rica
-
Croatia
-
Cuba
-
Curacao
-
Cyprus
-
Czech Republic
-
Democratic Republic of Congo
-
Denmark
-
Djibouti
-
Dominican Republic
-
Dominica
-
Ecuador
-
Egypt
-
El Salvador
-
Equatorial Guinea
-
Eritrea
-
Estonia
-
Ethiopia
-
Faeroe Islands
-
Falkland Islands
-
Fiji
-
Finland
-
France
-
French Polynesia
-
Gabon
-
Gambia
-
Georgia
-
Germany
-
Ghana
-
Gibraltar
-
Greece
-
Greenland
-
Grenada
-
Guam
-
Guatemala
-
Guernsey
-
Guinea-Bissau
-
Guinea
-
Guyana
-
Haiti
-
Honduras
-
Hungary
-
Iceland
-
India
-
Indonesia
- -
Iran
-
Iraq
-
Ireland
-
Isle of Man
-
Israel
-
Italy
-
Jamaica
-
Japan
-
Jersey
-
Jordan
-
Kazakhstan
-
Kenya
-
Kosovo
-
Kuwait
-
Kyrgyzstan
-
Laos
-
Latvia
-
Lebanon
-
Lesotho
-
Liberia
-
Libya
-
Liechtenstein
-
Lithuania
-
Luxembourg
-
North Macedonia
-
Madagascar
-
Malawi
-
Malaysia
-
Maldives
-
Mali
-
Malta
-
Mauritania
-
Mauritius
-
Mexico
-
Moldova
-
Monaco
-
Mongolia
-
Montenegro
-
Montserrat
-
Morocco
-
Mozambique
-
Myanmar
-
Namibia
-
Nepal
-
Netherlands
-
New Caledonia
-
New Zealand
-
Nicaragua
-
Nigeria
-
Niger
-
Northern Mariana Islands
-
Norway
-
Oman
-
Pakistan
-
Palestine
-
Panama
-
Papua New Guinea
-
Paraguay
-
Peru
-
Philippines
-
Poland
-
Portugal
-
Puerto Rico
-
Qatar
-
Romania
-
Russia
-
Rwanda
-
Saint Kitts and Nevis
-
Saint Lucia
-
Saint Vincent and the Grenadines
-
San Marino
-
Sao Tome and Principe
-
Saudi Arabia
-
Senegal
-
Serbia
-
Seychelles
-
Sierra Leone
-
Singapore
-
Sint Maarten (Dutch part)
-
Slovakia
-
Slovenia
-
Somalia
-
South Africa
-
South Korea
-
South Sudan
-
Spain
-
Sri Lanka
-
Sudan
-
Suriname
-
Swaziland
-
Sweden
-
Switzerland
-
Syria
-
Taiwan
-
Tajikistan
-
Tanzania
-
Thailand
-
Timor
-
Togo
-
Trinidad and Tobago
-
Tunisia
-
Turkey
-
Turks and Caicos Islands
-
Uganda
-
Ukraine
-
United Arab Emirates
-
United Kingdom
-
United States
-
United States Virgin Islands
-
Uruguay
-
Uzbekistan
-
Vatican
-
Venezuela
-
Vietnam
-
Western Sahara
+
Afghanistan
+
Albania
+
Algeria
+
Andorra
+
Angola
+
Anguilla
+
Antigua and Barbuda
+
Argentina
+
Armenia
+
Aruba
+
Australia
+
Austria
+
Azerbaijan
+
Bahamas
+
Bahrain
+
Bangladesh
+
Barbados
+
Belarus
+
Belgium
+
Belize
+
Benin
+
Bermuda
+
Bhutan
+
Bolivia
+
Bonaire Sint Eustatius and Saba
+
Bosnia and Herzegovina
+
Botswana
+
Brazil
+
British Virgin Islands
+
Brunei
+
Bulgaria
+
Burkina Faso
+
Burundi
+
Cambodia
+
Cameroon
+
Canada
+
Cape Verde
+
Cayman Islands
+
Central African Republic
+
Chad
+
Chile
+
China
+
Colombia
+
Comoros
+
Congo
+
Costa Rica
+
roatia
+
Cuba
+
Curacao
+
Cyprus
+
Czech Republic
+
Democratic Republic of Congo
+
Denmark
+
Djibouti
+
Dominican Republic
+
Dominica
+
Ecuador
+
Egypt
+
El Salvador
+
Equatorial Guinea
+
Eritrea
+
Estonia
+
Ethiopia
+
Faeroe Islands
+
Falkland Islands
+
Fiji
+
Finland
+
France
+
French Polynesia
+
Gabon
+
Gambia
+
Georgia
+
Germany
+
Ghana
+
Gibraltar
+
Greece
+
Greenland
+
Grenada
+
Guam
+
Guatemala
+
Guernsey
+
Guinea-Bissau
+
Guinea
+
Guyana
+
Haiti
+
Honduras
+
Hungary
+
Iceland
+
India
+
Indonesia
+
Iran
+
Iraq
+
Ireland
+
Isle of Man
+
Israel
+
Italy
+
Jamaica
+
Japan
+
Jersey
+
Jordan
+
Kazakhstan
+
Kenya
+
Kosovo
+
Kuwait
+
Kyrgyzstan
+
Laos
+
Latvia
+
Lebanon
+
Lesotho
+
Liberia
+
Libya
+
Liechtenstein
+
Lithuania
+
Luxembourg
+
North Macedonia
+
Madagascar
+
Malawi
+
Malaysia
+
Maldives
+
Mali
+
Malta
+
Mauritania
+
Mauritius
+
Mexico
+
Moldova
+
Monaco
+
Mongolia
+
Montenegro
+
Montserrat
+
Morocco
+
Mozambique
+
Myanmar
+
Namibia
+
Nepal
+
Netherlands
+
New Caledonia
+
New Zealand
+
Nicaragua
+
Nigeria
+
Niger
+
Northern Mariana Islands
+
Norway
+
Oman
+
Pakistan
+
Palestine
+
Panama
+
Papua New Guinea
+
Paraguay
+
Peru
+
Philippines
+
Poland
+
Portugal
+
Puerto Rico
+
Qatar
+
Romania
+
Russia
+
Rwanda
+
Saint Kitts and Nevis
+
Saint Lucia
+
Saint Vincent and the Grenadines
+
San Marino
+
Sao Tome and Principe
+
Saudi Arabia
+
Senegal
+
Serbia
+
Seychelles
+
Sierra Leone
+
Singapore
+
Sint Maarten (Dutch part)
+
Slovakia
+
Slovenia
+
Somalia
+
South Africa
+
South Korea
+
South Sudan
+
Spain
+
Sri Lanka
+
Sudan
+
Suriname
+
Swaziland
+
Sweden
+
Switzerland
+
Syria
+
Taiwan
+
Tajikistan
+
Tanzania
+
Thailand
+
Timor
+
Togo
+
Trinidad and Tobago
+
Tunisia
+
Turkey
+
Turks and Caicos Islands
+
Uganda
+
Ukraine
+
United Arab Emirates
+
United Kingdom
+
United States
+
United States Virgin Islands
+
Uruguay
+
Uzbekistan
+
Vatican
+
Venezuela
+
Vietnam
+
Western Sahara
World
-
Yemen
-
Zambia
-
Zimbabwe
+
Yemen
+
Zambia
+
Zimbabwe
@@ -334,6 +311,25 @@ Di Plots werden immer komplexer, daher hier eine kurze Zusammenfassung der sicht
Veraltete Plots Achtung! Nicht gepflegt, möglicherweise falsch und sowieso eher fragwürdig. +
+ Absolute Fälle + +
+ +
Neue Fälle + +
+ +
+ Absolute Todesfälle + +
+ +
+ Neue Todesfälle + +
+
Prozentualer Zuwachs Neue Fälle relativ zu absoluten Fällen mit gleitendem Mittelwert von 3 Tagen.