How can I add animation on the existing subplots?
14 次查看(过去 30 天)
显示 更早的评论
Hello,
I am trying to combine 5 graphs and a video and add a moving xline on each graph like a play bar. I was able to put graphs and video together, but I am struggling with adding the animation of moving xline on existing subplots. Also, it would be perfect if I could match the frame rate to play the video. The data were sampled at 2000 Hz whereas the video was recorded at approximately 30 Hz. I have attached my code and screenshot of the figure below just in case it helps.
I really appreciate any help.
for i = 2:6
if i == 2
s1 = subplot(5,7,[1,2]);
plot(s1,t,data.data(:,i));
xlim([0, t(end-1)])
title('Vertical Ground Reaction Force')
ylabel('N')
xlabel('Time (s)')
elseif i == 3
s2 = subplot(5,7,[8,9]);
plot(s2,t,movmean(data.data(:,i),100));
hold on;
area(t,max(movmean(data.data(:,i),100),threshold(i-2)),threshold(i-2));
xlim([0, t(end-1)])
title(data.labels(i,:))
xlabel('Time (s)')
ylabel('mV')
elseif i == 4
s3 = subplot(5,7,[15,16]);
plot(s3,t,movmean(data.data(:,i),100));
hold on;
area(t,max(movmean(data.data(:,i),100),threshold(i-2)),threshold(i-2));
xlim([0, t(end-1)])
title(data.labels(i,:))
xlabel('Time (s)')
ylabel('mV')
elseif i == 5
s4 = subplot(5,7,[22,23]);
plot(s4,t,movmean(data.data(:,i),100));
hold on;
area(t,max(movmean(data.data(:,i),100),threshold(i-2)),threshold(i-2));
xlim([0, t(end-1)])
title(data.labels(i,:))
xlabel('Time (s)')
ylabel('mV')
else
s5 = subplot(5,7,[29,30]);
plot(s5,t,movmean(data.data(:,i),100));
hold on;
area(t,max(movmean(data.data(:,i),100),threshold(i-2)),threshold(i-2));
xlim([0, t(end-1)])
title(data.labels(i,:))
xlabel('Time (s)')
ylabel('mV')
end
end
%%
ax1 = subplot(5,7,[3:7,10:14,17:21,24:28,31:35]); % For video
filename = fullfile(path,file);
v = VideoReader(filename);
nFrames = v.Duration*v.FrameRate; % Number of frames
% Display the first frame in the top subplot
vidFrame = readFrame(v);
image(vidFrame, 'Parent', ax1);
ax1.Visible = 'off';
i = 1;
%% Animate
while hasFrame(v)
pause(1/v.FrameRate);
vidFrame = readFrame(v);
image(vidFrame, 'Parent', ax1);
ax1.Visible = 'off';
s1 = xline(t(i));
i = i + 1;
end
0 个评论
采纳的回答
dpb
2022-11-2
I've got more going on at the moment than have time to deal with the synchronization issue, but the animated line in an existing axes is simple -- just use
s1 = subplot(5,7,[1,2]);
...
hAL(1)=animatedline(s1);
...
will return the handle of an animatedline object in the given axes. You then can add data to the object with addpoints in a loop either in batches or one-by-one.
2 个评论
dpb
2022-11-3
编辑:dpb
2022-11-3
Yes, create the object after the axes so you have the axes handle with which to associate each animated line -- the first call would be outside the time loop; the addpoints call inside when have new data.
You could have two animated lines in each, but neither animatedline nor xline is really designed for the purpose; for it I would suggest using xline but also similarly as with the animatedline, create one for each subplot axis at the same time as the animatedline, but then when updating, use the .Value property instead of calling xline again -- when you do that, you create a new line, you don't update the existing one...
hAx(1) = subplot(5,7,[1,2]);
hAL(1)=animatedline(hAx(1));
hXL(1)=xline(hAx(1),0);
...
% begin loop here after all axes/line objects are created...
while haveDataComing
for ix=1:numel(hAx) % use handle array so can iterate instead of duplicate
addpoints(hAL(i),XnextDataAxis(i),YnextDataAxis(i)); % update new data each axes
hXL(i).Value=XnextDataAxis(i); % and move the vertical line
end
haveDataComing=NewDataArrivedFlag;
end
The logic to determine how long to run may be from external event or if this is replaying previously recorded/computed data, then just a for...end loop over that array size may be substituted for a whle construct.
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!