1
1
from typing import Dict , Optional
2
2
3
- from altair import Chart
3
+ from altair import Chart , Scale
4
4
import pandas as pd
5
5
import i18n
6
6
import numpy as np
9
9
10
10
11
11
def build_admits_chart (
12
- * , alt , admits_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None
12
+ * , alt , admits_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None , use_log_scale : bool = False
13
13
) -> Chart :
14
- """Build admits chart."""
15
- y_scale = alt .Scale ()
16
- if max_y_axis is not None :
17
- y_scale .domain = (0 , max_y_axis )
14
+ """
15
+ This builds the "New Admissions" chart, projecting daily admissions over time.
16
+
17
+ Args:
18
+ alt: Reference to Altair package.
19
+ admits_floor_df: Pandas data frame containing three columns: "admits_hospitalized", "admits_icu", and
20
+ "admits_ventilated".
21
+ max_y_axis: Optional maximum value for the Y axis of the chart.
22
+ use_log_scale: Set to true to use a logarithmic scale on the Y axis. Default is linear scale.
23
+
24
+ Returns: The newly created chart.
25
+
26
+ """
27
+
28
+ adjusted_admits_floor_df = __adjust_data_for_log_scale (admits_floor_df ) if use_log_scale else admits_floor_df
29
+ y_scale = __build_y_scale (alt , max_y_axis , use_log_scale )
18
30
19
31
x = dict (shorthand = "date:T" , title = i18n .t ("charts-date" ), axis = alt .Axis (format = (DATE_FORMAT )))
20
32
y = dict (shorthand = "value:Q" , title = i18n .t ("charts-daily-admissions" ), scale = y_scale )
@@ -40,7 +52,7 @@ def build_admits_chart(
40
52
.transform_filter (alt .datum .day == 0 )
41
53
.mark_rule (color = "black" , opacity = 0.35 , size = 2 )
42
54
)
43
- admits_floor_df_renamed = admits_floor_df .rename ({
55
+ admits_floor_df_renamed = adjusted_admits_floor_df .rename ({
44
56
"admits_hospitalized" : i18n .t ("admits_hospitalized" ),
45
57
"admits_icu" : i18n .t ("admits_icu" ),
46
58
"admits_ventilated" : i18n .t ("admits_ventilated" )
@@ -53,12 +65,24 @@ def build_admits_chart(
53
65
54
66
55
67
def build_census_chart (
56
- * , alt , census_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None
68
+ * , alt , census_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None , use_log_scale : bool = False
57
69
) -> Chart :
58
- """Build census chart."""
59
- y_scale = alt .Scale ()
60
- if max_y_axis :
61
- y_scale .domain = (0 , max_y_axis )
70
+ """
71
+ This builds the "Admitted Patients" census chart, projecting total number of patients in the hospital over time.
72
+
73
+ Args:
74
+ alt: Reference to Altair package.
75
+ census_floor_df: Pandas data frame containing three columns: "census_hospitalized", "census_icu", and
76
+ "census_ventilated".
77
+ max_y_axis: Optional maximum value for the Y axis of the chart.
78
+ use_log_scale: Set to true to use a logarithmic scale on the Y axis. Default is linear scale.
79
+
80
+ Returns: The newly created chart.
81
+
82
+ """
83
+
84
+ adjusted_census_floor_df = __adjust_data_for_log_scale (census_floor_df ) if use_log_scale else census_floor_df
85
+ y_scale = __build_y_scale (alt , max_y_axis , use_log_scale )
62
86
63
87
x = dict (shorthand = "date:T" , title = i18n .t ("charts-date" ), axis = alt .Axis (format = (DATE_FORMAT )))
64
88
y = dict (shorthand = "value:Q" , title = i18n .t ("charts-census" ), scale = y_scale )
@@ -84,7 +108,7 @@ def build_census_chart(
84
108
.transform_filter (alt .datum .day == 0 )
85
109
.mark_rule (color = "black" , opacity = 0.35 , size = 2 )
86
110
)
87
- census_floor_df_renamed = census_floor_df .rename ({
111
+ census_floor_df_renamed = adjusted_census_floor_df .rename ({
88
112
"census_hospitalized" : i18n .t ("census_hospitalized" ),
89
113
"census_icu" : i18n .t ("census_icu" ),
90
114
"census_ventilated" : i18n .t ("census_ventilated" )
@@ -97,12 +121,24 @@ def build_census_chart(
97
121
98
122
99
123
def build_sim_sir_w_date_chart (
100
- * , alt , sim_sir_w_date_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None
124
+ * , alt , sim_sir_w_date_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None , use_log_scale : bool = False
101
125
) -> Chart :
102
- """Build sim sir w date chart."""
103
- y_scale = alt .Scale ()
104
- if max_y_axis is not None :
105
- y_scale .domain = (0 , max_y_axis )
126
+ """
127
+ This builds the "Susceptible, Infected, and Recovered" chart, projecting the number of those individuals in the
128
+ hospital's region over time.
129
+
130
+ Args:
131
+ alt: Reference to the Altair package.
132
+ sim_sir_w_date_floor_df: A Pandas data frame with columns named "susceptible", "infected", and "recovered".
133
+ max_y_axis: Optional maximum value for the Y axis of the chart.
134
+ use_log_scale: Set to true to use a logarithmic scale on the Y axis. Default is linear scale.
135
+
136
+ Returns: The newly created chart.
137
+
138
+ """
139
+
140
+ adjusted_sim_sir_w_date_floor_df = __adjust_data_for_log_scale (sim_sir_w_date_floor_df ) if use_log_scale else sim_sir_w_date_floor_df
141
+ y_scale = __build_y_scale (alt , max_y_axis , use_log_scale )
106
142
107
143
x = dict (shorthand = "date:T" , title = i18n .t ("charts-date" ), axis = alt .Axis (format = (DATE_FORMAT )))
108
144
y = dict (shorthand = "value:Q" , title = i18n .t ("charts-count" ), scale = y_scale )
@@ -128,7 +164,7 @@ def build_sim_sir_w_date_chart(
128
164
.transform_filter (alt .datum .day == 0 )
129
165
.mark_rule (color = "black" , opacity = 0.35 , size = 2 )
130
166
)
131
- sim_sir_w_date_floor_df_renamed = sim_sir_w_date_floor_df .rename ({
167
+ sim_sir_w_date_floor_df_renamed = adjusted_sim_sir_w_date_floor_df .rename ({
132
168
"susceptible" : i18n .t ("susceptible" ),
133
169
"infected" : i18n .t ("infected" ),
134
170
"recovered" : i18n .t ("recovered" )
@@ -146,3 +182,37 @@ def build_table(
146
182
table_df .date = table_df .date .dt .strftime (DATE_FORMAT )
147
183
table_df_renamed = table_df .rename (labels , axis = 1 )
148
184
return table_df_renamed
185
+
186
+
187
+ def __adjust_data_for_log_scale (dataframe : pd .DataFrame ) -> pd .DataFrame :
188
+ """
189
+ This will clean and adjust some of the data so that Altair can plot it using a logarithmic scale. Altair does not
190
+ allow zero values on the Y axis when plotting with a logarithmic scale, as log(0) is undefined.
191
+
192
+ Args:
193
+ dataframe: The data to plot on the chart.
194
+
195
+ Returns: A new data frame with the appropriate adjustments for plotting on a log scale.
196
+
197
+ """
198
+ return dataframe .replace (0 , float ('nan' )) # We use NaN so that the values will not appear at all on the chart.
199
+
200
+
201
+ def __build_y_scale (alt , max_y_axis : Optional [int ] = None , use_log_scale : bool = False ) -> Scale :
202
+ """
203
+ Creates the Y axis of the chart, taking into account some of the configuration parameters set by the user.
204
+
205
+ Args:
206
+ alt: Reference to Altair package.
207
+ max_y_axis: The maximum value of the Y axis. This is optional.
208
+ use_log_scale: Whether to use a logarithmic scale instead of a linear scale.
209
+
210
+ Returns: A newly created Scale instance.
211
+
212
+ """
213
+ scale_type = 'log' if use_log_scale else 'linear'
214
+ y_scale = alt .Scale (type = scale_type )
215
+ if max_y_axis is not None :
216
+ y_scale .domain = (0 , max_y_axis )
217
+
218
+ return y_scale
0 commit comments