code: def show_anomalies_from_scores(
      series: TimeSeries,
      model_output: TimeSeries = None,
      anomaly_scores: Union[TimeSeries, Sequence[TimeSeries]] = None,
      window: Union[int, Sequence[int]] = 1,
      names_of_scorers: Union[str, Sequence[str]] = None,
      actual_anomalies: TimeSeries = None,
      title: str = None,
      metric: str = None,
  ):
      """Plot the results generated by an anomaly model.
  
      The plot will be composed of the following:
          - the series itself with the output of the model (if given)
          - the anomaly score of each scorer. The scorer with different windows will be separated.
          - the actual anomalies, if given.
  
      If model_output is stochastic (i.e., if it has multiple samples), the function will plot:
          - the mean per timestamp
          - the quantile 0.95 for an upper bound
          - the quantile 0.05 for a lower bound
  
      Possible to:
          - add a title to the figure with the parameter `title`
          - give personalized names for the scorers with `names_of_scorers`
          - show the results of a metric for each anomaly score (AUC_ROC or AUC_PR), if the actual anomalies is given
  
      Parameters
      ----------
      series
          The series to visualize anomalies from.
      model_output
          Output of the model given as input the series (can be stochastic).
      anomaly_scores
          Output of the scorers given the output of the model and the series.
      window
          Window parameter for each anomaly scores.
          Default: 1. If a list of anomaly scores is given, the same default window will be used for every score.
      names_of_scorers
          Name of the scores. Must be a list of length equal to the number of scorers in the anomaly_model.
      actual_anomalies
          The ground truth of the anomalies (1 if it is an anomaly and 0 if not)
      title
          Title of the figure
      metric
          Optionally, Scoring function to use. Must be one of "AUC_ROC" and "AUC_PR".
          Default: "AUC_ROC"
      """
  
      raise_if_not(
          isinstance(series, TimeSeries),
          f"Input `series` must be of type TimeSeries, found {type(series)}.",
      )
  
      if title is None:
          if anomaly_scores is not None:
              title = "Anomaly results"
      else:
          raise_if_not(
              isinstance(title, str),
              f"Input `title` must be of type str, found {type(title)}.",
          )
  
      nbr_plots = 1
  
      if model_output is not None:
          raise_if_not(
              isinstance(model_output, TimeSeries),
              f"Input `model_output` must be of type TimeSeries, found {type(model_output)}.",
          )
  
      if actual_anomalies is not None:
          raise_if_not(
              isinstance(actual_anomalies, TimeSeries),
              f"Input `actual_anomalies` must be of type TimeSeries, found {type(actual_anomalies)}.",
          )
  
          nbr_plots = nbr_plots + 1
      else:
          raise_if_not(
              metric is None,
              "`actual_anomalies` must be given in order to calculate a metric.",
          )
  
      if anomaly_scores is not None:
          if isinstance(anomaly_scores, Sequence):
              for idx, s in enumerate(anomaly_scores):
                  raise_if_not(
                      isinstance(s, TimeSeries),
                      f"Elements of anomaly_scores must be of type TimeSeries, found {type(s)} at index {idx}.",
                  )
          else:
              raise_if_not(
                  isinstance(anomaly_scores, TimeSeries),
                  f"Input `anomaly_scores` must be of type TimeSeries or Sequence, found {type(actual_anomalies)}.",
              )
              anomaly_scores = [anomaly_scores]
  
          if names_of_scorers is not None:
              if isinstance(names_of_scorers, str):
                  names_of_scorers = [names_of_scorers]
              elif isinstance(names_of_scorers, Sequence):
                  for idx, name in enumerate(names_of_scorers):
                      raise_if_not(
                          isinstance(name, str),
                          f"Elements of names_of_scorers must be of type str, found {type(name)} at index {idx}.",
                      )
              else:
                  raise ValueError(
                      f"Input `names_of_scorers` must be of type str or Sequence, found {type(names_of_scorers)}."
                  )
  
              raise_if_not(
                  len(names_of_scorers) == len(anomaly_scores),
                  "The number of names in `names_of_scorers` must match the number of anomaly score "
                  + f"given as input, found {len(names_of_scorers)} and expected {len(anomaly_scores)}.",
              )
  
          if isinstance(window, int):
              window = [window]
          elif isinstance(window, Sequence):
              for idx, w in enumerate(window):
                  raise_if_not(
                      isinstance(w, int),
                      f"Every window must be of type int, found {type(w)} at index {idx}.",
                  )
          else:
              raise ValueError(
                  f"Input `window` must be of type int or Sequence, found {type(window)}."
              )
  
          raise_if_not(
              all([w > 0 for w in window]),
              "All windows must be positive integer.",
          )
  
          if len(window) == 1:
              window = window * len(anomaly_scores)
          else:
              raise_if_not(
                  len(window) == len(anomaly_scores),
                  "The number of window in `window` must match the number of anomaly score given as input. One "
                  + f"window value for each series. Found length {len(window)}, and expected {len(anomaly_scores)}.",
              )
  
          raise_if_not(
              all(
                  [w < len(s) for (w, s) in zip(window, anomaly_scores)]
              ),
              "All windows must be smaller than the length of their corresponding score.",
          )
  
          nbr_plots = nbr_plots + len(set(window))
      else:
          if window is not None:
              logger.warning(
                  "The parameter `window` is given, but the input `anomaly_scores` is None."
              )
  
          if names_of_scorers is not None:
              logger.warning(
                  "The parameter `names_of_scorers` is given, but the input `anomaly_scores` is None."
              )
  
          if metric is not None:
              logger.warning(
                  "The parameter `metric` is given, but the input `anomaly_scores` is None."
              )
  
      fig, axs = plt.subplots(
          nbr_plots,
          figsize=(8, 4 + 2 * (nbr_plots - 1)),
          sharex=True,
          gridspec_kw={"height_ratios": [2] + [1] * (nbr_plots - 1)},
          squeeze=False,
      )
  
      index_ax = 0
  
      _plot_series(
          series=series,
          ax_id=axs[index_ax][0],
          linewidth=0.5,
          label_name="",
      )
  
      if model_output is not None:
          _plot_series(
              series=model_output,
              ax_id=axs[index_ax][0],
              linewidth=0.5,
              label_name="model output",
          )
  
      axs[index_ax][0].set_title("")
  
      if actual_anomalies is not None or anomaly_scores is not None:
          axs[index_ax][0].set_xlabel("")
  
      axs[index_ax][0].legend(
          loc="upper center", bbox_to_anchor=(0.5, 1.1), ncol=2
      )
  
      if anomaly_scores is not None:
          dict_input = {}
  
          for idx, (score, w) in enumerate(zip(anomaly_scores, window)):
              dict_input[idx] = {
                  "series_score": score,
                  "window": w,
                  "name_id": idx,
              }
  
          current_window = window[0]
          index_ax = index_ax + 1
  
          for elem in sorted(
              dict_input.items(), key=lambda x: x[1]["window"]
          ):
              idx = elem[1]["name_id"]
              w = elem[1]["window"]
  
              if w != current_window:
                  current_window = w
                  index_ax = index_ax + 1
  
              if metric is not None:
                  value = round(
                      eval_accuracy_from_scores(
                          anomaly_score=anomaly_scores[idx],
                          actual_anomalies=actual_anomalies,
                          window=w,
                          metric=metric,
                      ),
                      3,
                  )
              else:
                  value = None
  
              if names_of_scorers is not None:
                  label = (
                      names_of_scorers[idx]
                      + [f" ({value})", ""][value is None]
                  )
              else:
                  label = (
                      f"score_{str(idx)}"
                      + [f" ({value})", ""][value is None]
                  )
  
              _plot_series(
                  series=elem[1]["series_score"],
                  ax_id=axs[index_ax][0],
                  linewidth=0.5,
                  label_name=label,
              )
  
              axs[index_ax][0].legend(
                  loc="upper center", bbox_to_anchor=(0.5, 1.19), ncol=2
              )
              axs[index_ax][0].set_title(
                  f"Window: {str(w)}", loc="left"
              )
              axs[index_ax][0].set_title("")
              axs[index_ax][0].set_xlabel("")
  
      if actual_anomalies is not None:
          _plot_series(
              series=actual_anomalies,
              ax_id=axs[index_ax + 1][0],
              linewidth=1,
              label_name="anomalies",
              color="red",
          )
  
          axs[index_ax + 1][0].set_title("")
          axs[index_ax + 1][0].set_ylim([-0.1, 1.1])
          axs[index_ax + 1][0].set_yticks([0, 1])
          axs[index_ax + 1][0].set_yticklabels(["no", "yes"])
          axs[index_ax + 1][0].legend(
              loc="upper center", bbox_to_anchor=(0.5, 1.2), ncol=2
          )
      else:
          axs[index_ax][0].set_xlabel("timestamp")
  
      fig.suptitle(title)
  
file_path: darts/darts/ad/utils.py
imports: from typing import Sequence, Tuple, Union
  import matplotlib.pyplot
  import numpy
  from sklearn.metrics import accuracy_score, average_precision_score, f1_score, precision_score, recall_score, roc_auc_score
  from darts import TimeSeries
  from darts.logging import get_logger, raise_if, raise_if_not
label_desc: Use image node_id 11 for calling a global function with example usage: show_anomalies_from_scores(series, model_output, anomaly_scores, window, names_of_scorers, actual_anomalies, title, metric) without return types