From a3bf0654f9c7aaeb763d034429b4f19de1b63752 Mon Sep 17 00:00:00 2001 From: Benedikt Bastin Date: Wed, 17 Feb 2021 11:55:30 +0100 Subject: [PATCH 1/2] feat: New plot for vaccination rates --- plot.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/plot.py b/plot.py index bdf325f..eb15aae 100644 --- a/plot.py +++ b/plot.py @@ -14,6 +14,7 @@ import requests as req import locale import os.path import shutil +import math from matplotlib.dates import date2num import matplotlib.ticker as mtick @@ -67,7 +68,6 @@ dates = impfungen['Datum'] start_of_reporting_date = dates.iloc[0].date() def calculate_vaccination_data(data): - cumulative = np.cumsum(data) total = int(np.sum(data)) total_percentage = float(total) / einwohner_deutschland * 100 @@ -80,7 +80,11 @@ def calculate_vaccination_data(data): days_since_start_of_vaccination = (last_date - start_of_vaccination_date).days days_since_start_of_reporting = (last_date - start_of_reporting_date).days - mean_all_time = np.mean(data[start_of_vaccination_index:]) + valid_data = data[start_of_vaccination_index:] + + cumulative = np.concatenate(([math.nan] * (days_since_start_of_reporting - days_since_start_of_vaccination), np.cumsum(valid_data))) + + mean_all_time = np.mean(valid_data) mean_seven_days = np.mean(data[-7:]) def extrapolate(rate, to_be_vaccinated): @@ -110,7 +114,7 @@ def calculate_vaccination_data(data): extrapolation_mean_seven_days = extrapolate(mean_seven_days, to_be_vaccinated) mean_vaccination_rates_daily = np.round(cumulative / range(1, len(cumulative) + 1)) - + vaccination_rates_daily_rolling_average = data.rolling(7).mean() vaccinations_missing_until_target = einwohner_deutschland * 0.7 - total vaccination_rate_needed_for_target = vaccinations_missing_until_target / days_until_target @@ -131,6 +135,7 @@ def calculate_vaccination_data(data): 'extrapolation_last_rate': extrapolation_last_rate, 'extrapolation_mean_seven_days': extrapolation_mean_seven_days, 'mean_vaccination_rates_daily': mean_vaccination_rates_daily, + 'vaccination_rates_daily_rolling_average': vaccination_rates_daily_rolling_average, 'vaccinations_missing_until_target': int(np.floor(vaccinations_missing_until_target)), 'vaccination_rate_needed_for_target': int(np.floor(vaccination_rate_needed_for_target)), 'vaccination_rate_needed_for_target_percentage': vaccination_rate_needed_for_target_percentage @@ -506,7 +511,7 @@ def plot_cumulative_two_vaccinations(): ax.fill_between(dates, first_vaccinations_cumulative, label='Erstimpfungen', color='blue') ax.fill_between(dates, second_vaccinations_cumulative, label='Zweitimpfungen', color='lightblue') - ax.set_ylim([0, first_vaccinations_cumulative.iloc[-1]]) + ax.set_ylim([0, first_vaccinations_cumulative[-1]]) ax.legend(loc='upper left') ax.xaxis_date() @@ -597,7 +602,7 @@ def plot_people_between_first_and_second(): ax.grid() first_vaccinations_cumulative = data_first_vaccination['cumulative'] - second_vaccinations_cumulative = data_second_vaccination['cumulative'] + second_vaccinations_cumulative = np.nan_to_num(data_second_vaccination['cumulative'], nan=0) people_between = first_vaccinations_cumulative - second_vaccinations_cumulative @@ -625,6 +630,54 @@ def plot_people_between_first_and_second(): plot_people_between_first_and_second() +def plot_vaccination_rate(): + + archive_plot_filename = '{}/vaccination_rate'.format(archive_folder) + latest_plot_filename = '{}/vaccination_rate'.format(site_folder) + + #if os.path.isfile(archive_plot_filename + '.pdf'): + #print('Plot {} already exists'.format(archive_plot_filename)) + #return + + fig, ax = plt.subplots(1) + + + plt.title( + 'Tägliche Impfrate sowie durchschnittliche Impfrate\n' + 'Datenquelle: RKI, Stand: {}. Erstellung: {}, Ersteller: Benedikt Bastin, Lizenz: CC BY-SA 4.0\n'.format( + print_stand, print_today + ) + ) + + ax.plot(dates, data_first_vaccination['daily'], label='Tägliche Erstimpfrate', color='blue', linewidth=0.5) + ax.plot(dates, data_second_vaccination['daily'], label='Tägliche Zweitimpfrate', color='lightblue', linewidth=0.5) + + ax.plot(dates, data_first_vaccination['vaccination_rates_daily_rolling_average'], color='blue', linewidth=2, label='Erstimpfrate über sieben Tage') + ax.plot(dates, data_second_vaccination['vaccination_rates_daily_rolling_average'], color='lightblue', linewidth=2, label='Zweitimpfrate über sieben Tage') + + + ax.plot(dates, data_first_vaccination['mean_vaccination_rates_daily'], color='violet', label='Durchschnittliche Erstimpfrate\nbis zu diesem Tag (inkl.)') + ax.plot(dates, data_second_vaccination['mean_vaccination_rates_daily'], color='magenta', label='Durchschnittliche Zweitimpfrate\nbis zu diesem Tag (inkl.)') + + + ax.grid(True) + + + ax.legend(loc='upper left') + ax.get_yaxis().get_major_formatter().set_scientific(False) + + ax.set_xlabel('Datum') + ax.set_ylabel('Impfrate [Impfungen/Tag]') + + plt.savefig(archive_plot_filename + '.pdf') + plt.savefig(archive_plot_filename + '.png') + plt.savefig(latest_plot_filename + '.pdf') + plt.savefig(latest_plot_filename + '.png') + plt.close() + + print('Created plot {} as pdf and png'.format(archive_plot_filename)) + +plot_vaccination_rate() def render_dashboard(): dashboard_filename = 'site/index.xhtml' From 8a3c5159b5bb7924625520d30ed4cceb1db9dc3f Mon Sep 17 00:00:00 2001 From: Benedikt Bastin Date: Wed, 17 Feb 2021 12:11:49 +0100 Subject: [PATCH 2/2] feat: Figures are now automatically generated --- dashboard_template.xhtml | 121 +++------------------------------------ plot.py | 43 ++++++++++++++ 2 files changed, 52 insertions(+), 112 deletions(-) diff --git a/dashboard_template.xhtml b/dashboard_template.xhtml index 5bc636a..35a6eb7 100644 --- a/dashboard_template.xhtml +++ b/dashboard_template.xhtml @@ -173,124 +173,21 @@

