special.py
1 from typing import List 2 from typing import Optional 3 from typing import Sequence 4 from typing import Tuple 5 6 import pandas as pd 7 8 from evidently.core.container import MetricContainer 9 from evidently.core.container import MetricOrContainer 10 from evidently.core.datasets import TestSummaryInfo 11 from evidently.core.metric_types import ByLabelCountValue 12 from evidently.core.metric_types import Metric 13 from evidently.core.metric_types import MetricId 14 from evidently.core.metric_types import SingleValue 15 from evidently.core.report import Context 16 from evidently.legacy.metric_results import HistogramData 17 from evidently.legacy.model.widget import BaseWidgetInfo 18 from evidently.legacy.model.widget import WidgetType 19 from evidently.legacy.options import ColorOptions 20 from evidently.legacy.renderers.html_widgets import WidgetSize 21 from evidently.legacy.renderers.html_widgets import group_widget 22 from evidently.legacy.renderers.html_widgets import histogram 23 from evidently.legacy.renderers.html_widgets import pie_chart 24 from evidently.legacy.tests.base_test import TestStatus 25 from evidently.metrics import MeanValue 26 from evidently.metrics import UniqueValueCount 27 28 29 class TestSummaryInfoPreset(MetricContainer): 30 column_info: TestSummaryInfo 31 32 def generate_metrics(self, context: "Context") -> Sequence[MetricOrContainer]: 33 result = [] 34 if self.column_info.has_all: 35 result.append(self._all_metric) 36 if self.column_info.has_any: 37 result.append(self._any_metric) 38 if self.column_info.has_count: 39 result.append(self._count_metric) 40 if self.column_info.has_rate: 41 result.append(self._rate_metric) 42 if self.column_info.has_score: 43 result.append(self._score_metric) 44 return result 45 46 @property 47 def _all_metric(self) -> Metric: 48 return UniqueValueCount(column=self.column_info.all_column) 49 50 @property 51 def _any_metric(self) -> Metric: 52 return UniqueValueCount(column=self.column_info.any_column) 53 54 @property 55 def _count_metric(self) -> Metric: 56 return UniqueValueCount(column=self.column_info.count_column) 57 58 @property 59 def _rate_metric(self) -> Metric: 60 return MeanValue(column=self.column_info.rate_column) 61 62 @property 63 def _score_metric(self) -> Metric: 64 return MeanValue(column=self.column_info.score_column) 65 66 def render( 67 self, context: "Context", child_widgets: Optional[List[Tuple[Optional[MetricId], List[BaseWidgetInfo]]]] = None 68 ) -> List[BaseWidgetInfo]: 69 widgets = [] 70 if self.column_info.has_all: 71 all_results = context.get_metric_result(self._all_metric) 72 assert isinstance(all_results, ByLabelCountValue) 73 widgets.append( 74 pie_chart( 75 title="All tests passed", 76 size=WidgetSize.HALF, 77 data={ 78 TestStatus.SUCCESS.value: all_results.counts[True].value if True in all_results.counts else 0, 79 TestStatus.FAIL.value: all_results.counts[False].value if False in all_results.counts else 0, 80 }, 81 ) 82 ) 83 if self.column_info.has_any: 84 any_results = context.get_metric_result(self._any_metric) 85 assert isinstance(any_results, ByLabelCountValue) 86 widgets.append( 87 pie_chart( 88 title="Any tests passed", 89 size=WidgetSize.HALF, 90 data={ 91 TestStatus.SUCCESS.value: any_results.counts[True].value if True in any_results.counts else 0, 92 TestStatus.FAIL.value: any_results.counts[False].value if False in any_results.counts else 0, 93 }, 94 ) 95 ) 96 97 if self.column_info.has_count: 98 count_results = context.get_metric_result(self._count_metric) 99 assert isinstance(count_results, ByLabelCountValue) 100 widgets.append( 101 histogram( 102 title="Count of tests passed", 103 color_options=ColorOptions(), 104 size=WidgetSize.HALF, 105 primary_hist=HistogramData( 106 x=pd.Series(count_results.counts.keys()), 107 count=pd.Series([v.value for v in count_results.counts.values()]), 108 ), 109 ) 110 ) 111 if self.column_info.has_rate: 112 rate_results = context.get_metric_result(self._rate_metric) 113 assert isinstance(rate_results, SingleValue) 114 assert rate_results.widget is not None 115 distr_widget = rate_results.widget[0] 116 widgets.append( 117 BaseWidgetInfo( 118 title="Rate of tests passed", 119 type=WidgetType.BIG_GRAPH.value, 120 size=WidgetSize.HALF, 121 params=distr_widget.params, 122 ) 123 ) 124 if self.column_info.has_score: 125 score_results = context.get_metric_result(self._score_metric) 126 assert isinstance(score_results, SingleValue) 127 assert score_results.widget is not None 128 distr_widget = score_results.widget[0] 129 widgets.append( 130 BaseWidgetInfo( 131 title="Row scores", 132 type=WidgetType.BIG_GRAPH.value, 133 size=WidgetSize.HALF, 134 params=distr_widget.params, 135 ) 136 ) 137 return [group_widget(title="Row test summary", widgets=widgets)]