code: def test_evaluation_plot(data):
      """Tests evaluation_plot"""
      forecasts = data["forecasts"]
      actuals = data["actuals"]
      num_timeseries = forecasts.shape[1]
      x = forecasts.index
  
      with pytest.raises(
          ValueError, match="There must be at least one trace to plot."
      ):
          evaluation_plot(x=x, traces=[])
  
      with pytest.raises(
          ValueError,
          match="``x`` length must match ``df`` length for all traces.",
      ):
          evaluation_plot(x=x[:10], traces=[TraceInfo(df=actuals)])
  
      with pytest.raises(
          ValueError,
          match="Column names must be identical in all traces.",
      ):
          f = forecasts.copy()
          f.columns = list("abcd")
          traces = [TraceInfo(df=f), TraceInfo(df=actuals)]
          evaluation_plot(x=x, traces=traces)
  
      traces = [
          TraceInfo(
              df=forecasts
          ),  # uses default (None) for other attributes
          TraceInfo(
              df=actuals, color="blue", name="actuals", legendgroup="a"
          ),
      ]
      # num_cols [1, num_timeseries] is is valid
      for num_cols in range(num_timeseries):
          evaluation_plot(x=x, traces=traces, num_cols=num_cols + 1)
  
      # num_cols outside this range is invalid
      with pytest.raises(ValueError) as record:
          evaluation_plot(x=x, traces=traces, num_cols=0)
          assert (
              f"`num_cols` should be between 1 and 4 (the number of columns), found 0."
              in record[0].message.args[0]
          )
  
      with pytest.raises(ValueError) as record:
          evaluation_plot(
              x=x, traces=traces, num_cols=num_timeseries + 1
          )
          assert (
              f"`num_cols` should be between 1 and 4 (the number of columns), found 5."
              in record[0].message.args[0]
          )
  
      # plot can be customized
      ylabel = "ylabel"
      title = "title_text"
      hline = True
      fig = evaluation_plot(
          x=x, traces=traces, ylabel=ylabel, title=title, hline=hline
      )
      assert len(fig.data) == num_timeseries * (
          hline + len(traces)
      )  # 4 plots, each with zero and two traces
      assert fig.data[0].name == "zero"  # horizontal line
      assert fig.data[1].name == "c1"  # name is the timeseries name
      assert fig.data[1].legendgroup is None
      assert fig.data[2].legendgroup == "a"
      assert fig.data[2].line.color == "blue"
      assert (
          fig.data[2].name == "c1-actuals"
      )  # "actuals" is appended ot the name
      assert fig.layout.title.text == title
      assert fig.layout.title.x == 0.5
      assert fig.layout.yaxis.title.text == ylabel
      assert fig.layout.yaxis4.title.text == ylabel
  
      hline = False
      fig = evaluation_plot(
          x=x, traces=traces, ylabel=ylabel, title=title, hline=hline
      )
      assert len(fig.data) == num_timeseries * (hline + len(traces))
  
imports: import math
  import os
  import warnings
  import cvxpy
  import numpy
  import pandas
  import pytest
  from scipy.linalg import sqrtm
  from sklearn.exceptions import NotFittedError
  from greykite.algo.reconcile.convex.reconcile_forecasts import ReconcileAdditiveForecasts
  from greykite.algo.reconcile.convex.reconcile_forecasts import TraceInfo
  from greykite.algo.reconcile.convex.reconcile_forecasts import apply_method_defaults
  from greykite.algo.reconcile.convex.reconcile_forecasts import evaluation_plot
  from greykite.algo.reconcile.convex.reconcile_forecasts import get_fit_params
  from greykite.algo.reconcile.convex.reconcile_forecasts import get_weight_matrix
  from greykite.algo.reconcile.hierarchical_relationship import HierarchicalRelationship
  from greykite.common.constants import TIME_COL
  from greykite.common.data_loader import DataLoader
  from greykite.common.evaluation import mean_absolute_percent_error
  from greykite.common.evaluation import median_absolute_percent_error
  from greykite.common.evaluation import root_mean_squared_error
  from greykite.common.python_utils import assert_equal
  from greykite.common.python_utils import reorder_columns
label_desc: Use image node_id 6 for calling a global function with example usage: test_evaluation_plot(data) without return types