Now using py files, for automation
[covid19.git] / test_and_case_data.py
1 #!/usr/bin/env python
2 # coding: utf-8
3 # %%
4 import itertools
5 import collections
6 import json
7 import pandas as pd
8 import numpy as np
9 from scipy.stats import gmean
10 import datetime
11 import os
12 import sqlalchemy
13
14 import matplotlib as mpl
15 import matplotlib.pyplot as plt
16 import matplotlib.animation as ani
17 plt.ioff()
18
19
20 # %%
21 chart_start_date = '2020-09-15'
22
23
24 # %%
25 connection_string = 'postgresql://covid:3NbjJTkT63@localhost/covid'
26
27
28 # %%
29 engine = sqlalchemy.create_engine(connection_string)
30
31 # %%
32 query_string = '''select uk_data.date,
33 uk_data.new_cases, uk_data_7.new_cases as new_cases_7,
34 uk_data.new_tests, uk_data_7.new_tests as new_tests_7,
35 uk_data.new_pcr_tests, uk_data_7.new_pcr_tests as new_pcr_7,
36 uk_data.new_pillar_1_2_tests as new_pillar_12, uk_data_7.new_pillar_1_2_tests as new_pillar_12_7,
37 uk_data.new_cases::float / uk_data.new_tests as fraction_positive,
38 uk_data_7.new_cases / uk_data_7.new_tests as fraction_positive_7
39 from uk_data left outer join uk_data_7 using (date)
40 order by uk_data.date'''
41 tests_data = pd.read_sql_query(query_string, engine,
42 index_col='date',
43 parse_dates = ['date'])
44
45 # %%
46 pri_y_max = int((tests_data.dropna().loc[chart_start_date: , 'new_tests_7'].max() * 1.1) / 100 ) * 100
47 ax = tests_data.dropna().loc[chart_start_date: , 'new_tests_7'].plot(figsize=(10, 8),
48 style=['k-'],
49 legend=False,
50 ylim=(0, pri_y_max))
51 ax.set_title('Tests done and new cases (7 day moving average)')
52 ax.legend(['Tests, 7 day moving average'], loc='lower left')
53 ax.set_ylabel('Tests')
54 sec_y_max = int((tests_data.dropna().loc[chart_start_date:, 'new_cases_7'].max() * 1.1) / 100) * 100
55 ax = tests_data.dropna().loc[chart_start_date:, 'new_cases_7'].plot(ax=ax, secondary_y=True, style='r--')
56 ax.set_ylim((0, sec_y_max))
57 ax.legend(['Cases (7 day moving average)'], loc='lower right')
58 ax.set_ylabel('New cases')
59 plt.savefig('tests_and_cases.png')
60
61
62 # %%
63 ax = (tests_data.loc[chart_start_date: , ['fraction_positive', 'fraction_positive_7']] * 100).plot(figsize=(10, 8),
64 style=['b:', 'k-'], legend=False)
65 ax.set_title('Fraction of tests with positive results')
66 ax.legend(['Fraction positive (%)', 'Fraction positive (%), 7 day moving average'], loc='upper left')
67 ax.set_ylabel('Fraction positive')
68 cases_axis_max = (1.0 * tests_data.loc[chart_start_date:].new_cases_7.max()
69 * tests_data.loc[chart_start_date:].fraction_positive.max()
70 / tests_data.loc[chart_start_date:].fraction_positive_7.max()
71 )
72
73 ax2 = ax.twinx()
74 ax2 = tests_data.loc[chart_start_date:, 'new_cases_7'].plot(ax=ax2, secondary_y=True, style='r--')
75 ax2.set_ylim(-1000, cases_axis_max)
76 ax2.legend(['Cases (7 day moving average)'], loc='center left')
77 ax2.set_ylabel('New cases')
78 plt.savefig('fraction_positive_tests.png')
79
80
81 # %%
82 ax = tests_data.dropna().loc[chart_start_date:].plot(x='fraction_positive_7', y='new_tests_7',
83 figsize=(8, 8),
84 legend=None)
85 ax.set_xlabel("Fraction of tests that are positive")
86 ax.set_ylabel("Number of tests")
87 for d in tests_data.dropna().loc[chart_start_date::15].index:
88 ax.plot(tests_data.loc[d, 'fraction_positive_7'], tests_data.loc[d, 'new_tests_7'], 'o',
89 markersize=8)#, markerfacecolor=marker_col, markeredgecolor=marker_col)
90 ax.text(tests_data.loc[d, 'fraction_positive_7'] + 0.0002, tests_data.loc[d, 'new_tests_7'],
91 s = d.strftime("%d %B %Y"))
92 plt.savefig('fraction_positive_tests_vs_tests.png')
93
94
95 # %%
96 fig = plt.figure(figsize=(8, 8))
97 plt.ylabel('Number of tests')
98 plt.xlabel('Fraction of tests that are positive')
99 all_data = tests_data.dropna().loc[chart_start_date:]
100
101
102 minx = all_data.fraction_positive_7.min() * 0.9
103 maxx = all_data.fraction_positive_7.max() * 1.1
104 miny = all_data.new_tests_7.min() * 0.9
105 maxy = all_data.new_tests_7.max() * 1.1
106
107 plt.xlim(minx, maxx)
108 plt.ylim(miny, maxy)
109 # plt.legend(None)
110
111 def build_state_frame(i):
112 this_data = all_data[:i]
113 plt.clf()
114 plt.ylabel('Number of tests')
115 plt.xlabel('Fraction of tests that are positive')
116 plt.xlim(minx, maxx)
117 plt.ylim(miny, maxy)
118 p = plt.plot(this_data.fraction_positive_7, this_data.new_tests_7)
119 p[0].set_color('r')
120 for d in this_data[::15].index:
121 plt.plot(this_data.loc[d, 'fraction_positive_7'],
122 this_data.loc[d, 'new_tests_7'], 'o',
123 markersize=8, markerfacecolor='r', markeredgecolor='r')
124 plt.text(this_data.loc[d, 'fraction_positive_7'] + 0.0002,
125 this_data.loc[d, 'new_tests_7'],
126 s = d.strftime("%d %B %Y"))
127
128 animator = ani.FuncAnimation(fig, build_state_frame,
129 frames=all_data.shape[0]+1,
130 interval=100,
131 repeat_delay=200,
132 repeat=True)
133 animator.save('tests_vs_fraction_positive.mp4')
134 # plt.show()
135
136
137 # %%
138 os.system('rm tests_vs_fraction_positive_animation.png')
139 os.system('ffmpeg -i tests_vs_fraction_positive.mp4 -plays 0 -final_delay 1 -f apng tests_vs_fraction_positive_animation.png')
140
141
142 # %%
143
144
145
146