11from typing import Dict , Optional
22
3- from altair import Chart
3+ from altair import Chart , Scale
44import pandas as pd
55import numpy as np
66
77from ..constants import DATE_FORMAT
88
99
1010def build_admits_chart (
11- * , alt , admits_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None
11+ * , alt , admits_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None , use_log_scale : bool = False
1212) -> Chart :
13- """Build admits chart."""
14- y_scale = alt .Scale ()
15- if max_y_axis is not None :
16- y_scale .domain = (0 , max_y_axis )
13+ """
14+ This builds the "New Admissions" chart, projecting daily admissions over time.
1715
18- x = dict (shorthand = "date:T" , title = "Date" , axis = alt .Axis (format = (DATE_FORMAT )))
16+ Args:
17+ alt: Reference to Altair package.
18+ admits_floor_df: Pandas data frame containing three columns: "admits_hospitalized", "admits_icu", and
19+ "admits_ventilated".
20+ max_y_axis: Optional maximum value for the Y axis of the chart.
21+ use_log_scale: Set to true to use a logarithmic scale on the Y axis. Default is linear scale.
22+
23+ Returns: The newly created chart.
24+
25+ """
26+
27+ adjusted_admits_floor_df = __adjust_data_for_log_scale (admits_floor_df ) if use_log_scale else admits_floor_df
28+ y_scale = __build_y_scale (alt , max_y_axis , use_log_scale )
29+
30+ x = dict (shorthand = "date:T" , title = "Date" , axis = alt .Axis (format = DATE_FORMAT ))
1931 y = dict (shorthand = "value:Q" , title = "Daily admissions" , scale = y_scale )
2032 color = "key:N"
2133 tooltip = ["date:T" , alt .Tooltip ("value:Q" , format = ".0f" , title = "Admit" ), "key:N" ]
@@ -40,19 +52,31 @@ def build_admits_chart(
4052 .mark_rule (color = "black" , opacity = 0.35 , size = 2 )
4153 )
4254 return (
43- alt .layer (points , bar , data = admits_floor_df )
55+ alt .layer (points , bar , data = adjusted_admits_floor_df )
4456 .configure_legend (orient = "bottom" )
4557 .interactive ()
4658 )
4759
4860
4961def build_census_chart (
50- * , alt , census_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None
62+ * , alt , census_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None , use_log_scale : bool = False
5163) -> Chart :
52- """Build census chart."""
53- y_scale = alt .Scale ()
54- if max_y_axis :
55- y_scale .domain = (0 , max_y_axis )
64+ """
65+ This builds the "Admitted Patients" census chart, projecting total number of patients in the hospital over time.
66+
67+ Args:
68+ alt: Reference to Altair package.
69+ census_floor_df: Pandas data frame containing three columns: "census_hospitalized", "census_icu", and
70+ "census_ventilated".
71+ max_y_axis: Optional maximum value for the Y axis of the chart.
72+ use_log_scale: Set to true to use a logarithmic scale on the Y axis. Default is linear scale.
73+
74+ Returns: The newly created chart.
75+
76+ """
77+
78+ adjusted_census_floor_df = __adjust_data_for_log_scale (census_floor_df ) if use_log_scale else census_floor_df
79+ y_scale = __build_y_scale (alt , max_y_axis , use_log_scale )
5680
5781 x = dict (shorthand = "date:T" , title = "Date" , axis = alt .Axis (format = (DATE_FORMAT )))
5882 y = dict (shorthand = "value:Q" , title = "Census" , scale = y_scale )
@@ -79,19 +103,31 @@ def build_census_chart(
79103 .mark_rule (color = "black" , opacity = 0.35 , size = 2 )
80104 )
81105 return (
82- alt .layer (points , bar , data = census_floor_df )
106+ alt .layer (points , bar , data = adjusted_census_floor_df )
83107 .configure_legend (orient = "bottom" )
84108 .interactive ()
85109 )
86110
87111
88112def build_sim_sir_w_date_chart (
89- * , alt , sim_sir_w_date_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None
113+ * , alt , sim_sir_w_date_floor_df : pd .DataFrame , max_y_axis : Optional [int ] = None , use_log_scale : bool = False
90114) -> Chart :
91- """Build sim sir w date chart."""
92- y_scale = alt .Scale ()
93- if max_y_axis is not None :
94- y_scale .domain = (0 , max_y_axis )
115+ """
116+ This builds the "Susceptible, Infected, and Recovered" chart, projecting the number of those individuals in the
117+ hospital's region over time.
118+
119+ Args:
120+ alt: Reference to the Altair package.
121+ sim_sir_w_date_floor_df: A Pandas data frame with columns named "susceptible", "infected", and "recovered".
122+ max_y_axis: Optional maximum value for the Y axis of the chart.
123+ use_log_scale: Set to true to use a logarithmic scale on the Y axis. Default is linear scale.
124+
125+ Returns: The newly created chart.
126+
127+ """
128+
129+ 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
130+ y_scale = __build_y_scale (alt , max_y_axis , use_log_scale )
95131
96132 x = dict (shorthand = "date:T" , title = "Date" , axis = alt .Axis (format = (DATE_FORMAT )))
97133 y = dict (shorthand = "value:Q" , title = "Count" , scale = y_scale )
@@ -118,7 +154,7 @@ def build_sim_sir_w_date_chart(
118154 .mark_rule (color = "black" , opacity = 0.35 , size = 2 )
119155 )
120156 return (
121- alt .layer (points , bar , data = sim_sir_w_date_floor_df )
157+ alt .layer (points , bar , data = adjusted_sim_sir_w_date_floor_df )
122158 .configure_legend (orient = "bottom" )
123159 .interactive ()
124160 )
@@ -131,3 +167,37 @@ def build_table(
131167 table_df .date = table_df .date .dt .strftime (DATE_FORMAT )
132168 table_df .rename (labels )
133169 return table_df
170+
171+
172+ def __adjust_data_for_log_scale (dataframe : pd .DataFrame ) -> pd .DataFrame :
173+ """
174+ This will clean and adjust some of the data so that Altair can plot it using a logarithmic scale. Altair does not
175+ allow zero values on the Y axis when plotting with a logarithmic scale, as log(0) is undefined.
176+
177+ Args:
178+ dataframe: The data to plot on the chart.
179+
180+ Returns: A new data frame with the appropriate adjustments for plotting on a log scale.
181+
182+ """
183+ return dataframe .replace (0 , float ('nan' )) # We use NaN so that the values will not appear at all on the chart.
184+
185+
186+ def __build_y_scale (alt , max_y_axis : Optional [int ] = None , use_log_scale : bool = False ) -> Scale :
187+ """
188+ Creates the Y axis of the chart, taking into account some of the configuration parameters set by the user.
189+
190+ Args:
191+ alt: Reference to Altair package.
192+ max_y_axis: The maximum value of the Y axis. This is optional.
193+ use_log_scale: Whether to use a logarithmic scale instead of a linear scale.
194+
195+ Returns: A newly created Scale instance.
196+
197+ """
198+ scale_type = 'log' if use_log_scale else 'linear'
199+ y_scale = alt .Scale (type = scale_type )
200+ if max_y_axis is not None :
201+ y_scale .domain = (0 , max_y_axis )
202+
203+ return y_scale
0 commit comments