Now using py files, for automation
[covid19.git] / test_and_case_data.py
diff --git a/test_and_case_data.py b/test_and_case_data.py
new file mode 100644 (file)
index 0000000..7de6bf0
--- /dev/null
@@ -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')
+
+
+# %%
+
+
+
+