-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdashboard.py
138 lines (113 loc) · 4.06 KB
/
dashboard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
"""
Monitor the COVID-19 status across many locations in a single dashboard.
Copyright (C) 2020 Luke Macken <[email protected]>
SPDX-License-Identifier: AGPL-3.0-or-later
"""
import math
import pandas as pd
import matplotlib.pyplot as plt
KEYWORDS = [
("province:Colorado", "city:Denver"),
("province:Massachusetts", "city:Hampden"),
("province:Massachusetts", "city:Suffolk"),
("province:California", "city:Los Angeles"),
("province:New York", "city:Wayne"),
("province:New York", "city:New York"),
("province:Virginia", "city:Arlington"),
("province:Florida", "city:Orange"),
"country:Viet Nam",
"country:Korea (South)",
"country:Japan",
]
REFRESH_HOURS = 12 # Refresh the data twice a day
# Setup the window
NUM_COLS = 3
NUM_ROWS = math.ceil(len(KEYWORDS) / NUM_COLS)
# Map each axis to a number
# Then the index of the keyword in KEYWORDS is the axis key
AXMAP = {}
def get_data():
"""
Country CountryCode Lat Lon Confirmed Deaths Recovered Active Date LocationID Province City CityCode
Date
2020-04-04 00:00:00+00:00 Colombia CO 4.57 -74.30 1406 32 85 0 2020-04-04 00:00:00+00:00 89e1ca12-78be-407f-aa18-bfcd05f01a56 NaN NaN NaN
"""
print("Downloading all COVID-19 data from covid19api.com")
df = pd.read_json("https://api.covid19api.com/all")
df = df.query("Country != ''") # Clean it
df.Date = pd.to_datetime(df.Date)
df = df.set_index("Date").sort_index().fillna(0)
return df
def analyze_keyword(keyword, df):
ax = AXMAP[KEYWORDS.index(keyword)]
ax.clear()
if isinstance(keyword, tuple):
keywords = list(keyword)
else:
keywords = [keyword]
kw_df = None
title = ''
while len(keywords):
kw = keywords.pop(0)
qdf = df
if kw_df is not None:
qdf = kw_df
if kw.startswith("country:"):
kw = kw.split(":")[1]
_df = qdf[qdf.Country == kw]
elif kw.startswith("province:"):
kw = kw.split(":")[1]
_df = qdf[qdf.Province == kw]
elif kw.startswith("city:"):
kw = kw.split(":")[1]
_df = qdf[qdf.City == kw]
elif kw.startswith("citycode:"):
kw = kw.split(":")[1]
_df = qdf[qdf.CityCode == kw]
else:
_df = qdf[qdf.Province.str.contains(kw)]
kw_df = _df
title = f"{kw} {title}"
kw_df = kw_df.sort_index()
print(f"Found {len(kw_df)} entries for {keyword}")
recent_data = kw_df.tail(6)
print(recent_data.to_string())
kw_df.Confirmed.plot(label='confirmed', legend=True, title=title, ax=ax)
kw_df.Deaths.plot(label='deaths', legend=True, title=title, ax=ax)
kw_df.Recovered.plot(label='recovered', legend=True, title=title, ax=ax)
def annotate_status(df, status, color, xytext, shrink=0.05):
latest = df.tail(1)
x = latest.index.tolist()[0]
y = latest[status].tolist()[0]
ax.annotate(
f"{latest[status].values[0]}",
xy=(x, y),
xycoords="data",
xytext=xytext,
textcoords="axes fraction",
arrowprops=dict(facecolor=color, shrink=shrink),
horizontalalignment="right",
verticalalignment="top",
)
annotate_status(kw_df, "Confirmed", "black", xytext=(0.8, 0.95))
annotate_status(kw_df, "Deaths", "red", xytext=(0.7, 0.7))
annotate_status(kw_df, "Recovered", "green", xytext=(0.6, 0.4), shrink=0.1)
print()
def main():
fig, axes = plt.subplots(NUM_ROWS, NUM_COLS, sharex=False, sharey=False)
# Give each axis a number
for i, ax in enumerate(axes.flatten()):
AXMAP[i] = ax
plt.show(block=False)
while True:
df = get_data()
for keyword in KEYWORDS:
analyze_keyword(keyword, df)
fig.subplots_adjust(wspace=0.25, hspace=0.7)
fig.canvas.draw()
fig.canvas.flush_events()
print(f"Sleeping for {REFRESH_HOURS} hour(s)")
print(80 * "=")
plt.pause(REFRESH_HOURS * 60 * 60)
if __name__ == "__main__":
main()