/ src / evidently / presets / special.py
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)]