Args: ... (existing args) ... is_mcl: Whether the forecasts come from timeMCL model (with scores) or TimeGrad
(target_df, hypothesis_forecasts, forecast_length, rows=4, cols=4, plot_mean=True, context_points=None, freq_type='H', fname='Predictions_plot.png', extract_unique=True, save_path=None, is_mcl=True, plot_p=True, main_color='lightcoral', mean_color='blue', dataset=None, axs=None, ax_cbar=None, global_min_prob=None, global_max_prob=None, dims_to_plot=None, seed=None)
| 50 | return hypothesis_forecasts, probabilities |
| 51 | |
| 52 | def plot_mcl(target_df, hypothesis_forecasts, forecast_length, rows=4, cols=4, plot_mean=True, context_points=None, freq_type='H', fname='Predictions_plot.png', extract_unique=True, save_path=None, is_mcl=True, plot_p=True, main_color='lightcoral', mean_color='blue', dataset=None, axs=None, ax_cbar=None, global_min_prob=None, global_max_prob=None, dims_to_plot=None, seed=None): |
| 53 | """ |
| 54 | Args: |
| 55 | ... (existing args) ... |
| 56 | is_mcl: Whether the forecasts come from timeMCL model (with scores) or TimeGrad |
| 57 | """ |
| 58 | # Handle forecasts based on model type |
| 59 | if is_mcl: |
| 60 | # For timeMCL, extract unique forecasts if requested |
| 61 | if extract_unique: |
| 62 | hypothesis_forecasts, probabilities = extract_unique_forecasts(hypothesis_forecasts) |
| 63 | else: |
| 64 | # Extract scores for non-unique forecasts |
| 65 | scores = hypothesis_forecasts[:,:,-1] |
| 66 | hypothesis_forecasts = hypothesis_forecasts[:,:,:-1] |
| 67 | probabilities = scores / scores.sum(axis=0, keepdims=True) |
| 68 | else: |
| 69 | # For TimeGrad, use equal probabilities for all samples |
| 70 | probabilities = np.ones_like(hypothesis_forecasts) / hypothesis_forecasts.shape[0] |
| 71 | |
| 72 | # check PeriodIndex |
| 73 | if isinstance(target_df.index, pd.PeriodIndex): |
| 74 | target_df.index = target_df.index.to_timestamp() |
| 75 | |
| 76 | # entire data |
| 77 | time_index = target_df.index |
| 78 | values = target_df.values |
| 79 | full_len, target_dim = values.shape |
| 80 | |
| 81 | k, fcst_len, d_ = hypothesis_forecasts.shape |
| 82 | assert fcst_len == forecast_length, "forecast_length mismatch" |
| 83 | |
| 84 | # define how many context points we want before the 'end of training' |
| 85 | # if not given, default to 2 * forecast_length |
| 86 | if context_points is None: |
| 87 | context_points = 2 * forecast_length |
| 88 | |
| 89 | # suppose "end of training" is (full_len - forecast_length) |
| 90 | # i.e. the last training point is full_len - forecast_length - 1 |
| 91 | train_end_idx = full_len - forecast_length |
| 92 | if train_end_idx < 0: |
| 93 | # edge case: dataset too short vs forecast_length |
| 94 | train_end_idx = full_len |
| 95 | |
| 96 | # we want from (train_end_idx - context_points) up to the end of the dataset |
| 97 | start_idx = max(0, train_end_idx - context_points) |
| 98 | |
| 99 | # slice the data in that window |
| 100 | tail_index = time_index[start_idx:] |
| 101 | tail_values = values[start_idx:] |
| 102 | if len(tail_values) == 0: |
| 103 | print("WARNING: tail is empty!") |
| 104 | return |
| 105 | |
| 106 | # freq inference |
| 107 | freq = tail_index.freq |
| 108 | if freq is None: |
| 109 | freq = pd.infer_freq(tail_index) |
no test coverage detected