Signal Imputation in Signal Analyzer Using Time-Series Foundation Model
This example shows how to integrate a Chronos model [1] into a MATLAB® workflow to restore missing values in a corrupted signal. The example also shows how to use the Chronos model as a custom preprocessing function in Signal Analyzer and use Signal Analyzer to analyze the imputed signal.
Introduction
Foundation models like Chronos can handle a wide range of time-series forecasting tasks with minimal customization. You can apply the model to a new data set without training it on that data set and adapt it for tasks such as anomaly detection and imputation.
In this example, you implement the model in PyTorch®. The chronos_forecast.py file defines the interface functions to load Chronos models and perform forecasting. The helperFillMissingWithChronos function handles data exchange between MATLAB and Python®, using the Chronos forecasting model to perform signal imputation. The helperCustomFillGaps function integrates Chronos as a custom preprocessing step in Signal Analyzer.
Set Up Python Environment
Chronos is implemented in PyTorch, so you must configure a Python environment for MATLAB to call. To install a supported Python implementation, see Configure Your System to Use Python. To avoid library conflicts, use the External Languages side panel in MATLAB to create a Python virtual environment using the requirements_chronos.txt file. For details on the External Languages side panel, see Manage Python Environments Using External Languages Panel. For details on Python environment execution modes and debugging Python from MATLAB, see Python Coexecution.
Use the helperCheckPyenv function to verify that the current PythonEnvironment contains the libraries listed in the requirements_chronos.txt file. This example was tested using Python 3.11.2.
requirementsFile = "requirements_chronos.txt";
currentPyenv = helperCheckPyenv(requirementsFile,Verbose=true);Checking Python environment Parsing requirements_chronos.txt Checking required package 'chronos-forecasting' Checking required package 'torch' Required Python libraries are installed.
You can use the following process ID and name to attach a debugger to the Python interface and debug the example code.
fprintf("Process ID for '%s' is %s.\n", ... currentPyenv.ProcessName,currentPyenv.ProcessID)
Process ID for 'MATLABPyHost' is 2961556.
Chronos is available in multiple pretrained variants, such as chronos-t5-tiny, chronos-t5-small, and larger models. You can choose a variant depending on the complexity of your task and available resources. The actual pretrained model is not loaded into memory until you make the first prediction using that model name.
Call Chronos Forecasting Model from MATLAB
Clear the Python Chronos pipeline cache to force a fresh model and pipeline initialization.
py.chronos_forecast.clear_pipeline_cache(verbose=1);
[chronos] pipeline cache cleared
Generate a simple synthetic input signal to forecast. Set npred to 16 to predict the next 16 points given the input signal. Chronos is a probabilistic model, so each prediction is randomly generated. Set nsample to 3 to generate three different forecasts.
sigin = sin((1:64)*0.4); npred = 16; nsample = 3;
Call the Chronos forecasting function implemented in Python from within MATLAB.
sigoutnp = py.chronos_forecast.forecast(sigin, int64(16),int64(3),model_name="amazon/chronos-t5-tiny");[chronos] initializing pipeline with ('amazon/chronos-t5-tiny', 'auto', torch.float32)
Convert the forecast output into a MATLAB double array. The size is 3-by-16, meaning three forecasts, each of length 16.
whos sigoutnpName Size Bytes Class Attributes sigoutnp 1x1 8 py.numpy.ndarray
sigout = double(sigoutnp);
whos sigoutName Size Bytes Class Attributes sigout 3x16 384 double
Visualize the results.
plot(1:64,sigin,64+1:64+16,sigout,"o") legend(["Signal","Prediction" + (1:3)],Location="southoutside",Orientation="horizontal") grid on ylim([-1,1])

Fill Missing Values Using Chronos Model from MATLAB
Prepare Signal with Missing Data
Create a synthetic signal by adding a linear trend and small noise to a frequency-swept chirp, then simulate missing data with NaNs.
fs = 1000;
t = 0:1/fs:1.5-1/fs;
rng("default")
sigFull = chirp(t,10,0.5,30) + t + 0.3*rand(1,length(t));
sigMissing = sigFull;
sigMissing(600:850) = NaN;Visualize the signal.
tiledlayout(2,1) nexttile plot(t,sigFull) xlabel("Time (s)") ylabel("Amplitude") title("Original Signal") grid on nexttile plot(t,sigMissing) xlabel("Time (s)") ylabel("Amplitude") title("Signal with Missing Data") grid on

