code: def test_silverkite_with_components_hourly_data(
      expected_component_names,
  ):
      """Tests ``plot_components`` with hourly data"""
      hourly_data = generate_df_with_reg_for_tests(
          freq="H",
          periods=24 * 3,
          train_start_date=datetime.datetime(2018, 1, 1),
          conti_year_origin=2018,
      )
      train_df = hourly_data.get("train_df").copy()
      params_hourly = params_components()
      # Removes predictor column for dow by hour interaction
      # "dow_hr" is unique in forecast period otherwise and causes an error
      params_hourly["extra_pred_cols"].remove("dow_hr")
  
      # converts into parameters for `forecast_silverkite`
      coverage = params_hourly.pop("coverage")
      model = BaseSilverkiteEstimator(
          coverage=coverage,
          uncertainty_dict=params_hourly["uncertainty_dict"],
      )
      model.fit(
          X=train_df, time_col=cst.TIME_COL, value_col=cst.VALUE_COL
      )
      silverkite = SilverkiteForecast()
      model.model_dict = silverkite.forecast(
          df=train_df,
          time_col=cst.TIME_COL,
          value_col=cst.VALUE_COL,
          **params_hourly,
      )
      model.finish_fit()
  
      # Tests `plot_components`
      title = "Custom component plot"
      fig = model.plot_components(title=title)
      expected_rows = 10
      assert len(fig.data) == expected_rows  # includes changepoints
      assert all(
          [
              fig.data[i].name in expected_component_names
              for i in range(expected_rows)
          ]
      )
      assert fig.layout.xaxis.title["text"] == "Date"
      assert fig.layout.title["text"] == title
      assert fig.layout.title["x"] == 0.5
  
      # Tests `plot_components(predict_phase=True)`
      _ = model.predict(X=hourly_data["test_df"])
      fig = model.plot_components(predict_phase=True)
      expected_rows = 6
      assert len(fig.data) == expected_rows  # includes changepoints
      assert all(
          [
              fig.data[i].name in expected_component_names
              for i in range(expected_rows)
          ]
      )
      assert fig.layout.xaxis.title["text"] == "Date"
      assert fig.layout.title["text"] == "Component Plot - Predicted"
      assert fig.layout.title["x"] == 0.5
  
      # Tests `plot_components(predict_phase=True)` with gap
      _ = model.predict(X=hourly_data["test_df"].iloc[5:, :])
      fig = model.plot_components(predict_phase=True)
      expected_rows = 6
      assert len(fig.data) == expected_rows  # includes changepoints
      assert all(
          [
              fig.data[i].name in expected_component_names
              for i in range(expected_rows)
          ]
      )
      assert fig.layout.xaxis.title["text"] == "Date"
      assert fig.layout.title["text"] == "Component Plot - Predicted"
      assert fig.layout.title["x"] == 0.5
  
imports: import datetime
  import numpy
  import pandas
  import pytest
  from sklearn.exceptions import NotFittedError
  from sklearn.metrics import mean_absolute_error
  from sklearn.metrics import mean_squared_error
  from testfixtures import LogCapture
  import greykite.common.constants
  from greykite.algo.forecast.silverkite.forecast_silverkite import SilverkiteForecast
  from greykite.common.data_loader import DataLoader
  from greykite.common.features.timeseries_features import convert_date_to_continuous_time
  from greykite.common.python_utils import assert_equal
  from greykite.common.testing_utils import daily_data_reg
  from greykite.common.testing_utils import generate_df_for_tests
  from greykite.common.testing_utils import generate_df_with_reg_for_tests
  from greykite.sklearn.estimator.base_silverkite_estimator import BaseSilverkiteEstimator
  from greykite.sklearn.estimator.testing_utils import params_component_breakdowns
  from greykite.sklearn.estimator.testing_utils import params_components
label_desc: Use image node_id 15 for calling a global function with example usage: test_silverkite_with_components_hourly_data(expected_component_names) without return types