Fix errors and bugs in the given code, without changing its intended functionality. ONLY return the fixed code and nothing else. Enclose the entire code in a single code block.



from darts import TimeSeries
from darts.models import KalmanForecaster
import numpy as np
import pandas as pd
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import matplotlib.pyplot as plt

# Define the train-test split ratio
train_ratio = 0.98

# Sample data for demonstration purposes
filtered_refgps = filtered_refgps  # assume this is already defined

# Determine the number of training samples
num_samples = len(filtered_refgps)
train_size = int(num_samples * train_ratio)

# Create a date range for the entire dataset
date_range = pd.date_range(start='2023-01-01', periods=num_samples, freq='D')

# Create a DataFrame with the date range and the filtered_refgps data
df = pd.DataFrame({'value': filtered_refgps}, index=date_range)

# Split the data into train and test sets
train_df = df.iloc[:train_size]
test_df = df.iloc[train_size:]

# Convert to TimeSeries with explicit frequency handling
train_series = TimeSeries.from_dataframe(train_df, freq='D', fill_missing_dates=True)
test_series = TimeSeries.from_dataframe(test_df, freq='D', fill_missing_dates=True)

# Initialize KalmanForecaster
model = KalmanForecaster(dim_x=12)

# Fit the model on the training data
model.fit(train_series)

# Function to generate and plot forecasts
def generate_and_plot_forecasts(forecast_horizon, stride):
    historical_fcsts = model.historical_forecasts(
        series=test_series,
        start=0,
        forecast_horizon=forecast_horizon,
        stride=stride,
        retrain=False,
        verbose=True
    )
    
    # Extract predicted values
    if isinstance(historical_fcsts, list):
        # For multi-step forecasts, we get a list of TimeSeries
        pred_values = np.array([ts.values().flatten() for ts in historical_fcsts])
        forecast_dates = historical_fcsts[0].time_index
    else:
        # For single-step forecasts, we get a single TimeSeries
        pred_values = historical_fcsts.values()
        forecast_dates = historical_fcsts.time_index
    
    # Plot results
    plt.figure(figsize=(12, 6))
    plt.plot(test_df.index, test_df['value'].values, label='Actual', alpha=0.7)
    
    if pred_values.ndim == 1:
        plt.plot(forecast_dates, pred_values, label='Forecast', linestyle='--', alpha=0.7)
    else:
        for i in range(pred_values.shape[1]):
            plt.plot(forecast_dates, pred_values[:, i], 
                     label=f'Forecast t+{i+1}', linestyle='--', alpha=0.7)
    
    plt.legend()
    plt.title(f'Kalman Filter Forecaster: Horizon={forecast_horizon}, Stride={stride}')
    plt.xlabel('Date')
    plt.ylabel('Value')
    plt.show()
    
    print(f"Number of test samples: {len(test_df)}")
    print(f"Number of forecast points: {len(forecast_dates)}")
    print(f"Shape of pred_values: {pred_values.shape}")

# Generate and plot forecasts for different settings
why cant i get 4 charts?
generate_and_plot_forecasts(forecast_horizon=4, stride=1)

# Function to calculate metrics
def calculate_metrics(actual, predicted):
    mse = np.mean((actual - predicted)**2)
    rmse = np.sqrt(mse)
    mae = np.mean(np.abs(actual - predicted))
    return mse, rmse, mae

# Calculate metrics for single-step forecast
historical_fcsts = model.historical_forecasts(
    series=test_series,
    start=0,
    forecast_horizon=1,
    stride=1,
    retrain=False,
    verbose=True
)

pred_values = historical_fcsts.values().flatten()
actual_values = test_df['value'].values[-len(pred_values):]

mse, rmse, mae = calculate_metrics(actual_values, pred_values)
print(f'Metrics for single-step forecast:')
print(f'MSE: {mse:.4f}, RMSE: {rmse:.4f}, MAE: {mae:.4f}')