X-Git-Url: https://git.njae.me.uk/?p=covid19.git;a=blobdiff_plain;f=test_and_case_data.py;fp=test_and_case_data.py;h=7de6bf0cca54cf3131c4020f0518933f90475d1b;hp=0000000000000000000000000000000000000000;hb=5afedd66506be7575034ae6deebcfaa7c2ced978;hpb=4abff18d7988bdea04a267a08a0792ba570fe0bd diff --git a/test_and_case_data.py b/test_and_case_data.py new file mode 100644 index 0000000..7de6bf0 --- /dev/null +++ b/test_and_case_data.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python +# coding: utf-8 +# %% +import itertools +import collections +import json +import pandas as pd +import numpy as np +from scipy.stats import gmean +import datetime +import os +import sqlalchemy + +import matplotlib as mpl +import matplotlib.pyplot as plt +import matplotlib.animation as ani +plt.ioff() + + +# %% +chart_start_date = '2020-09-15' + + +# %% +connection_string = 'postgresql://covid:3NbjJTkT63@localhost/covid' + + +# %% +engine = sqlalchemy.create_engine(connection_string) + +# %% +query_string = '''select uk_data.date, + uk_data.new_cases, uk_data_7.new_cases as new_cases_7, + uk_data.new_tests, uk_data_7.new_tests as new_tests_7, + uk_data.new_pcr_tests, uk_data_7.new_pcr_tests as new_pcr_7, + uk_data.new_pillar_1_2_tests as new_pillar_12, uk_data_7.new_pillar_1_2_tests as new_pillar_12_7, + uk_data.new_cases::float / uk_data.new_tests as fraction_positive, + uk_data_7.new_cases / uk_data_7.new_tests as fraction_positive_7 + from uk_data left outer join uk_data_7 using (date) + order by uk_data.date''' +tests_data = pd.read_sql_query(query_string, engine, + index_col='date', + parse_dates = ['date']) + +# %% +pri_y_max = int((tests_data.dropna().loc[chart_start_date: , 'new_tests_7'].max() * 1.1) / 100 ) * 100 +ax = tests_data.dropna().loc[chart_start_date: , 'new_tests_7'].plot(figsize=(10, 8), + style=['k-'], + legend=False, + ylim=(0, pri_y_max)) +ax.set_title('Tests done and new cases (7 day moving average)') +ax.legend(['Tests, 7 day moving average'], loc='lower left') +ax.set_ylabel('Tests') +sec_y_max = int((tests_data.dropna().loc[chart_start_date:, 'new_cases_7'].max() * 1.1) / 100) * 100 +ax = tests_data.dropna().loc[chart_start_date:, 'new_cases_7'].plot(ax=ax, secondary_y=True, style='r--') +ax.set_ylim((0, sec_y_max)) +ax.legend(['Cases (7 day moving average)'], loc='lower right') +ax.set_ylabel('New cases') +plt.savefig('tests_and_cases.png') + + +# %% +ax = (tests_data.loc[chart_start_date: , ['fraction_positive', 'fraction_positive_7']] * 100).plot(figsize=(10, 8), + style=['b:', 'k-'], legend=False) +ax.set_title('Fraction of tests with positive results') +ax.legend(['Fraction positive (%)', 'Fraction positive (%), 7 day moving average'], loc='upper left') +ax.set_ylabel('Fraction positive') +cases_axis_max = (1.0 * tests_data.loc[chart_start_date:].new_cases_7.max() + * tests_data.loc[chart_start_date:].fraction_positive.max() + / tests_data.loc[chart_start_date:].fraction_positive_7.max() + ) + +ax2 = ax.twinx() +ax2 = tests_data.loc[chart_start_date:, 'new_cases_7'].plot(ax=ax2, secondary_y=True, style='r--') +ax2.set_ylim(-1000, cases_axis_max) +ax2.legend(['Cases (7 day moving average)'], loc='center left') +ax2.set_ylabel('New cases') +plt.savefig('fraction_positive_tests.png') + + +# %% +ax = tests_data.dropna().loc[chart_start_date:].plot(x='fraction_positive_7', y='new_tests_7', + figsize=(8, 8), + legend=None) +ax.set_xlabel("Fraction of tests that are positive") +ax.set_ylabel("Number of tests") +for d in tests_data.dropna().loc[chart_start_date::15].index: + ax.plot(tests_data.loc[d, 'fraction_positive_7'], tests_data.loc[d, 'new_tests_7'], 'o', + markersize=8)#, markerfacecolor=marker_col, markeredgecolor=marker_col) + ax.text(tests_data.loc[d, 'fraction_positive_7'] + 0.0002, tests_data.loc[d, 'new_tests_7'], + s = d.strftime("%d %B %Y")) +plt.savefig('fraction_positive_tests_vs_tests.png') + + +# %% +fig = plt.figure(figsize=(8, 8)) +plt.ylabel('Number of tests') +plt.xlabel('Fraction of tests that are positive') +all_data = tests_data.dropna().loc[chart_start_date:] + + +minx = all_data.fraction_positive_7.min() * 0.9 +maxx = all_data.fraction_positive_7.max() * 1.1 +miny = all_data.new_tests_7.min() * 0.9 +maxy = all_data.new_tests_7.max() * 1.1 + +plt.xlim(minx, maxx) +plt.ylim(miny, maxy) +# plt.legend(None) + +def build_state_frame(i): + this_data = all_data[:i] + plt.clf() + plt.ylabel('Number of tests') + plt.xlabel('Fraction of tests that are positive') + plt.xlim(minx, maxx) + plt.ylim(miny, maxy) + p = plt.plot(this_data.fraction_positive_7, this_data.new_tests_7) + p[0].set_color('r') + for d in this_data[::15].index: + plt.plot(this_data.loc[d, 'fraction_positive_7'], + this_data.loc[d, 'new_tests_7'], 'o', + markersize=8, markerfacecolor='r', markeredgecolor='r') + plt.text(this_data.loc[d, 'fraction_positive_7'] + 0.0002, + this_data.loc[d, 'new_tests_7'], + s = d.strftime("%d %B %Y")) + +animator = ani.FuncAnimation(fig, build_state_frame, + frames=all_data.shape[0]+1, + interval=100, + repeat_delay=200, + repeat=True) +animator.save('tests_vs_fraction_positive.mp4') +# plt.show() + + +# %% +os.system('rm tests_vs_fraction_positive_animation.png') +os.system('ffmpeg -i tests_vs_fraction_positive.mp4 -plays 0 -final_delay 1 -f apng tests_vs_fraction_positive_animation.png') + + +# %% + + + +