Fill Missing Values in MATLAB Using Chronos
Use the provided helper function, helperFillMissingWithChronos, to call the Chronos model from MATLAB. For this simple case, use the lightweight chronos-t5-tiny variant.
Chronos is a probabilistic forecaster that not only provides a single imputed signal but also produces uncertainty bounds. The helperFillMissingWithChronos function returns not only a median prediction (filledChronos) but also lower and upper bounds (filledChronosLow and filledChronosHigh) that define a central 80% predictive interval, giving a sense of confidence around the reconstructed values inside the missing region.
Modify the function parameters to control how the function predicts missing values.
ContextLength— Control the number of previous time steps to use.MaxHorizon— Determine how far ahead to predict.Bidirectional— Enable the model to run both forward and backward passes, using past data to predict ahead and future data to predict backward, improving estimates within gaps.AggregationMethod— Determine how forward and backward predictions are combined. For example,"half"fills the first half of each missing region using the forward pass and the second half using the backward pass.ModelName— Select the Chronos model to use. The lightweight"amazon/chronos-t5-tiny"runs quickly, while"amazon/chronos-t5-small"or"amazon/chronos-t5-base"can improve accuracy on more complex data.ExecutionEnvironment— Specify the hardware resource for running the model. Defaults to "auto", but can be set to "cpu" or "gpu" for explicit control.Verbose— Control whether to display detailed progress information.
[filledChronos,filledChronosLow,filledChronosHigh] = helperFillMissingWithChronos( ... sigMissing, ... ContextLength=512, ... MaxHorizon=64, ... Bidirectional=true, ... AggregationMethod="half", ... ModelName="amazon/chronos-t5-tiny", ... ExecutionEnvironment ="auto",... Verbose=true);
[MATLAB] Clearing pipeline cache...
[chronos] pipeline cache cleared
[MATLAB] Starting Forward pass: 4 windows to forecast
[chronos] initializing pipeline with ('amazon/chronos-t5-tiny', 'auto', torch.float32)
[MATLAB] 1/4 Forward window | elapsed=0.8s ETA=2.5s
[MATLAB] 2/4 Forward window | elapsed=1.3s ETA=1.3s
[MATLAB] 3/4 Forward window | elapsed=1.8s ETA=0.6s
[MATLAB] 4/4 Forward window | elapsed=2.3s ETA=0.0s
[MATLAB] Starting Backward pass: 4 windows to forecast
[MATLAB] 1/4 Backward window | elapsed=0.5s ETA=1.5s
[MATLAB] 2/4 Backward window | elapsed=1.0s ETA=1.0s
[MATLAB] 3/4 Backward window | elapsed=1.5s ETA=0.5s
[MATLAB] 4/4 Backward window | elapsed=2.0s ETA=0.0s
Compare Results
Compare the original signal, the Chronos-imputed signal, and the result from an autoregressive gap-filling method.
filledAR = fillgaps(sigMissing);
fig = helperPlotImputationComparison(t, sigMissing, sigFull, ...
filledAR, filledChronos, filledChronosLow, filledChronosHigh);
Both methods exhibit slight discontinuities at the edges of the imputed regions. The Chronos model better preserves the signal's frequency and amplitude characteristics across the gap, while the autoregressive model introduces more noticeable distortions.
A closer look at the Chronos model shows that the 80% confidence interval becomes wider near the center of the gap, indicating increased uncertainty. This behaviour makes sense because the model relies on observed data at both ends of the gap to inform its predictions. The farther a point is from any known data, the less information the model has available to work with, so its confidence naturally decreases. As a result, the uncertainty is highest near the middle of the missing region.
Further compare the time-frequency characteristics of different imputation methods using spectrograms.
figure(Position=[0 0 800 600]);
tiledlayout(3,1);
sigList = {sigFull,filledChronos,filledAR};
sigNames = {"Original", "Chronos Imputed", "AR Imputed"};
for ii = 1:3
nexttile
sig = sigList{ii};
spectrogram(sig,128,96,"yaxis",MinThreshold=-30);
set(gca,'ylim',[0,0.2])
ylabel("Frequency")
title(sigNames(ii))
end
As shown, the Chronos-imputed result preserves the overall frequency trend across the missing region and maintains spectral energy more effectively than the autoregressive model.
Use Chronos Model as Custom Preprocessing Function in Signal Analyzer
Launch Signal Analyzer to Inspect Corrupted Signal
Load the sample vibration signal from the Helidata data set, which contains simulated accelerometer data recorded in a helicopter cabin during the main motor’s run-up and coast-down. The file includes a variable, vib, that holds the vibration time series.
data = load("helidata");
signalGroundTruth = data.vib;Set the random seed for reproducible gaps. Use helperAddRandomMissing to introduce 15% missing samples into vibsignal between 20% and 80% of its length, with each gap spanning 10–50 samples.
rng("default") gapRange = [round(0.2*numel(signalGroundTruth)) round(0.8*numel(signalGroundTruth))]; [sigCorrupted, gapMask] = helperAddRandomMissing( ... signalGroundTruth, ... 0.15, ... Range=gapRange, ... MinGapLen=10, ... MaxGapLen=50 ... );
Open Signal Analyzer and display the corrupted signal.
signalAnalyzer(sigCorrupted)
Duplicate and Preprocess Signals
Follow the instructions in Preprocess Signals to add a custom preprocessing function, which internally calls the MATLAB wrapper function of your Python model.
Use the provided helperCustomFillGaps function as an example. It internally calls helperFillMissingWithChronos. Duplicate the corrupted signal in the Signals table to preserve a reference. Apply the custom fill-gaps function only to the copy. Press Accept All to commit the changes.

