Repository: deepchecks/deepchecks

Issue:
[BUG] Calling `save_as_html` can raise an error if the label column is imbalanced and has the type `np.bool_`
**Describe the bug**
The error comes from this chart (section "Train Test Label Drift"):
![image](https://user-images.githubusercontent.com/17814966/152127072-57de57d7-1030-42e4-b03c-6a2d5e4305ae.png)

This bar chart is created whenever the label is imbalanced and drifts between train and test (which is the case with my data).

The x axis has the values `False` and `True` with the dtype `np.bool_`. Before saving as HTML, somewhere in the code, this diagram is encoded as JSON. The call to `json.dumps` causes the error. The solution is to convert the problematic data to the regular Python `bool` type.

**To Reproduce**
Steps to reproduce the behavior:
1. Run the code below
2. See error: "TypeError: Object of type bool_ is not JSON serializable"

```python
import pandas as pd
import numpy as np

from deepchecks import Dataset
from deepchecks.suites import train_test_validation


if __name__ == "__main__":
    # Generate some random data
    # Note that the data type of the generated label is numpy.bool_
    # (in my project, the label column has this type)
    np.random.seed(42)
    training_size = 1000
    training_positive_proportion = 0.01  # Very low proportion to simulate an imbalanced dataset
    testing_size = 100
    testing_positive_proportion = 0.05  # This proportion is different from training to simulate a drift on the label
    training_df = pd.DataFrame({
        "feature_1": np.ones(training_size),
        "label": np.random.choice(a=[False, True], size=(training_size,), p=[training_positive_proportion, 1 - training_positive_proportion])
    })
    testing_df = pd.DataFrame({
        "feature_1": np.ones(testing_size),
        "label": np.random.choice(a=[False, True], size=(testing_size,), p=[testing_positive_proportion, 1 - testing_positive_proportion])
    })

    # Run the train_test_validation suite
    training_ds = Dataset(df=training_df, label="label", features=["feature_1"])
    testing_ds = Dataset(df=testing_df, label="label", features=["feature_1"])
    suite = train_test_validation()
    results = suite.run(train_dataset=training_ds, test_dataset=testing_ds)

    # Save as HTML, this will raise the following error:
    # "TypeError: Object of type bool_ is not JSON serializable"
    results.save_as_html("output.html")
```

**Expected behavior**
I would expect deepchecks to deal with this internally by converting the legend values to `bool`.

**Environment (please complete the following information):**
 - OS: Ubuntu 20.04 (running on Windows 10 with WSL)
 - Python Version: 3.8.10
 - Deepchecks Version: 0.4.1


Discussion:

Resolving patch:
diff --git a/deepchecks/utils/dataframes.py b/deepchecks/utils/dataframes.py
--- a/deepchecks/utils/dataframes.py
+++ b/deepchecks/utils/dataframes.py
@@ -10,13 +10,37 @@
 #
 """Contain functions for handling dataframes in checks."""
 import typing as t
+
 import pandas as pd
+import numpy as np
+
 from deepchecks.utils.typing import Hashable
 from deepchecks.utils.validation import ensure_hashable_or_mutable_sequence
 from deepchecks.core.errors import DeepchecksValueError
 
 
-__all__ = ['validate_columns_exist', 'select_from_dataframe']
+__all__ = ['validate_columns_exist', 'select_from_dataframe', 'un_numpy']
+
+
+def un_numpy(val):
+    """Convert numpy value to native value.
+
+    Parameters
+    ----------
+    val :
+        The value to convert.
+
+    Returns
+    -------
+        returns the numpy value in a native type.
+    """
+    if isinstance(val, np.bool_):
+        return str(val)
+    if isinstance(val, (np.float64, np.float_)):
+        if np.isnan(val):
+            return None
+        return float(val)
+    return val
 
 
 def validate_columns_exist(
diff --git a/deepchecks/utils/distribution/plot.py b/deepchecks/utils/distribution/plot.py
--- a/deepchecks/utils/distribution/plot.py
+++ b/deepchecks/utils/distribution/plot.py
@@ -20,6 +20,7 @@
 
 from deepchecks.utils.distribution.preprocessing import preprocess_2_cat_cols_to_same_bins
 from deepchecks.utils.plot import colors
+from deepchecks.utils.dataframes import un_numpy
 
 
 def get_density(data, xs) -> np.ndarray:
@@ -140,6 +141,9 @@ def feature_distribution_traces(train_column,
         expected_percents, actual_percents, categories_list = \
             preprocess_2_cat_cols_to_same_bins(dist1=train_column, dist2=test_column,
                                                max_num_categories=max_num_categories)
+        # fixes plotly widget bug with numpy values by converting them to native values
+        # https://github.com/plotly/plotly.py/issues/3470
+        categories_list = [un_numpy(cat) for cat in categories_list]
         cat_df = pd.DataFrame({'Train dataset': expected_percents, 'Test dataset': actual_percents},
                               index=categories_list)
         train_bar = go.Bar(


Test patch: