Skip to content

Commit 4177e46

Browse files
authored
Merge pull request #191 from CodeForPhilly/17-chart-language
17 chart language
2 parents 458fe52 + 6294131 commit 4177e46

File tree

4 files changed

+96
-11
lines changed

4 files changed

+96
-11
lines changed

src/app.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@
1919
)
2020
from penn_chime.settings import DEFAULTS
2121
from penn_chime.models import sim_sir_df, build_admissions_df, build_census_df
22-
from penn_chime.charts import (
23-
additional_projections_chart,
24-
admitted_patients_chart,
25-
new_admissions_chart,
26-
)
22+
from penn_chime.charts import (additional_projections_chart,
23+
admitted_patients_chart,
24+
new_admissions_chart,
25+
chart_descriptions)
2726

2827
# This is somewhat dangerous:
2928
# Hide the main menu with "Rerun", "run on Save", "clear cache", and "record a screencast"
@@ -51,20 +50,24 @@
5150

5251
st.subheader("New Admissions")
5352
st.markdown("Projected number of **daily** COVID-19 admissions at Penn hospitals")
53+
new_admit_chart = new_admissions_chart(alt, admissions_df, parameters=p, as_date=as_date)
5454
st.altair_chart(
55-
new_admissions_chart(alt, admissions_df, parameters=p, as_date=as_date),
56-
use_container_width=True,
55+
new_admit_chart, use_container_width=True
5756
)
57+
58+
st.markdown(chart_descriptions(new_admit_chart))
59+
5860
if st.checkbox("Show Projected Admissions in tabular form"):
5961
draw_projected_admissions_table(st, admissions_df, as_date=as_date)
6062
st.subheader("Admitted Patients (Census)")
6163
st.markdown(
6264
"Projected **census** of COVID-19 patients, accounting for arrivals and discharges at Penn hospitals"
6365
)
66+
census_chart = admitted_patients_chart(alt=alt, census=census_df, parameters=p, as_date=as_date)
6467
st.altair_chart(
65-
admitted_patients_chart(alt=alt, census=census_df, parameters=p, as_date=as_date),
66-
use_container_width=True,
68+
census_chart, use_container_width=True
6769
)
70+
st.markdown(chart_descriptions(census_chart, suffix=" Census"))
6871
if st.checkbox("Show Projected Census in tabular form"):
6972
draw_census_table(st, census_df, as_date=as_date)
7073
st.markdown(

src/penn_chime/charts.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2+
from math import ceil
3+
import datetime
14
from altair import Chart # type: ignore
25
import pandas as pd # type: ignore
36
import numpy as np # type: ignore
@@ -112,3 +115,43 @@ def additional_projections_chart(
112115
)
113116
.interactive()
114117
)
118+
119+
120+
def chart_descriptions(chart: Chart, suffix: str = ""):
121+
"""
122+
123+
:param chart: Chart: The alt chart to be used in finding max points
124+
:param suffix: str: The assumption is that the charts have similar column names.
125+
The census chart adds " Census" to the column names.
126+
Make sure to include a space or underscore as appropriate
127+
:return: str: Returns a multi-line string description of the results
128+
"""
129+
messages = []
130+
131+
cols = ["Hospitalized", "ICU", "Ventilated"]
132+
asterisk = False
133+
day = "date" if "date" in chart.data.columns else "day"
134+
135+
for col in cols:
136+
if chart.data[col].idxmax() + 1 == len(chart.data):
137+
asterisk = True
138+
139+
on = chart.data[day][chart.data[col].idxmax()]
140+
if day == "date":
141+
on = datetime.datetime.strftime(on, "%b %d") # todo: bring this to an optional arg / i18n
142+
else:
143+
on += 1 # 0 index issue
144+
145+
messages.append(
146+
"{}{} peaks at {:,} on day {}{}".format(
147+
col,
148+
suffix,
149+
ceil(chart.data[col].max()),
150+
on,
151+
"*" if asterisk else "",
152+
)
153+
)
154+
155+
if asterisk:
156+
messages.append("_* The max is at the upper bound of the data, and therefore may not be the actual max_")
157+
return "\n\n".join(messages)

src/penn_chime/presentation.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,6 @@ def draw_projected_admissions_table(
404404
admits_table = add_date_column(
405405
admits_table, drop_day_column=True, date_format=DATE_FORMAT
406406
)
407-
408407
st.table(admits_table)
409408
return None
410409

tests/test_app.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
"""Tests."""
22

3+
from math import ceil # type: ignore
4+
import datetime # type: ignore
35
import pytest # type: ignore
46
import pandas as pd # type: ignore
57
import numpy as np # type: ignore
68
import altair as alt # type: ignore
79

8-
from src.penn_chime.charts import new_admissions_chart, admitted_patients_chart
10+
from src.penn_chime.charts import new_admissions_chart, admitted_patients_chart, chart_descriptions
911
from src.penn_chime.models import sir, sim_sir, build_admissions_df
1012
from src.penn_chime.parameters import Parameters
1113
from src.penn_chime.presentation import display_header
@@ -254,3 +256,41 @@ def test_parameters():
254256
0.05 * 0.05 * (param.infected_v[1:-1] + param.recovered_v[1:-1]) - 100
255257
)
256258
assert (diff.abs() < 0.1).all()
259+
assert len(param.susceptible_v) == len(param.infected_v) == len(param.recovered_v) == param.n_days + 1 == 3
260+
261+
262+
def test_chart_descriptions():
263+
# new admissions chart
264+
projection_admits = pd.read_csv('tests/projection_admits.csv')
265+
projection_admits = projection_admits.rename(columns={'hosp': 'Hospitalized', 'icu': 'ICU', 'vent': 'Ventilated'})
266+
chart = new_admissions_chart(alt, projection_admits, PARAM)
267+
description = chart_descriptions(chart)
268+
269+
hosp, icu, vent, asterisk = description.split("\n\n") # break out the description into lines
270+
271+
max_hosp = chart.data['Hospitalized'].max()
272+
assert str(ceil(max_hosp)) in hosp
273+
274+
max_icu_ix = chart.data['ICU'].idxmax()
275+
assert max_icu_ix + 1 == len(chart.data)
276+
assert "*" in icu
277+
278+
# test asterisk
279+
param = PARAM
280+
param.n_days = 600
281+
282+
projection_admits = pd.read_csv('tests/projection_admits.csv')
283+
projection_admits = projection_admits.rename(columns={'hosp': 'Hospitalized', 'icu': 'ICU', 'vent': 'Ventilated'})
284+
chart = new_admissions_chart(alt, projection_admits, PARAM)
285+
description = chart_descriptions(chart)
286+
assert "*" not in description
287+
288+
# census chart
289+
census_df = pd.read_csv('tests/census_df.csv')
290+
census_df = census_df.rename(columns={'hosp': 'Hospitalized', 'icu': 'ICU', 'vent': 'Ventilated'})
291+
chart = admitted_patients_chart(alt, census_df, PARAM, as_date=True)
292+
description = chart_descriptions(chart)
293+
294+
assert str(ceil(chart.data['Ventilated'].max())) in description
295+
assert str(chart.data['ICU'].idxmax()) not in description
296+
assert datetime.datetime.strftime(chart.data.iloc[chart.data['ICU'].idxmax()].date, '%b %d') in description

0 commit comments

Comments
 (0)