Skip to content

Instantly share code, notes, and snippets.

@dgfitch
Last active September 29, 2021 11:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dgfitch/b6ca1cc61b4795e698cefdf672a90f23 to your computer and use it in GitHub Desktop.
Save dgfitch/b6ca1cc61b4795e698cefdf672a90f23 to your computer and use it in GitHub Desktop.
Stack the UW COVID dashboard graphs, dividing positive tests into tests to get a positive percentage chart.
import re
import requests
from requests_html import HTMLSession
import pandas as pd
import matplotlib.pyplot as plt
session = HTMLSession()
r = session.get('https://covidresponse.wisc.edu/dashboard/')
def extract_regex(pattern, value):
m = re.search(pattern, value)
if m:
g = m.groups()
return [int(g[0]), float(g[1])]
else:
return [0, 0.0]
def extract_numbers(s):
# In the format: 'Students: 0 positive tests<br>7-day average: 4.9<br><br>Employees: 0 positive tests<br>7-day average: 1.0'
# But may be missing employees
students = extract_regex(r"Students: (\d+) [^<]+<br>7-day average: (\d+\.\d+)", s)
employees = extract_regex(r"Employees: (\d+) [^<]+<br>7-day average: (\d+\.\d+)", s)
return students + employees
def extract_data(chart):
tooltips = chart.xpath('//g/@data-tooltip_annotation')
data = pd.DataFrame([extract_numbers(x) for x in tooltips])
data.columns = ['students', 'students_7day_average', 'employees', 'employees_7day_average']
return data
positive_chart = r.html.find('.svg-bar-chart', first=True)
tests_chart = r.html.find('#chart-covid-tests', first=True)
positive = extract_data(positive_chart)
tests = extract_data(tests_chart)
# Now we have the data. Manipulate and chart it!
total_tests = tests.students + tests.employees
pp = positive / tests * 100
pp = pp.fillna(0)
pp = pp.loc[:, ['students', 'employees']]
# Create rolling averages
pp[ '7day_students' ] = pp.students.rolling(7).mean()
pp[ '7day_employees' ] = pp.employees.rolling(7).mean()
plt.figure(frameon=False, figsize=(18, 12), dpi=400)
ax = pp.plot.bar(y=['students', 'employees'], title="Percent positive tests", width=1.0, color=['#44f', '#4f4'])
ax = pp.plot(y=['7day_students', '7day_employees'], linestyle='-', ax=ax, color=['#22f', '#2f2'])
def plot_total_tests(thing, color):
mult = 50
size = mult / total_tests
size[size > 0.5] = 0.5
low = thing - size
high = thing + size
low[low < 0] = 0
plt.fill_between(total_tests.index, low, high, color=color, alpha=0.5, zorder=2)
plot_total_tests(pp['7day_students'], '#77f')
plot_total_tests(pp['7day_employees'], '#7f7')
ax.set_xticks([])
ax.legend(labels=['Students', 'Employees', '7-day Student average', '7-day Employee average'])
fig = ax.get_figure()
fig.savefig('covid_positive_percentage.png', dpi=400)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment