We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] [CV] Image property drift - fix error
**Describe the bug**
fix error in image property drift

**To Reproduce**
Steps to reproduce the behavior:
1. Go to https://www.kaggle.com/code/itay94/notebookc2fb7a0a35

**Screenshots**
![image](https://user-images.githubusercontent.com/20860465/161570603-b7535655-1beb-4aa0-b7a7-4c7d56d17b94.png)

**Environment (please complete the following information):**
 - OS: Kaggle
 - Python Version: Kaggle
 - Deepchecks Version: 0.6.0



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `deepchecks/vision/checks/distribution/image_property_drift.py`
Content:
```
1 # ----------------------------------------------------------------------------
2 # Copyright (C) 2021-2022 Deepchecks (https://www.deepchecks.com)
3 #
4 # This file is part of Deepchecks.
5 # Deepchecks is distributed under the terms of the GNU Affero General
6 # Public License (version 3 or later).
7 # You should have received a copy of the GNU Affero General Public License
8 # along with Deepchecks.  If not, see <http://www.gnu.org/licenses/>.
9 # ----------------------------------------------------------------------------
10 #
11 """Module contains Image Property Drift check."""
12 import typing as t
13 from collections import defaultdict
14 
15 import pandas as pd
16 
17 from deepchecks.core import CheckResult
18 from deepchecks.core import ConditionResult
19 from deepchecks.core import DatasetKind
20 from deepchecks.core.errors import NotEnoughSamplesError, DeepchecksValueError
21 from deepchecks.core.condition import ConditionCategory
22 from deepchecks.utils.distribution.drift import calc_drift_and_plot
23 from deepchecks.vision import Batch
24 from deepchecks.vision import Context
25 from deepchecks.vision import TrainTestCheck
26 from deepchecks.vision.utils.image_properties import validate_properties, default_image_properties, get_column_type
27 
28 
29 __all__ = ['ImagePropertyDrift']
30 
31 
32 TImagePropertyDrift = t.TypeVar('TImagePropertyDrift', bound='ImagePropertyDrift')
33 
34 
35 class ImagePropertyDrift(TrainTestCheck):
36     """
37     Calculate drift between train dataset and test dataset per image property, using statistical measures.
38 
39     Check calculates a drift score for each image property in test dataset, by comparing its distribution to the train
40     dataset. For this, we use the Earth Movers Distance.
41 
42     See https://en.wikipedia.org/wiki/Wasserstein_metric
43 
44     Parameters
45     ----------
46     image_properties : List[Dict[str, Any]], default: None
47         List of properties. Replaces the default deepchecks properties.
48         Each property is dictionary with keys 'name' (str), 'method' (Callable) and 'output_type' (str),
49         representing attributes of said method. 'output_type' must be one of 'continuous'/'discrete'
50     max_num_categories: int, default: 10
51     classes_to_display : Optional[List[float]], default: None
52         List of classes to display. The distribution of the properties would include only samples belonging (or
53         containing an annotation belonging) to one of these classes. If None, samples from all classes are displayed.
54     min_samples: int, default: 10
55         Minimum number of samples needed in each dataset needed to calculate the drift.
56     """
57 
58     def __init__(
59         self,
60         image_properties: t.List[t.Dict[str, t.Any]] = None,
61         max_num_categories: int = 10,
62         classes_to_display: t.Optional[t.List[str]] = None,
63         min_samples: int = 30,
64         **kwargs
65     ):
66         super().__init__(**kwargs)
67         if image_properties is not None:
68             validate_properties(image_properties)
69             self.image_properties = image_properties
70         else:
71             self.image_properties = default_image_properties
72 
73         self.max_num_categories = max_num_categories
74         self.classes_to_display = classes_to_display
75         self.min_samples = min_samples
76         self._train_properties = None
77         self._test_properties = None
78         self._class_to_string = None
79 
80     def initialize_run(self, context: Context):
81         """Initialize self state, and validate the run context."""
82         self._class_to_string = context.train.label_id_to_name
83         self._train_properties = defaultdict(list)
84         self._test_properties = defaultdict(list)
85 
86     def update(
87         self,
88         context: Context,
89         batch: Batch,
90         dataset_kind: DatasetKind
91     ):
92         """Calculate image properties for train or test batch."""
93         if dataset_kind == DatasetKind.TRAIN:
94             properties = self._train_properties
95         elif dataset_kind == DatasetKind.TEST:
96             properties = self._test_properties
97         else:
98             raise RuntimeError(
99                 f'Internal Error - Should not reach here! unknown dataset_kind: {dataset_kind}'
100             )
101 
102         images = batch.images
103 
104         if self.classes_to_display:
105             # use only images belonging (or containing an annotation belonging) to one of the classes in
106             # classes_to_display
107             classes = context.train.get_classes(batch.labels)
108             images = [
109                 image for idx, image in enumerate(images) if
110                 any(cls in map(self._class_to_string, classes[idx]) for cls in self.classes_to_display)
111             ]
112 
113         for single_property in self.image_properties:
114             property_list = single_property['method'](images)
115             properties[single_property['name']].extend(property_list)
116 
117     def compute(self, context: Context) -> CheckResult:
118         """Calculate drift score between train and test datasets for the collected image properties.
119 
120         Returns
121         -------
122         CheckResult
123             value: dictionary containing drift score for each image property.
124             display: distribution graph for each image property.
125         """
126         if sorted(self._train_properties.keys()) != sorted(self._test_properties.keys()):
127             raise RuntimeError('Internal Error! Vision check was used improperly.')
128 
129         # if self.classes_to_display is set, check that it has classes that actually exist
130         if self.classes_to_display is not None:
131             if not set(self.classes_to_display).issubset(
132                     map(self._class_to_string, context.train.classes_indices.keys())
133             ):
134                 raise DeepchecksValueError(
135                     f'Provided list of class ids to display {self.classes_to_display} not found in training dataset.'
136                 )
137 
138         properties = sorted(self._train_properties.keys())
139         df_train = pd.DataFrame(self._train_properties)
140         df_test = pd.DataFrame(self._test_properties)
141         if len(df_train) < self.min_samples or len(df_test) < self.min_samples:
142             return CheckResult(
143                 value=None,
144                 display=f'Not enough samples to calculate drift score, min {self.min_samples} samples required.',
145                 header='Image Property Drift'
146             )
147 
148         figures = {}
149         drifts = {}
150 
151         for single_property in self.image_properties:
152             property_name = single_property['name']
153 
154             try:
155                 score, _, figure = calc_drift_and_plot(
156                     train_column=df_train[property_name],
157                     test_column=df_test[property_name],
158                     value_name=property_name,
159                     column_type=get_column_type(single_property['output_type']),
160                     max_num_categories=self.max_num_categories,
161                     min_samples=self.min_samples
162                 )
163 
164                 figures[property_name] = figure
165                 drifts[property_name] = score
166             except NotEnoughSamplesError:
167                 figures[property_name] = '<p>Not enough non-null samples to calculate drift</p>'
168                 drifts[property_name] = 0
169 
170         if drifts:
171             columns_order = sorted(properties, key=lambda col: drifts[col], reverse=True)
172 
173             headnote = '<span>' \
174                        'The Drift score is a measure for the difference between two distributions. ' \
175                        'In this check, drift is measured ' \
176                        f'for the distribution of the following image properties: {properties}.' \
177                        '</span>'
178 
179             displays = [headnote] + [figures[col] for col in columns_order]
180         else:
181             drifts = None
182             displays = []
183 
184         return CheckResult(
185             value=drifts,
186             display=displays,
187             header='Image Property Drift'
188         )
189 
190     def add_condition_drift_score_not_greater_than(
191         self: TImagePropertyDrift,
192         max_allowed_drift_score: float = 0.1
193     ) -> TImagePropertyDrift:
194         """
195         Add condition - require drift score to not be more than a certain threshold.
196 
197         Parameters
198         ----------
199         max_allowed_drift_score: float ,  default: 0.1
200             the max threshold for the Earth Mover's Distance score
201 
202         Returns
203         -------
204         ConditionResult
205             False if any column has passed the max threshold, True otherwise
206         """
207 
208         def condition(result: t.Dict[str, float]) -> ConditionResult:
209             failed_properties = [
210                 (property_name, drift_score)
211                 for property_name, drift_score in result.items()
212                 if drift_score > max_allowed_drift_score
213             ]
214             if len(failed_properties) > 0:
215                 failed_properties = ';\n'.join(f'{p}={d:.2f}' for p, d in failed_properties)
216                 return ConditionResult(
217                     False,
218                     'Earth Mover\'s Distance is above the threshold '
219                     f'for the next properties:\n{failed_properties}'
220                 )
221             return ConditionResult(ConditionCategory.PASS)
222 
223         return self.add_condition(
224             f'Earth Mover\'s Distance <= {max_allowed_drift_score} for image properties drift',
225             condition
226         )
227
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/deepchecks/vision/checks/distribution/image_property_drift.py b/deepchecks/vision/checks/distribution/image_property_drift.py
--- a/deepchecks/vision/checks/distribution/image_property_drift.py
+++ b/deepchecks/vision/checks/distribution/image_property_drift.py
@@ -139,10 +139,10 @@
         df_train = pd.DataFrame(self._train_properties)
         df_test = pd.DataFrame(self._test_properties)
         if len(df_train) < self.min_samples or len(df_test) < self.min_samples:
-            return CheckResult(
-                value=None,
-                display=f'Not enough samples to calculate drift score, min {self.min_samples} samples required.',
-                header='Image Property Drift'
+            raise NotEnoughSamplesError(
+                f'Not enough samples to calculate drift score, minimum {self.min_samples} samples required'
+                f', but got {len(df_train)} and {len(df_test)} samples in the train and test datasets.'
+                'Use \'min_samples\' parameter to change the requirement.'
             )
 
         figures = {}

{"golden_diff": "diff --git a/deepchecks/vision/checks/distribution/image_property_drift.py b/deepchecks/vision/checks/distribution/image_property_drift.py\n--- a/deepchecks/vision/checks/distribution/image_property_drift.py\n+++ b/deepchecks/vision/checks/distribution/image_property_drift.py\n@@ -139,10 +139,10 @@\n         df_train = pd.DataFrame(self._train_properties)\n         df_test = pd.DataFrame(self._test_properties)\n         if len(df_train) < self.min_samples or len(df_test) < self.min_samples:\n-            return CheckResult(\n-                value=None,\n-                display=f'Not enough samples to calculate drift score, min {self.min_samples} samples required.',\n-                header='Image Property Drift'\n+            raise NotEnoughSamplesError(\n+                f'Not enough samples to calculate drift score, minimum {self.min_samples} samples required'\n+                f', but got {len(df_train)} and {len(df_test)} samples in the train and test datasets.'\n+                'Use \\'min_samples\\' parameter to change the requirement.'\n             )\n \n         figures = {}\n", "issue": "[BUG] [CV] Image property drift - fix error\n**Describe the bug**\r\nfix error in image property drift\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Go to https://www.kaggle.com/code/itay94/notebookc2fb7a0a35\r\n\r\n**Screenshots**\r\n![image](https://user-images.githubusercontent.com/20860465/161570603-b7535655-1beb-4aa0-b7a7-4c7d56d17b94.png)\r\n\r\n**Environment (please complete the following information):**\r\n - OS: Kaggle\r\n - Python Version: Kaggle\r\n - Deepchecks Version: 0.6.0\r\n\r\n\n", "before_files": [{"content": "# ----------------------------------------------------------------------------\n# Copyright (C) 2021-2022 Deepchecks (https://www.deepchecks.com)\n#\n# This file is part of Deepchecks.\n# Deepchecks is distributed under the terms of the GNU Affero General\n# Public License (version 3 or later).\n# You should have received a copy of the GNU Affero General Public License\n# along with Deepchecks.  If not, see <http://www.gnu.org/licenses/>.\n# ----------------------------------------------------------------------------\n#\n\"\"\"Module contains Image Property Drift check.\"\"\"\nimport typing as t\nfrom collections import defaultdict\n\nimport pandas as pd\n\nfrom deepchecks.core import CheckResult\nfrom deepchecks.core import ConditionResult\nfrom deepchecks.core import DatasetKind\nfrom deepchecks.core.errors import NotEnoughSamplesError, DeepchecksValueError\nfrom deepchecks.core.condition import ConditionCategory\nfrom deepchecks.utils.distribution.drift import calc_drift_and_plot\nfrom deepchecks.vision import Batch\nfrom deepchecks.vision import Context\nfrom deepchecks.vision import TrainTestCheck\nfrom deepchecks.vision.utils.image_properties import validate_properties, default_image_properties, get_column_type\n\n\n__all__ = ['ImagePropertyDrift']\n\n\nTImagePropertyDrift = t.TypeVar('TImagePropertyDrift', bound='ImagePropertyDrift')\n\n\nclass ImagePropertyDrift(TrainTestCheck):\n    \"\"\"\n    Calculate drift between train dataset and test dataset per image property, using statistical measures.\n\n    Check calculates a drift score for each image property in test dataset, by comparing its distribution to the train\n    dataset. For this, we use the Earth Movers Distance.\n\n    See https://en.wikipedia.org/wiki/Wasserstein_metric\n\n    Parameters\n    ----------\n    image_properties : List[Dict[str, Any]], default: None\n        List of properties. Replaces the default deepchecks properties.\n        Each property is dictionary with keys 'name' (str), 'method' (Callable) and 'output_type' (str),\n        representing attributes of said method. 'output_type' must be one of 'continuous'/'discrete'\n    max_num_categories: int, default: 10\n    classes_to_display : Optional[List[float]], default: None\n        List of classes to display. The distribution of the properties would include only samples belonging (or\n        containing an annotation belonging) to one of these classes. If None, samples from all classes are displayed.\n    min_samples: int, default: 10\n        Minimum number of samples needed in each dataset needed to calculate the drift.\n    \"\"\"\n\n    def __init__(\n        self,\n        image_properties: t.List[t.Dict[str, t.Any]] = None,\n        max_num_categories: int = 10,\n        classes_to_display: t.Optional[t.List[str]] = None,\n        min_samples: int = 30,\n        **kwargs\n    ):\n        super().__init__(**kwargs)\n        if image_properties is not None:\n            validate_properties(image_properties)\n            self.image_properties = image_properties\n        else:\n            self.image_properties = default_image_properties\n\n        self.max_num_categories = max_num_categories\n        self.classes_to_display = classes_to_display\n        self.min_samples = min_samples\n        self._train_properties = None\n        self._test_properties = None\n        self._class_to_string = None\n\n    def initialize_run(self, context: Context):\n        \"\"\"Initialize self state, and validate the run context.\"\"\"\n        self._class_to_string = context.train.label_id_to_name\n        self._train_properties = defaultdict(list)\n        self._test_properties = defaultdict(list)\n\n    def update(\n        self,\n        context: Context,\n        batch: Batch,\n        dataset_kind: DatasetKind\n    ):\n        \"\"\"Calculate image properties for train or test batch.\"\"\"\n        if dataset_kind == DatasetKind.TRAIN:\n            properties = self._train_properties\n        elif dataset_kind == DatasetKind.TEST:\n            properties = self._test_properties\n        else:\n            raise RuntimeError(\n                f'Internal Error - Should not reach here! unknown dataset_kind: {dataset_kind}'\n            )\n\n        images = batch.images\n\n        if self.classes_to_display:\n            # use only images belonging (or containing an annotation belonging) to one of the classes in\n            # classes_to_display\n            classes = context.train.get_classes(batch.labels)\n            images = [\n                image for idx, image in enumerate(images) if\n                any(cls in map(self._class_to_string, classes[idx]) for cls in self.classes_to_display)\n            ]\n\n        for single_property in self.image_properties:\n            property_list = single_property['method'](images)\n            properties[single_property['name']].extend(property_list)\n\n    def compute(self, context: Context) -> CheckResult:\n        \"\"\"Calculate drift score between train and test datasets for the collected image properties.\n\n        Returns\n        -------\n        CheckResult\n            value: dictionary containing drift score for each image property.\n            display: distribution graph for each image property.\n        \"\"\"\n        if sorted(self._train_properties.keys()) != sorted(self._test_properties.keys()):\n            raise RuntimeError('Internal Error! Vision check was used improperly.')\n\n        # if self.classes_to_display is set, check that it has classes that actually exist\n        if self.classes_to_display is not None:\n            if not set(self.classes_to_display).issubset(\n                    map(self._class_to_string, context.train.classes_indices.keys())\n            ):\n                raise DeepchecksValueError(\n                    f'Provided list of class ids to display {self.classes_to_display} not found in training dataset.'\n                )\n\n        properties = sorted(self._train_properties.keys())\n        df_train = pd.DataFrame(self._train_properties)\n        df_test = pd.DataFrame(self._test_properties)\n        if len(df_train) < self.min_samples or len(df_test) < self.min_samples:\n            return CheckResult(\n                value=None,\n                display=f'Not enough samples to calculate drift score, min {self.min_samples} samples required.',\n                header='Image Property Drift'\n            )\n\n        figures = {}\n        drifts = {}\n\n        for single_property in self.image_properties:\n            property_name = single_property['name']\n\n            try:\n                score, _, figure = calc_drift_and_plot(\n                    train_column=df_train[property_name],\n                    test_column=df_test[property_name],\n                    value_name=property_name,\n                    column_type=get_column_type(single_property['output_type']),\n                    max_num_categories=self.max_num_categories,\n                    min_samples=self.min_samples\n                )\n\n                figures[property_name] = figure\n                drifts[property_name] = score\n            except NotEnoughSamplesError:\n                figures[property_name] = '<p>Not enough non-null samples to calculate drift</p>'\n                drifts[property_name] = 0\n\n        if drifts:\n            columns_order = sorted(properties, key=lambda col: drifts[col], reverse=True)\n\n            headnote = '<span>' \\\n                       'The Drift score is a measure for the difference between two distributions. ' \\\n                       'In this check, drift is measured ' \\\n                       f'for the distribution of the following image properties: {properties}.' \\\n                       '</span>'\n\n            displays = [headnote] + [figures[col] for col in columns_order]\n        else:\n            drifts = None\n            displays = []\n\n        return CheckResult(\n            value=drifts,\n            display=displays,\n            header='Image Property Drift'\n        )\n\n    def add_condition_drift_score_not_greater_than(\n        self: TImagePropertyDrift,\n        max_allowed_drift_score: float = 0.1\n    ) -> TImagePropertyDrift:\n        \"\"\"\n        Add condition - require drift score to not be more than a certain threshold.\n\n        Parameters\n        ----------\n        max_allowed_drift_score: float ,  default: 0.1\n            the max threshold for the Earth Mover's Distance score\n\n        Returns\n        -------\n        ConditionResult\n            False if any column has passed the max threshold, True otherwise\n        \"\"\"\n\n        def condition(result: t.Dict[str, float]) -> ConditionResult:\n            failed_properties = [\n                (property_name, drift_score)\n                for property_name, drift_score in result.items()\n                if drift_score > max_allowed_drift_score\n            ]\n            if len(failed_properties) > 0:\n                failed_properties = ';\\n'.join(f'{p}={d:.2f}' for p, d in failed_properties)\n                return ConditionResult(\n                    False,\n                    'Earth Mover\\'s Distance is above the threshold '\n                    f'for the next properties:\\n{failed_properties}'\n                )\n            return ConditionResult(ConditionCategory.PASS)\n\n        return self.add_condition(\n            f'Earth Mover\\'s Distance <= {max_allowed_drift_score} for image properties drift',\n            condition\n        )\n", "path": "deepchecks/vision/checks/distribution/image_property_drift.py"}], "after_files": [{"content": "# ----------------------------------------------------------------------------\n# Copyright (C) 2021-2022 Deepchecks (https://www.deepchecks.com)\n#\n# This file is part of Deepchecks.\n# Deepchecks is distributed under the terms of the GNU Affero General\n# Public License (version 3 or later).\n# You should have received a copy of the GNU Affero General Public License\n# along with Deepchecks.  If not, see <http://www.gnu.org/licenses/>.\n# ----------------------------------------------------------------------------\n#\n\"\"\"Module contains Image Property Drift check.\"\"\"\nimport typing as t\nfrom collections import defaultdict\n\nimport pandas as pd\n\nfrom deepchecks.core import CheckResult\nfrom deepchecks.core import ConditionResult\nfrom deepchecks.core import DatasetKind\nfrom deepchecks.core.errors import NotEnoughSamplesError, DeepchecksValueError\nfrom deepchecks.core.condition import ConditionCategory\nfrom deepchecks.utils.distribution.drift import calc_drift_and_plot\nfrom deepchecks.vision import Batch\nfrom deepchecks.vision import Context\nfrom deepchecks.vision import TrainTestCheck\nfrom deepchecks.vision.utils.image_properties import validate_properties, default_image_properties, get_column_type\n\n\n__all__ = ['ImagePropertyDrift']\n\n\nTImagePropertyDrift = t.TypeVar('TImagePropertyDrift', bound='ImagePropertyDrift')\n\n\nclass ImagePropertyDrift(TrainTestCheck):\n    \"\"\"\n    Calculate drift between train dataset and test dataset per image property, using statistical measures.\n\n    Check calculates a drift score for each image property in test dataset, by comparing its distribution to the train\n    dataset. For this, we use the Earth Movers Distance.\n\n    See https://en.wikipedia.org/wiki/Wasserstein_metric\n\n    Parameters\n    ----------\n    image_properties : List[Dict[str, Any]], default: None\n        List of properties. Replaces the default deepchecks properties.\n        Each property is dictionary with keys 'name' (str), 'method' (Callable) and 'output_type' (str),\n        representing attributes of said method. 'output_type' must be one of 'continuous'/'discrete'\n    max_num_categories: int, default: 10\n    classes_to_display : Optional[List[float]], default: None\n        List of classes to display. The distribution of the properties would include only samples belonging (or\n        containing an annotation belonging) to one of these classes. If None, samples from all classes are displayed.\n    min_samples: int, default: 10\n        Minimum number of samples needed in each dataset needed to calculate the drift.\n    \"\"\"\n\n    def __init__(\n        self,\n        image_properties: t.List[t.Dict[str, t.Any]] = None,\n        max_num_categories: int = 10,\n        classes_to_display: t.Optional[t.List[str]] = None,\n        min_samples: int = 30,\n        **kwargs\n    ):\n        super().__init__(**kwargs)\n        if image_properties is not None:\n            validate_properties(image_properties)\n            self.image_properties = image_properties\n        else:\n            self.image_properties = default_image_properties\n\n        self.max_num_categories = max_num_categories\n        self.classes_to_display = classes_to_display\n        self.min_samples = min_samples\n        self._train_properties = None\n        self._test_properties = None\n        self._class_to_string = None\n\n    def initialize_run(self, context: Context):\n        \"\"\"Initialize self state, and validate the run context.\"\"\"\n        self._class_to_string = context.train.label_id_to_name\n        self._train_properties = defaultdict(list)\n        self._test_properties = defaultdict(list)\n\n    def update(\n        self,\n        context: Context,\n        batch: Batch,\n        dataset_kind: DatasetKind\n    ):\n        \"\"\"Calculate image properties for train or test batch.\"\"\"\n        if dataset_kind == DatasetKind.TRAIN:\n            properties = self._train_properties\n        elif dataset_kind == DatasetKind.TEST:\n            properties = self._test_properties\n        else:\n            raise RuntimeError(\n                f'Internal Error - Should not reach here! unknown dataset_kind: {dataset_kind}'\n            )\n\n        images = batch.images\n\n        if self.classes_to_display:\n            # use only images belonging (or containing an annotation belonging) to one of the classes in\n            # classes_to_display\n            classes = context.train.get_classes(batch.labels)\n            images = [\n                image for idx, image in enumerate(images) if\n                any(cls in map(self._class_to_string, classes[idx]) for cls in self.classes_to_display)\n            ]\n\n        for single_property in self.image_properties:\n            property_list = single_property['method'](images)\n            properties[single_property['name']].extend(property_list)\n\n    def compute(self, context: Context) -> CheckResult:\n        \"\"\"Calculate drift score between train and test datasets for the collected image properties.\n\n        Returns\n        -------\n        CheckResult\n            value: dictionary containing drift score for each image property.\n            display: distribution graph for each image property.\n        \"\"\"\n        if sorted(self._train_properties.keys()) != sorted(self._test_properties.keys()):\n            raise RuntimeError('Internal Error! Vision check was used improperly.')\n\n        # if self.classes_to_display is set, check that it has classes that actually exist\n        if self.classes_to_display is not None:\n            if not set(self.classes_to_display).issubset(\n                    map(self._class_to_string, context.train.classes_indices.keys())\n            ):\n                raise DeepchecksValueError(\n                    f'Provided list of class ids to display {self.classes_to_display} not found in training dataset.'\n                )\n\n        properties = sorted(self._train_properties.keys())\n        df_train = pd.DataFrame(self._train_properties)\n        df_test = pd.DataFrame(self._test_properties)\n        if len(df_train) < self.min_samples or len(df_test) < self.min_samples:\n            raise NotEnoughSamplesError(\n                f'Not enough samples to calculate drift score, minimum {self.min_samples} samples required'\n                f', but got {len(df_train)} and {len(df_test)} samples in the train and test datasets.'\n                'Use \\'min_samples\\' parameter to change the requirement.'\n            )\n\n        figures = {}\n        drifts = {}\n\n        for single_property in self.image_properties:\n            property_name = single_property['name']\n\n            try:\n                score, _, figure = calc_drift_and_plot(\n                    train_column=df_train[property_name],\n                    test_column=df_test[property_name],\n                    value_name=property_name,\n                    column_type=get_column_type(single_property['output_type']),\n                    max_num_categories=self.max_num_categories,\n                    min_samples=self.min_samples\n                )\n\n                figures[property_name] = figure\n                drifts[property_name] = score\n            except NotEnoughSamplesError:\n                figures[property_name] = '<p>Not enough non-null samples to calculate drift</p>'\n                drifts[property_name] = 0\n\n        if drifts:\n            columns_order = sorted(properties, key=lambda col: drifts[col], reverse=True)\n\n            headnote = '<span>' \\\n                       'The Drift score is a measure for the difference between two distributions. ' \\\n                       'In this check, drift is measured ' \\\n                       f'for the distribution of the following image properties: {properties}.' \\\n                       '</span>'\n\n            displays = [headnote] + [figures[col] for col in columns_order]\n        else:\n            drifts = None\n            displays = []\n\n        return CheckResult(\n            value=drifts,\n            display=displays,\n            header='Image Property Drift'\n        )\n\n    def add_condition_drift_score_not_greater_than(\n        self: TImagePropertyDrift,\n        max_allowed_drift_score: float = 0.1\n    ) -> TImagePropertyDrift:\n        \"\"\"\n        Add condition - require drift score to not be more than a certain threshold.\n\n        Parameters\n        ----------\n        max_allowed_drift_score: float ,  default: 0.1\n            the max threshold for the Earth Mover's Distance score\n\n        Returns\n        -------\n        ConditionResult\n            False if any column has passed the max threshold, True otherwise\n        \"\"\"\n\n        def condition(result: t.Dict[str, float]) -> ConditionResult:\n            failed_properties = [\n                (property_name, drift_score)\n                for property_name, drift_score in result.items()\n                if drift_score > max_allowed_drift_score\n            ]\n            if len(failed_properties) > 0:\n                failed_properties = ';\\n'.join(f'{p}={d:.2f}' for p, d in failed_properties)\n                return ConditionResult(\n                    False,\n                    'Earth Mover\\'s Distance is above the threshold '\n                    f'for the next properties:\\n{failed_properties}'\n                )\n            return ConditionResult(ConditionCategory.PASS)\n\n        return self.add_condition(\n            f'Earth Mover\\'s Distance <= {max_allowed_drift_score} for image properties drift',\n            condition\n        )\n", "path": "deepchecks/vision/checks/distribution/image_property_drift.py"}]}