Compare Original and Filled Signals
Accept all changes and compare the filled signal with the original ground truth signal.

Further compare the spectrograms obtained from the Chronos model (imputed), the autoregressive model (imputed), and the ground truth signal, shown from left to right.

Conclusion
This example demonstrates how to integrate Python-based models into MATLAB workflows and Signal Analyzer, enabling advanced data preprocessing directly within MATLAB. By bringing Python capabilities into MATLAB, you can expand preprocessing options while continuing to leverage MATLAB interactive apps, visualization, and analysis tools in a seamless environment.
Reference
[1] Ansari, Abdul Fatir, Lorenzo Stella, Caner Turkmen, Zhang Xiyuan, Pedro Mercado, Huibin Shen, Oleksandr Shchur, et al. "Chronos: Learning the Language of Time Series." Transactions on Machine Learning Research, 2024. https://openreview.net/forum?id=gerNCVqqtR
Appendix — Helper Functions
helperPlotAnomalyResults This function plots imputation results comparing AR and Chronos methods.
function fig = helperPlotImputationComparison(t, sigMissing, sigFull, filledAR, filledChronos, filledChronosLow, filledChronosHigh) % Plot imputation results comparing AR and Chronos methods % This function is only intended to support this example. It may be changed % or removed in a future release. arguments t (:,1) {mustBeNumeric} sigMissing (:,1) {mustBeNumeric} sigFull (:,1) {mustBeNumeric} filledAR (:,1) {mustBeNumeric} filledChronos (:,1) {mustBeNumeric} filledChronosLow (:,1) {mustBeNumeric} filledChronosHigh (:,1) {mustBeNumeric} end % Compute masks m = isnan(sigMissing); o = ~m; % Create observed/imputed versions chronosObs = filledChronos; chronosImp = filledChronos; chronosObs(m) = NaN; chronosImp(o) = NaN; arObs = filledAR; arImp = filledAR; arObs(m) = NaN; arImp(o) = NaN; % Create figure fig = figure(Position=[0 0 800 800]); tiledlayout(4, 1, TileSpacing="compact") % Plot 1: Original Signal nexttile hold on plot(t, sigMissing, LineWidth=1.2, DisplayName="Observed") plot(t(m), sigFull(m), DisplayName="True (Gap)") hold off title("Original Signal") legend(Location="northwest") box on grid on % Plot 2: AR Imputed nexttile hold on plot(t, arObs, LineWidth=1.2, DisplayName="Observed") plot(t, arImp, DisplayName="AR (Imputed)") hold off title("AR Imputed") xlabel("Time (s)") legend(Location="northwest") grid on box on % Plot 3: Chronos Imputation with Uncertainty Band nexttile ax = gca; c = ax.ColorOrder(5,:); hold on plot(t, chronosObs, LineWidth=1.2, DisplayName="Observed") fill([t(:); flipud(t(:))], [filledChronosLow(:); flipud(filledChronosHigh(:))], c, ... FaceAlpha=0.8, EdgeColor="none", DisplayName="80% Confidence Band") plot(t, chronosImp, LineWidth=1.2, DisplayName="Chronos (Imputed)") hold off title("Chronos Imputation with Uncertainty Band") legend(Location="northwest") grid on box on % Plot 4: Chronos vs Ground Truth nexttile hold on plot(t, sigMissing, LineWidth=1.2, DisplayName="Observed") plot(t(m), sigFull(m), LineWidth=1.2, DisplayName="True (Gap)") plot(t, chronosImp, "--", LineWidth=1.2, DisplayName="Chronos (Imputed)") hold off title("Chronos Imputed vs Ground Truth") xlabel("Time (s)") legend(Location="northwest") grid on box on % Link axes linkaxes(findall(fig, Type="Axes"), "xy") % Adjust view after plotting xlim([0.4 1]) ylim([-1.1 2.2]) end
See Also
Apps
Functions
chirp|fillgaps|spectrogram