Repository: evidentlyai/evidently
Issue: DQ Dashboard: Plotly ValueError thrown when `len(columns) > 15:`
Root cause: Validation Gap

I'm running a DQ Dashboard as follows:

```
dq_dashboard = Dashboard(tabs=[DataQualityTab()])
dq_dashboard.calculate(ref_data_sample, prod_data_sample, column_mapping=column_mapping)
```
When the number of columns in my dataframe is greater than 15 I get the following Plotly error:

```
[ValueError: 
    Invalid value of type 'builtins.str' received for the 'text' property of heatmap
        Received value: ''

    The 'text' property is an array that may be specified as a tuple,
    list, numpy array, or pandas Series]()
``` 

Plotly expects an array for `text` here but a str is passed. 

I suspect it's due to this line in  data_quality_correlations.py:

https://github.com/evidentlyai/evidently/blob/ed2558c1becfce6bed0379211ea15aaa3aaa666a/src/evidently/dashboard/widgets/data_quality_correlations.py#L121

versions: 
`evidently = "0.1.47.dev1"`
`plotly =  "5.6.0"`

stack trace:

```
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/home/.../09-dq-checks.ipynb Cell 15' in <cell line: 2>()
      1 dq_dashboard = Dashboard(tabs=[DataQualityTab()])
----> 2 dq_dashboard.calculate(ref_data_sample, prod_data_sample, column_mapping=column_mapping)
      3 dq_dashboard.save("dq_dashboard_trip_score.html")

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/evidently/dashboard/dashboard.py:152, in Dashboard.calculate(self, reference_data, current_data, column_mapping)
    147 def calculate(self,
    148               reference_data: pandas.DataFrame,
    149               current_data: Optional[pandas.DataFrame] = None,
    150               column_mapping: Optional[ColumnMapping] = None):
    151     column_mapping = column_mapping or ColumnMapping()
--> 152     self.execute(reference_data, current_data, column_mapping)

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/evidently/pipeline/pipeline.py:49, in Pipeline.execute(self, reference_data, current_data, column_mapping)
     47 for stage in self.stages:
     48     stage.options_provider = self.options_provider
---> 49     stage.calculate(
     50         rdata.copy(), None if cdata is None else cdata.copy(), column_mapping, self.analyzers_results
     51     )

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/evidently/dashboard/tabs/base_tab.py:63, in Tab.calculate(self, reference_data, current_data, column_mapping, analyzers_results)
     61 for widget in self._widgets:
     62     widget.options_provider = self.options_provider
---> 63     self._widget_results.append(widget.calculate(reference_data,
     64                                                  current_data,
     65                                                  column_mapping,
     66                                                  analyzers_results))

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/evidently/dashboard/widgets/data_quality_correlations.py:43, in DataQualityCorrelationsWidget.calculate(self, reference_data, current_data, column_mapping, analyzers_results)
     41 for kind in ['pearson', 'spearman', 'kendall', 'cramer_v']:
     42     if reference_correlations[kind].shape[0] > 1:
---> 43         correlation_figure = self._plot_correlation_figure(kind, reference_correlations, current_correlations)
     44         additional_graphs.append(
     45             AdditionalGraphInfo(
     46                 kind,
   (...)
     51             )
     52         )
     54         parts.append(
     55             {
     56                 "title": kind,
     57                 "id": kind
     58             }
     59         )

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/evidently/dashboard/widgets/data_quality_correlations.py:108, in DataQualityCorrelationsWidget._plot_correlation_figure(self, kind, reference_correlations, current_correlations)
    106     text = ""
    107     texttemplate = ""
--> 108 trace = go.Heatmap(
    109     z=reference_correlations[kind],
    110     x=columns,
    111     y=columns,
    112     text=text,
    113     texttemplate=texttemplate,
    114     coloraxis="coloraxis")
    115 fig.append_trace(trace, 1, 1)
    116 if current_correlations is not None:

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/plotly/graph_objs/_heatmap.py:2949, in Heatmap.__init__(self, arg, autocolorscale, coloraxis, colorbar, colorscale, connectgaps, customdata, customdatasrc, dx, dy, hoverinfo, hoverinfosrc, hoverlabel, hoverongaps, hovertemplate, hovertemplatesrc, hovertext, hovertextsrc, ids, idssrc, legendgroup, legendgrouptitle, legendrank, meta, metasrc, name, opacity, reversescale, showlegend, showscale, stream, text, textfont, textsrc, texttemplate, transpose, uid, uirevision, visible, x, x0, xaxis, xcalendar, xgap, xhoverformat, xperiod, xperiod0, xperiodalignment, xsrc, xtype, y, y0, yaxis, ycalendar, ygap, yhoverformat, yperiod, yperiod0, yperiodalignment, ysrc, ytype, z, zauto, zhoverformat, zmax, zmid, zmin, zsmooth, zsrc, **kwargs)
   2947 _v = text if text is not None else _v
   2948 if _v is not None:
-> 2949     self["text"] = _v
   2950 _v = arg.pop("textfont", None)
   2951 _v = textfont if textfont is not None else _v

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/plotly/basedatatypes.py:4827, in BasePlotlyType.__setitem__(self, prop, value)
   4823         self._set_array_prop(prop, value)
   4825     # ### Handle simple property ###
   4826     else:
-> 4827         self._set_prop(prop, value)
   4828 else:
   4829     # Make sure properties dict is initialized
   4830     self._init_props()

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/plotly/basedatatypes.py:5171, in BasePlotlyType._set_prop(self, prop, val)
   5169         return
   5170     else:
-> 5171         raise err
   5173 # val is None
   5174 # -----------
   5175 if val is None:
   5176     # Check if we should send null update

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/plotly/basedatatypes.py:5166, in BasePlotlyType._set_prop(self, prop, val)
   5163 validator = self._get_validator(prop)
   5165 try:
-> 5166     val = validator.validate_coerce(val)
   5167 except ValueError as err:
   5168     if self._skip_invalid:

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/_plotly_utils/basevalidators.py:405, in DataArrayValidator.validate_coerce(self, v)
    403     v = to_scalar_or_list(v)
    404 else:
--> 405     self.raise_invalid_val(v)
    406 return v

File ~/.cache/pypoetry/virtualenvs/ds-model-monitoring-GQktnPqD-py3.9/lib/python3.9/site-packages/_plotly_utils/basevalidators.py:289, in BaseValidator.raise_invalid_val(self, v, inds)
    286             for i in inds:
    287                 name += "[" + str(i) + "]"
--> 289         raise ValueError(
    290             """
    291     Invalid value of type {typ} received for the '{name}' property of {pname}
    292         Received value: {v}
    293 
    294 {valid_clr_desc}""".format(
    295                 name=name,
    296                 pname=self.parent_name,
    297                 typ=type_str(v),
    298                 v=repr(v),
    299                 valid_clr_desc=self.description(),
    300             )
    301         )

ValueError: 
    Invalid value of type 'builtins.str' received for the 'text' property of heatmap
        Received value: ''

    The 'text' property is an array that may be specified as a tuple,
    list, numpy array, or pandas Series
```

Thanks

Interesting! I'm getting this too with 24 columns. 

As an update, as you mentioned, it works if there's at most 15 columns.

Hi @chrisjclarke, @benjamintanweihao!
Thanks for reporting, we have fixed this bug. The update will be published in the next release.

@0lgaF Thank you! Do you know when you'll be cutting a new release? For the impatient, I manage to get things showing up by modifying `evidently/dashboard/widgets/data_quality_correlations.py` and changing `text = ""` to `test = [""]`. :D 

@benjamintanweihao, we are planning for April 11th

By the way, if correlations are not your main goal, you can exclude this widget from Data Quality dashboard till April 11th =)
(https://docs.evidentlyai.com/user-guide/customization/select-widgets-to-display include_widgets parameter)