diff --git a/plot.py b/plot.py index 836c7b4..85494df 100644 --- a/plot.py +++ b/plot.py @@ -15,10 +15,14 @@ import locale import os.path import shutil import math +from functools import reduce -from matplotlib.dates import date2num +from matplotlib.dates import date2num, DateFormatter, WeekdayLocator +import matplotlib.dates as mdates import matplotlib.ticker as mtick +from isoweek import Week + locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8') site_folder = 'site/' @@ -33,7 +37,7 @@ print_today = today.isoformat() filename_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S") - +force_renew = True # https://www.tagesschau.de/ausland/europa/ursula-von-der-leyen-zu-corona-impfstoffen-101.html target_date_for_herd_immunity = datetime.date(2021, 9, 22) @@ -87,6 +91,17 @@ def calculate_vaccination_data(data): mean_all_time = np.mean(valid_data) mean_seven_days = np.mean(data[-7:]) + vaccinations_by_week_map = map(lambda x: (Week.withdate(x[0]), x[1]), zip(dates, data)) + + vaccinations_by_week = {} + + for w, v in vaccinations_by_week_map: + if w in vaccinations_by_week: + vaccinations_by_week[w] = vaccinations_by_week[w] + v + else: + vaccinations_by_week[w] = v + + def extrapolate(rate, to_be_vaccinated): days_extrapolated = int(np.ceil(to_be_vaccinated / rate)) extrapolated_dates = np.array([dates[0] + datetime.timedelta(days=i) for i in range(days_extrapolated)]) @@ -131,6 +146,7 @@ def calculate_vaccination_data(data): 'days_since_start': days_since_start_of_vaccination + 1, # Shift from zero to one-based-index 'start_of_vaccination_date': start_of_vaccination_date, 'start_of_vaccination_date_str': start_of_vaccination_date.strftime('%d. %B %Y'), + 'vaccinations_by_week': vaccinations_by_week, 'extrapolation_mean_all_time': extrapolation_mean_all_time, 'extrapolation_last_rate': extrapolation_last_rate, 'extrapolation_mean_seven_days': extrapolation_mean_seven_days, @@ -276,7 +292,7 @@ def plot_vaccination_bar_graph_total_time(): archive_plot_filename = '{}/vaccination_bar_graph_total_time'.format(archive_folder) latest_plot_filename = '{}/vaccination_bar_graph_total_time'.format(site_folder) - if os.path.isfile(archive_plot_filename + '.pdf'): + if os.path.isfile(archive_plot_filename + '.pdf') and not force_renew: print('Plot {} already exists'.format(archive_plot_filename)) return @@ -314,12 +330,67 @@ def plot_vaccination_bar_graph_total_time(): plot_vaccination_bar_graph_total_time() +def plot_vaccination_bar_graph_total_time_by_week(): + + archive_plot_filename = '{}/vaccination_bar_graph_total_time_by_week'.format(archive_folder) + latest_plot_filename = '{}/vaccination_bar_graph_total_time_by_week'.format(site_folder) + + if os.path.isfile(archive_plot_filename + '.pdf') and not force_renew: + print('Plot {} already exists'.format(archive_plot_filename)) + return + + fig, ax = plt.subplots(1) + + + plt.title( + 'Wöchentliche Impfrate (Erst- und Zweitimpfung übereinander)\n' + 'Datenquelle: RKI, Stand: {}. Erstellung: {}, Ersteller: Benedikt Bastin, Lizenz: CC BY-SA 4.0\n'.format( + print_stand, print_today + ) + ) + + ax.grid() + + w = [w.day(3) for w in data_first_vaccination['vaccinations_by_week'].keys()] + + f = list(data_first_vaccination['vaccinations_by_week'].values()) + s = list(data_second_vaccination['vaccinations_by_week'].values()) + + for d, v in zip(w, s): + print(f"{d}: {v}") + + print(type(w[0]), type(f[0])) + + ax.bar(w, f, label='Wöchentliche Erstimpfungen', color='blue', width=6.8) + ax.bar(w, s, label='Wöchentliche Zweitimpfungen', color='lightblue', width=6.8, bottom=f) + + #ax.set_ylim([0, np.max(f + s) * 1.1]) + + ax.legend(loc='upper left') + ax.get_xaxis().set_major_formatter(DateFormatter('%Y-w%W')) + ax.get_xaxis().set_major_locator(WeekdayLocator(3, 2)) + ax.get_yaxis().get_major_formatter().set_scientific(False) + + ax.set_xlabel('Datum') + ax.set_ylabel('Wöchentliche Impfungen') + + + 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_bar_graph_total_time_by_week() + def plot_vaccination_bar_graph_total_time_two_bars(): archive_plot_filename = '{}/vaccination_bar_graph_total_time_two_bars'.format(archive_folder) latest_plot_filename = '{}/vaccination_bar_graph_total_time_two_bars'.format(site_folder) - if os.path.isfile(archive_plot_filename + '.pdf'): + if os.path.isfile(archive_plot_filename + '.pdf') and not force_renew: print('Plot {} already exists'.format(archive_plot_filename)) return @@ -365,7 +436,7 @@ def plot_vaccination_bar_graph_compare_both_vaccinations(): archive_plot_filename = '{}/vaccination_bar_graph_compare_both_vaccinations'.format(archive_folder) latest_plot_filename = '{}/vaccination_bar_graph_compare_both_vaccinations'.format(site_folder) - if os.path.isfile(archive_plot_filename + '.pdf'): + if os.path.isfile(archive_plot_filename + '.pdf') and not force_renew: print('Plot {} already exists'.format(archive_plot_filename)) return @@ -411,7 +482,7 @@ def plot_cumulative_two_vaccinations(): archive_plot_filename = '{}/cumulative_two_vaccinations'.format(archive_folder) latest_plot_filename = '{}/cumulative_two_vaccinations'.format(site_folder) - if os.path.isfile(archive_plot_filename + '.pdf'): + if os.path.isfile(archive_plot_filename + '.pdf') and not force_renew: print('Plot {} already exists'.format(archive_plot_filename)) return @@ -458,7 +529,7 @@ def plot_cumulative_two_vaccinations_percentage(): archive_plot_filename = '{}/cumulative_two_vaccinations_percentage'.format(archive_folder) latest_plot_filename = '{}/cumulative_two_vaccinations_percentage'.format(site_folder) - if os.path.isfile(archive_plot_filename + '.pdf'): + if os.path.isfile(archive_plot_filename + '.pdf') and not force_renew: print('Plot {} already exists'.format(archive_plot_filename)) return @@ -507,7 +578,7 @@ def plot_people_between_first_and_second(): archive_plot_filename = '{}/people_between_first_and_second'.format(archive_folder) latest_plot_filename = '{}/people_between_first_and_second'.format(site_folder) - if os.path.isfile(archive_plot_filename + '.pdf'): + if os.path.isfile(archive_plot_filename + '.pdf') and not force_renew: print('Plot {} already exists'.format(archive_plot_filename)) return @@ -557,7 +628,7 @@ 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'): + if os.path.isfile(archive_plot_filename + '.pdf') and not force_renew: print('Plot {} already exists'.format(archive_plot_filename)) return @@ -606,9 +677,9 @@ def plot_vaccination_done_days(): archive_plot_filename = '{}/vaccination_done_days'.format(archive_folder) latest_plot_filename = '{}/vaccination_done_days'.format(site_folder) - #if os.path.isfile(archive_plot_filename + '.pdf'): - #print('Plot {} already exists'.format(archive_plot_filename)) - #return + if os.path.isfile(archive_plot_filename + '.pdf') and not force_renew: + print('Plot {} already exists'.format(archive_plot_filename)) + return fig, ax = plt.subplots(1) @@ -653,9 +724,9 @@ def plot_vaccination_done_dates(): archive_plot_filename = '{}/vaccination_done_dates'.format(archive_folder) latest_plot_filename = '{}/vaccination_done_dates'.format(site_folder) - #if os.path.isfile(archive_plot_filename + '.pdf'): - #print('Plot {} already exists'.format(archive_plot_filename)) - #return + if os.path.isfile(archive_plot_filename + '.pdf') and not force_renew: + print('Plot {} already exists'.format(archive_plot_filename)) + return fig, ax = plt.subplots(1) @@ -711,7 +782,7 @@ def render_dashboard(): stylesheet_filename = 'site/rki-dashboard.css' stylesheet_archive_filename = 'site/archive/{}/rki-dashboard.css'.format(filename_stand) - if os.path.isfile(dashboard_archive_filename): + if os.path.isfile(dashboard_archive_filename) and not force_renew: print('Dashboard {} already exists'.format(dashboard_archive_filename)) return @@ -750,34 +821,38 @@ def render_dashboard(): 'caption': 'Tägliche Impfrate (Erst- und Zweitimpfung übereinander)' },{ 'index': 2, + 'filename': 'vaccination_bar_graph_total_time_by_week', + 'caption': 'Wöchentliche Impfrate (Erst- und Zweitimpfung übereinander)' + },{ + 'index': 3, 'filename': 'vaccination_bar_graph_total_time_two_bars', 'caption': 'Tägliche Impfrate (Erst- und Zweitimpfung nebeneinander)' },{ - 'index': 3, + 'index': 4, 'filename': 'vaccination_bar_graph_compare_both_vaccinations', 'caption': 'Tägliche Impfrate (Erst- und Zweitimpfung nebeneinander)' },{ - 'index': 4, + 'index': 5, 'filename': 'cumulative_two_vaccinations', 'caption': 'Kumulative Impfrate (Erst- und Zweitimpfung)' },{ - 'index': 5, + 'index': 6, 'filename': 'cumulative_two_vaccinations_percentage', 'caption': 'Kumulative Impfrate (Erst- und Zweitimpfung) in Prozent der Bevölkerung Deutschlands' },{ - 'index': 6, + 'index': 7, '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': 7, + 'index': 8, 'filename': 'vaccination_rate', 'caption': 'Tägliche Impfrate sowie durchschnittliche Impfrate' },{ - 'index': 8, + 'index': 9, 'filename': 'vaccination_done_days', 'caption': 'Lineare Extrapolation bis 70 % der Bevölkerung anhand der Erstimpfungen der durchschnittlichen Impfrate (Anzahl Tage, Gesamt und 7 Tage)' },{ - 'index': 9, + 'index': 10, 'filename': 'vaccination_done_dates', 'caption': 'Lineare Extrapolation bis 70 % der Bevölkerung anhand der Erstimpfungen der durchschnittlichen Impfrate (Datum, Gesamt und 7 Tage)' } diff --git a/requirements.txt b/requirements.txt index 1e70fad..b1176b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,5 @@ pandas openpyxl requests jinja2 +isoweek