Plots

+ {% for fig in figures %}
- + + src="{{ fig['filename'] }}.png" + alt="{{ fig['caption'] }}" />
- Abbildung 1: - Tägliche Impfquote, kumulierte Impfungen und lineare Extrapolation bis 10 % der Bevölkerung Deutschlands
- Download als PNG - Download als PDF -
-
- -
- - - -
- Abbildung 2: - Tägliche Impfquote, kumulierte Impfungen und lineare Extrapolation bis 70 % der Bevölkerung Deutschlands
- Download als PNG - Download als PDF -
-
-
- - - -
- Abbildung 3: - Tägliche Impfquote, kumulierte Impfungen und lineare Extrapolation bis 100 % der Bevölkerung Deutschlands
- Download als PNG - Download als PDF -
-
-
- - - -
- Abbildung 4: - Tägliche Impfrate (Erst- und Zweitimpfung übereinander)
- Download als PNG - Download als PDF -
-
-
- - - -
- Abbildung 5: - Tägliche Impfrate (Erst- und Zweitimpfung nebeneinander)
- Download als PNG - Download als PDF -
-
-
- - - -
- Abbildung 6: - Tägliche Impfrate (Erst- und Zweitimpfung nebeneinander)
- Download als PNG - Download als PDF -
-
-
- - - -
- Abbildung 7: - Kumulative Impfrate (Erst- und Zweitimpfung)
- Download als PNG - Download als PDF -
-
-
- - - -
- Abbildung 8: - Kumulative Impfrate (Erst- und Zweitimpfung) in Prozent der Bevölkerung Deutschlands2
- Download als PNG - Download als PDF -
-
-
- - - -
- Abbildung 9: - Anzahl der Personen zwischen Erst- und Zweitimpfung, also Personen, die die erste Impfung erhalten haben, die zweite aber noch nicht
- Download als PNG - Download als PDF + Abbildung {{ fig['index'] }}: + {{ fig['caption'] }}
+ Download als PNG + Download als PDF
+ {% endfor %}
diff --git a/plot.py b/plot.py index eb15aae..906462f 100644 --- a/plot.py +++ b/plot.py @@ -717,6 +717,49 @@ def render_dashboard(): data_second_vaccination = data_second_vaccination, #details_per_land = dict(sorted(details_per_land_formatted.items(), key=lambda item: item[0])), #details_total = details_total_formatted + figures = [ + { + 'index': 1, + 'filename': 'extrapolated_to_10_percent', + 'caption': 'Tägliche Impfquote, kumulierte Impfungen und lineare Extrapolation bis 10 % der Bevölkerung Deutschlands' + },{ + 'index': 2, + 'filename': 'extrapolated_to_70_percent', + 'caption': 'Tägliche Impfquote, kumulierte Impfungen und lineare Extrapolation bis 70 % der Bevölkerung Deutschlands' + },{ + 'index': 3, + 'filename': 'extrapolated_to_100_percent', + 'caption': 'Tägliche Impfquote, kumulierte Impfungen und lineare Extrapolation bis 100 % der Bevölkerung Deutschlands' + },{ + 'index': 4, + 'filename': 'vaccination_bar_graph_total_time', + 'caption': 'Tägliche Impfrate (Erst- und Zweitimpfung übereinander)' + },{ + 'index': 5, + 'filename': 'vaccination_bar_graph_total_time_two_bars', + 'caption': 'Tägliche Impfrate (Erst- und Zweitimpfung nebeneinander)' + },{ + 'index': 6, + 'filename': 'vaccination_bar_graph_compare_both_vaccinations', + 'caption': 'Tägliche Impfrate (Erst- und Zweitimpfung nebeneinander)' + },{ + 'index': 7, + 'filename': 'cumulative_two_vaccinations', + 'caption': 'Kumulative Impfrate (Erst- und Zweitimpfung)' + },{ + 'index': 8, + 'filename': 'cumulative_two_vaccinations_percentage', + 'caption': 'Kumulative Impfrate (Erst- und Zweitimpfung) in Prozent der Bevölkerung Deutschlands' + },{ + 'index': 9, + 'filename': 'people_between_first_and_second', + 'caption': 'Anzahl der Personen zwischen Erst- und Zweitimpfung, also Personen, die die erste Impfung erhalten haben, die zweite aber noch nicht' + },{ + 'index': 10, + 'filename': 'vaccination_rate', + 'caption': 'Tägliche Impfrate sowie durchschnittliche Impfrate' + } + ] ).dump('site/index.xhtml') shutil.copyfile(dashboard_filename, dashboard_archive_filename)