def fixed_viewpoint_selector( base: alt.Chart, active_fixed_viewpoint_selector: bool = False) -> alt.Chart: """Transparent selectors across the chart (visible on hover). This is what tells us the belief time for a given x-value of the cursor. :param active_fixed_viewpoint_selector: if False, return an idle colored version without tooltip """ selector = base.mark_rule().encode( x=alt.X("belief_time:T", scale={"domain": time_selection_brush.ref()}), color=alt.ColorValue(idle_color) if not active_fixed_viewpoint_selector else alt.ColorValue("#c21431"), opacity=alt.condition(nearest_x_hover_brush, alt.value(1), alt.value(0)), tooltip=[ alt.Tooltip( "belief_time:T", timeUnit="yearmonthdatehoursminutes", title="Click to select belief time", ) ] if active_fixed_viewpoint_selector is True else None, ) return selector.add_selection(nearest_x_select_brush).add_selection( nearest_x_hover_brush)
def value_vs_time_chart( base: alt.Chart, active_fixed_viewpoint_selector: bool, sensor_name: str, sensor_unit: str, belief_horizon_unit: str, intuitive_forecast_horizon: bool, interpolate: bool, ci: float, event_value_range: Tuple[float, float], ) -> alt.LayerChart: # Configure the stepwise line for the reference if interpolate is True: ts_line_reference_chart = base.mark_line(interpolate="monotone") else: ts_line_reference_chart = base.mark_rule().encode(x2=alt.X2("event_end:T")) ts_line_reference_chart = ts_line_reference_chart.encode( y=alt.Y( "reference_value", scale=alt.Scale(domain=(event_value_range[0], event_value_range[-1])), ), color=alt.ColorValue("black"), tooltip=[ alt.Tooltip( "event_start:T", timeUnit="yearmonthdatehoursminutes", title="Event start", ), alt.Tooltip( "event_end:T", timeUnit="yearmonthdatehoursminutes", title="Event end" ), alt.Tooltip("reference_value:Q", title="Real value", format=".2f"), ], ) # Configure the stepwise line for the beliefs if interpolate is True: ts_line_chart = base.mark_line(interpolate="monotone") else: ts_line_chart = base.mark_rule().encode(x2=alt.X2("event_end:T")) ts_line_chart = ts_line_chart.encode( y=alt.Y("expected_value", title="%s (%s)" % (sensor_name, sensor_unit)) ) if active_fixed_viewpoint_selector is True: ts_line_chart = ( ts_line_chart.transform_filter( "datum.belief_time <= nearest_x_select.belief_time" ) .transform_joinaggregate( most_recent_belief_time="max(belief_time)", groupby=["event_start", "source"], ) .transform_filter("datum.belief_time == datum.most_recent_belief_time") ) # Configure the confidence intervals if interpolate is True: confidence_interval = ts_line_chart.mark_area( interpolate="monotone", opacity=0.3 ) else: confidence_interval = ts_line_chart.mark_bar(opacity=0.3) confidence_interval = confidence_interval.encode( y="lower_value", y2="upper_value", tooltip=[ alt.Tooltip( "event_start:T", timeUnit="yearmonthdatehoursminutes", title="Event start", ), alt.Tooltip( "event_end:T", timeUnit="yearmonthdatehoursminutes", title="Event end" ), alt.Tooltip("expected_value:Q", title="Expected value", format=".2f"), alt.Tooltip( "belief_time:T", timeUnit="yearmonthdatehoursminutes", title="Belief time", ), alt.Tooltip( "belief_horizon:Q", title="%s (%s)" % ( "Forecast horizon" if intuitive_forecast_horizon else "Belief horizon", belief_horizon_unit, ), ), alt.Tooltip("source", title="Source"), alt.Tooltip( "upper_value:Q", format=".2f", title="Upper value of {0:.0f}% confidence interval".format(100 * ci), ), alt.Tooltip( "lower_value:Q", format=".2f", title="Lower value of {0:.0f}% confidence interval".format(100 * ci), ), ], ) return (ts_line_reference_chart + ts_line_chart + confidence_interval).properties( title="Model results" )
def horizon_selector( base: alt.Chart, horizon_selection_brush: alt.MultiSelection, belief_horizon_unit: str, intuitive_forecast_horizon: bool, unique_belief_horizons, ) -> alt.LayerChart: bar_chart = ( base.mark_rule(orient="vertical").transform_filter( time_selection_brush ) # Apply brush before calculating accuracy metrics for the selected events on the fly .transform_calculate( constant=1 + alt.datum.event_start - alt.datum.event_start).transform_calculate( belief_horizon_str='datum.belief_horizon + " %s"' % belief_horizon_unit). encode( opacity=alt.condition( time_selection_brush, alt.Opacity("event_start:T", scale=alt.Scale(domain=(0.9999, 1)), legend=None), alt.value(0), ), # Trick to be able to apply the selection filter for event_start (event_start must be a field in one of the encoding channels) x=alt.X( "belief_horizon:Q", axis=alt.Axis(labelFlush=False), scale=alt.Scale( zero=False, domain=(unique_belief_horizons[0], unique_belief_horizons[-1]), ), title="", ), y=alt.Y( "constant:Q", title=" ", axis=alt.Axis(values=[], domain=False, ticks=False), ), color=alt.condition( horizon_selection_brush | horizon_hover_brush, alt.ColorValue("#c21431"), alt.ColorValue(idle_color), ), size=alt.value(1), tooltip=[ alt.Tooltip( "belief_horizon_str:N", title="Click to select %s" % ("forecast horizon" if intuitive_forecast_horizon else "belief horizon"), ) ], ).properties( height=30, title="Select %s" % ("forecast horizon" if intuitive_forecast_horizon else "belief horizon"), ).transform_filter(time_selection_brush)) circle_chart = (bar_chart.mark_circle().transform_calculate( half_constant=alt.datum.constant / 2).encode( y=alt.Y("half_constant:Q", title="", axis=alt.Axis(values=[])), size=alt.value(100), )) return ( bar_chart.add_selection(horizon_selection_brush, horizon_hover_brush) + circle_chart)