Plot a segment over an animated line in real-time with dynamic time (X) axis

21 visualizzazioni (ultimi 30 giorni)
Hello all,
I've been struggling for a while to make this work. I have some realtime values coming from some sensors. I make forecasting based on some time-window using double exponential moving average. I want to plot the data feed in real time and every once in a while to also plot the forecast for the next N seconds. Obviously I simplified the code for the example bellow, replacing the real-time reading and writing of the values with a simple RNG, and also removed the entire forecasting part and just added a simple constant for the second plot.
N = 30; % time window
FutureTime = zeros([1,N]);
%%CREATE A FIGURE TO VISUALISE THE PLOT
f = figure('Name', 'Live Data Feed & Forecasts');
X1 = subplot(1,2,1); % There would be multiple subplots - one for every monitored parameter
X1.YGrid = 'on';
X1.YLim = [-1 2];
title('Parameter 1 Feed and Forecast');
ylabel('param 1 dimention');
xlabel('Time [hh:mm:ss]');
Line1 = animatedline('Color','r','LineWidth',2); % Animated line for the 1st subplot
All_Axes = X1; % An array containing all subplots' X axes for use with the dynamicDateTicks function
%%SET CYCLE TIME
time = now;
stopTime = '03/26 17:33'; % Run time for the cycle
count = 1; % cycle counter
while ~isequal(datestr(now,'mm/DD HH:MM'),stopTime)
time(count) = datenum(clock);
Y1 = rand; % read real-time value
addpoints(Line1,datenum(time(count)),Y1); % Plot real-time data to the respective animated line
hold on
% Update axes
X1.XLim = datenum([time(count)-seconds(N) time(count)+seconds(N)]); % Set the range of X axes to be N seconds before and after 'now'
dynamicDateTicks(All_Axes, 'HH:MM:SS') % Dynamically convert serial time to hh:mm:ss format
drawnow
%%PLOT SECOND LINE
%
% if mod(count,5)==0 % make forecast every 5 seconds for the next N seconds (starting after N sec.)
%
% Forecast_Param1(1:N) = 0.5; % tons of code here, but for cimplicity we'll take this for a constant
%
% for i=1:N % Build extended time array (N seconds into the future) from the last reading's timestamp
% FutureTime(1,i) = addtodate(time(count), i, 'second');
% end
%
% % plot the forecast on top of the live data (with transparency 80%)
% h1a = plot( FutureTime,Forecast_Param1, 'c', 'LineWidth',6, 'DisplayName',' 0.2');
% h1a.Color(4) = 0.2;
% xlim = datenum([time(count)-seconds(N) time(count)+seconds(N)]); % Set the range of X axes to be N seconds before and after 'now'
% dynamicDateTicks(All_Axes, 'HH:MM:SS') % Dynamically convert serial time to hh:mm:ss format
% drawnow
%
% end
pause(1); % Wait 1 sec for the sensors to give new values
count = count +1;
end
disp('END');
The code above works perfect as long as the second line (the plot in the cycle) is not run. The animated line moves ahead as intended and the X axis is dynamically set with the correct time window. As soon as the second plot is added the X axis stops being "dynamic" and has a constant beginning just expanding ahead. If I mark the animated line as comment and just run the plot, then again everything works fine and the X axis changes accordingly. But for the life of me, I can't make them tic together... :(
Can anyone with more experience have a look and say where might I be wrong? P.S. The dynamicDateTicks is auxiliary function by Ameya Deoras: https://www.mathworks.com/matlabcentral/fileexchange/27075-intelligent-dynamic-date-ticks

Risposte (1)

Alexander Grantcharov
Alexander Grantcharov il 15 Set 2019
Modificato: Alexander Grantcharov il 15 Set 2019
Coming back here a bit over a year later I though I'd give answeres to my own questions :) just in case anyone else needs doing the same things and is having the same struggles I had.
The script uses DynamicDateTicks by Ameya Deoras to do most of the work. Here is how I did it (I've reduced a lot of my code, and added extra comments, just to make is easier to understand):
% atm_temperature_value.Value and atm_pressure_value.Value are my live feed values acquired from the sensors
% If you want to test my code you'll have to attach these values to something else (you could use a RNG within the loop)
% The same has to be done for Forecast_Temperature and Forecast_Pressure arrays, as they are the result of the forecasting process
%% CREATE A FIGURE TO VISUALISE THE PLOTS
f = figure('Name', 'Live Data Feed', 'Position', [50 350 1800 600]);
Tx = subplot(2,5,1); % Temperature Subplot X axis
T_Line = animatedline('Color',[1.000 0.000 0.000],'LineWidth',2); % the line animating the live (main) feed of data in red
TF_Line = animatedline('Color',[1.000 0.000 0.000], 'LineWidth',4, 'DisplayName',' 0.1'); % the animated line of the second (predicted) data set (thiker red line with reduced opacity)
TF_Line.Color(4) = 0.1; % Reduced opacity for the second (prediction) line
Px = subplot(2,5,2); % Pressure Subplot
P_Line = animatedline('Color',[0.812 0.573 0.000],'LineWidth',2); % Orange
PF_Line = animatedline('Color',[0.812 0.573 0.000], 'LineWidth',4, 'DisplayName',' 0.1');
PF_Line.Color(4) = 0.1;
% An axis array for all data subplot's X axis to be updated and visualised as date time format
All_Axes = [Tx Px]; % Add all subplot's X axes to this array
% SET TIME FOR THE CYCLE (AND FINISH THE EXPERIMENT)
stopTime = '03/26 17:33'; % MM/DD Time
count = 1; % Cycle counter
while ~isequal(datestr(now,'mm/DD HH:MM'),stopTime)
%% UPDATE THE ANIMATED LINES
% Get the current time
t = datetime('now');
addpoints(T_Line,datenum(t),atm_temperature_value.Value); % Plot real-time temperature value (from the sensor) to the T_Line on Tx axis
addpoints(P_Line,datenum(t),atm_pressure_value.Value); % Plot real-time pressure value (from the sensor) to the P_Line on Px axis
%% SOME CODE HERE TO FORECAST NEXT (N) PERIOD EVERY (M) SECONDS
% Forecast_Temperature and Forecast_Pressure arrays are the result of this action
% Build extended time array (N seconds into the future)
% with 1 seconds step interval
for i=1:N
ForecastTime(1,i) = addtodate(datenum(t), i, 'second');
end
% Plot Forecasted Values
addpoints(TF_Line,ForecastTime(1,N),Forecast_Temperature(1,N)); % Adds the forcasted values to the Temperature subplot, but uses the forecasted line features.
addpoints(PF_Line,ForecastTime(1,N),Forecast_Pressure(1,N)); % The same for the Pressure.
drawnow
%% UPDATE X AXES ON ALL SUBPLOTS
Tx.XLim = datenum([t-seconds(N) t+seconds(N)]);
Px.XLim = datenum([t-seconds(N) t+seconds(N)]);
dynamicDateTicks(All_Axes, 'HH:MM:SS') % Uses the array of all X axis
drawnow
%% END ITTERATION
pause(1);
count = count +1;
end
disp('END');
I'm not sure how clear I've made this, but hopefully it is helpfull to someone. :)
Cheers!

Categorie

Scopri di più su 2-D and 3-D Plots in Help Center e File Exchange

Prodotti

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by