code: def text_data_describe_plot(
      n_samples: int,
      max_num_labels_to_show: int,
      is_multi_label: bool,
      task_type: str,
      properties: pd.DataFrame,
      categorical_metadata: Optional[List[str]] = None,
      numerical_metadata: Optional[List[str]] = None,
      categorical_properties: Optional[List[str]] = None,
      numerical_properties: Optional[List[str]] = None,
      model_classes: Optional[List[str]] = None,
      label: Optional[TTextLabel] = None,
  ):
      """Return a plotly figure instance.
  
      Parameters
      ----------
      properties: pd.DataFrame
          The DataFrame consisting of the text properties data. If no prooperties are there, you can pass an
          empty DataFrame as well.
      n_samples: int
          The total number of samples present in the TextData object.
      max_num_labels_to_show : int
          The threshold to display the maximum number of labels on the label distribution pie chart and display
          rest of the labels under "Others" category.
      is_multi_label: bool
          A boolean where True denotes that the TextData contains multi labeled data otherwise false.
      task_type: str
          The task type for the text data. Can be either 'text_classification' or 'token_classification'.
      categorical_metadata: Optional[List[str]], default: None
          The names of the categorical metadata columns.
      numerical_metadata: Optional[List[str]], default: None
          The names of the numerical metadata columns.
      categorical_properties: Optional[List[str]], default: None
          The names of the categorical properties columns.
      numerical_properties: Optional[List[str]], default: None
          The names of the numerical text properties columns.
      label: Optional[TTextLabel], default: None
          The label for the text data. Can be either a text_classification label or a token_classification label.
          If None, the label distribution graph is not generated.
  
          - text_classification label - For text classification the accepted label format differs between multilabel and
            single label cases. For single label data, the label should be passed as a sequence of labels, with one entry
            per sample that can be either a string or an integer. For multilabel data, the label should be passed as a
            sequence of sequences, with the sequence for each sample being a binary vector, representing the presence of
            the i-th label in that sample.
          - token_classification label - For token classification the accepted label format is the IOB format or similar
            to it. The Label must be a sequence of sequences of strings or integers, with each sequence corresponding to
            a sample in the tokenized text, and exactly the length of the corresponding tokenized text.
      model_classes: Optional[List[str]], default: None
          List of classes names to use for multi-label display. Only used if the dataset is multi-label.
  
      Returns
      -------
      Plotly Figure instance.
      """
      specs = [
          [{"type": "pie"}, {"type": "table"}]
          if label is not None
          else [{"type": "table", "colspan": 2}, None]
      ] + [
          [{"type": "xy", "colspan": 2}, None]
          for _ in range(len(properties.columns))
      ]
  
      subplot_titles = []
      if label is not None:
          annotated_samples = _calculate_number_of_annotated_samples(
              label, is_multi_label, task_type
          )
          subplot_titles.append(
              f"Label Distribution<br><sup>Out of {annotated_samples} annotated samples</sup><br><br>"
          )
  
      subplot_titles.append("")  # Empty title for table figure
      if not properties.empty:
          for prop_name in properties:
              if prop_name in TEXT_PROPERTIES_DESCRIPTION:
                  subplot_titles.append(
                      f'{prop_name} Property Distribution<sup><a href="{get_docs_link()}nlp/'
                      'usage_guides/nlp_properties.html#deepchecks-built-in-properties">&#x24D8;</a>'
                      f"</sup><br><sup>{TEXT_PROPERTIES_DESCRIPTION[prop_name]}</sup>"
                  )
  
      fig = make_subplots(
          rows=len(properties.columns) + 1,
          cols=2,
          specs=specs,
          subplot_titles=subplot_titles,
          row_heights=[1.5] + [1.0] * len(properties.columns),
      )
  
      # Create label distribution if label is provided
      if label is not None:
          if is_multi_label:
              df_label = pd.DataFrame(label).fillna(0)
              if model_classes is not None:
                  hashmap = {}
                  for val in label:
                      model_array = np.array(
                          [
                              model_classes[i]
                              for i, val in enumerate(val)
                              if val == 1
                          ]
                      )
                      for class_name in model_array:
                          hashmap[class_name] = (
                              hashmap[class_name] + 1
                              if class_name in hashmap
                              else 1
                          )
                  label_counts = pd.Series(
                      list(hashmap.values()), index=list(hashmap)
                  )
              else:
                  label_counts = pd.Series(
                      np.sum(df_label.to_numpy(), axis=0)
                  )
          elif task_type == TaskType.TOKEN_CLASSIFICATION:
              hashmap = {}
              for val in label:
                  flattened_array = (
                      pd.Series(np.array(val).flatten())
                      .fillna("NaN")
                      .to_numpy()
                  )
                  unique_values, counts = np.unique(
                      flattened_array, return_counts=True
                  )
                  for label_value, count in zip(unique_values, counts):
                      if label_value != "NaN":
                          hashmap[label_value] = (
                              hashmap[label_value] + count
                              if label_value in hashmap
                              else count
                          )
              label_counts = pd.Series(
                  list(hashmap.values()), index=list(hashmap)
              )
          else:
              label_counts = pd.Series(label).value_counts()
  
          label_counts.sort_values(ascending=False, inplace=True)
          labels_to_display = label_counts[:max_num_labels_to_show]
          labels_to_display.index = [
              break_to_lines_and_trim(str(label))
              for label in list(labels_to_display.index)
          ]
          count_other_labels = label_counts[
              max_num_labels_to_show + 1 :
          ].sum()
          labels_to_display["Others"] = count_other_labels
  
          # Pie chart for label distribution
          fig.add_trace(
              go.Pie(
                  labels=list(labels_to_display.index),
                  values=list(labels_to_display),
                  textposition="inside",
                  showlegend=False,
                  textinfo="label+percent",
                  hovertemplate="%{label}: %{value} samples<extra></extra>",
              ),
              row=1,
              col=1,
          )
  
      # Table figure for displaying some statistics
      annotation_ratio = _calculate_annoation_ratio(
          label, n_samples, is_multi_label, task_type
      )
      table_trace = _generate_table_trace(
          n_samples,
          annotation_ratio,
          categorical_metadata,
          numerical_metadata,
          categorical_properties,
          numerical_properties,
      )
      fig.add_trace(
          table_trace, row=1, col=2 if label is not None else 1
      )
  
      # Looping over all the properties to generate respective property distribution graphs
      curr_row = 2  # Since row 1 is occupied with Pie and Table
      for property_name in properties.columns:
          if property_name in categorical_properties:
              # Creating bar plots for categorical properties
              (
                  trace,
                  xaxis_layout,
                  yaxis_layout,
              ) = _generate_categorical_distribution_plot(
                  properties[property_name], property_name
              )
              fig.add_trace(trace, row=curr_row, col=1)
              fig.update_xaxes(xaxis_layout, row=curr_row, col=1)
              fig.update_yaxes(yaxis_layout, row=curr_row, col=1)
          else:
              # Creating scatter plots for numerical properties
              y_value, xs = _get_distribution_values(
                  properties[property_name]
              )
              (
                  trace,
                  shapes,
                  annotations,
                  xaxis_layout,
                  yaxis_layout,
              ) = _generate_numeric_distribution_plot(
                  properties[property_name], xs, y_value, property_name
              )
              fig.add_trace(trace, row=curr_row, col=1)
  
              for shape, annotation in zip(shapes, annotations):
                  fig.add_shape(shape, row=curr_row, col=1)
                  fig.add_annotation(annotation, row=curr_row, col=1)
  
              fig.update_yaxes(yaxis_layout, row=curr_row, col=1)
              fig.update_xaxes(xaxis_layout, row=curr_row, col=1)
  
          curr_row += 1
  
      fig.update_layout(height=450 * (len(properties.columns) + 1))
      return fig
  
file_path: deepchecks/deepchecks/nlp/utils/text_data_plot.py
imports: from typing import List, Optional
  import numpy
  import pandas
  import plotly.graph_objs
  from plotly.subplots import make_subplots
  from deepchecks.nlp.task_type import TaskType, TTextLabel
  from deepchecks.nlp.utils.text import break_to_lines_and_trim
  from deepchecks.nlp.utils.text_properties import TEXT_PROPERTIES_DESCRIPTION
  from deepchecks.utils.dataframes import un_numpy
  from deepchecks.utils.distribution.plot import get_density
  from deepchecks.utils.plot import feature_distribution_colors
  from deepchecks.utils.strings import format_percent, get_docs_link
label_desc: Use image node_id 8 for calling a global function with example usage: text_data_describe_plot(n_samples, max_num_labels_to_show, is_multi_label, task_type, properties, categorical_metadata, numerical_metadata, categorical_properties, numerical_properties, model_classes, label) and returns: fig