How to animate a plot of raw EEG data?
Show older comments
Hello,
I would like to do a
1) simple plot of time against raw EEG (uV) data, the tricky thing is that
2) I hope to animate it as a moving line, as if it's being read real-time and the line forming.
I tried to look for answers throughout the forum but couldn't find any answer that can resolve this. I tried using this code, that plots a graph without any animation, and it seems to have an error message. Can anyone please help me see what the problem might be?
clear all
clc
a1 = animatedline('Color', [0 .7 .7]);
axis([0 30 0 1000])
t = linspace(0, 20, 180); %what does this mean?
T = readtable('d_museMonitor_2021-01-21--18-36-17.csv');
A = table2array(T(:, 23));
fs=256;
for k = 1:length(t)
tk = [0:length(A)-1]/fs;
y = A; %or can this be y = A(k,:)? but this doesn't seem to work either
addpoints(a1, tk, A);
drawnow limitrate
end
Warning: Number of points exceeds the default maximum number of points of 1000000. To control the number of points in the animated
line, set the MaximumNumPoints property of the AnimatedLine object to the desired value.
> In testing (line 17)
Yet the data I have only has around 50000 points.. So I don't quite understand what the situation is..
3) Also, would it be possible to also show me how to covert the animation into a movie?
Thanks!!
Answers (2)
Iuliu Ardelean
on 29 Jan 2021
Hi
I've changed a few things in your code.
Firstly, below is your movie as a .gif file. You can make it smoother if you want (see code below).
For more info on how to make .gif files, check out: https://uk.mathworks.com/matlabcentral/answers/94495-how-can-i-create-animated-gif-images-in-matlab (this is where I took the gif-making code sections from, and modified them a little).
I hope this answers all three questions.

Here is the code:
clear all
clc
close all
h = figure;
a1 = animatedline('Color', [0 .7 .7]);
axis([0 30 0 1000])
T = readtable('d_museMonitor_2021-01-21--18-36-17.csv');
A = table2array(T(:, 23));
t = linspace(0, 20, length(A)); % Q: what does this mean?
% A: this creates a vector of length 47039
% with the first element 0 and
% the final element 20...
fs=256;
filename = 'testAnimated.gif'; % this is for your movie
for k = 1:length(t)
tk = t(k);
yk = A(k);
addpoints(a1, tk, yk); % you need to make sure you are only adding one
% point at a time... that means that
% length of tk = length of yk = 1.
% I think you were giving it 47039 elements every time,
% which may have caused the Warning to appear, but I am not too sure.
drawnow limitrate
% to make a gif:
% Write to the GIF File
if k == 1
% Capture the plot as an image
frame = getframe(h);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
if mod(k,1000) == 0 % NOTE: change this to a smaller number if you want smoother gif
% you have quite a lot of points though, so it's a bit of a tradeoff
% between quality and total time required
% Capture the plot as an image
frame = getframe(h);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
end
end
1 Comment
Cherie Chao
on 30 Jan 2021
Edited: Cherie Chao
on 30 Jan 2021
Cris LaPierre
on 29 Jan 2021
I would modify the plotting code a little.
- Use fs to set the time
- Adjust xlim to give the perception of a 30 second scrolling window.
I find it much better to use the variable names to refer to data in a table. It helps you make sure you are plotting what you intended.
a1 = animatedline('Color', [0 .7 .7]);
axis([0 30 0 1000])
opts = detectImportOptions("d_museMonitor_2021-01-21--18-36-17.csv");
opts.VariableNamesLine = 1;
T = readtable('d_museMonitor_2021-01-21--18-36-17.csv',opts);
fs=256;
t = (1:height(T)-1)/fs;
for k = 1:height(T)
addpoints(a1, t(k), T.RAW_AF7(k));
% set the xlims to create a scrolling window
xlim([max(0, t(k)-30) max(30, t(k))])
drawnow limitrate
end
8 Comments
Cherie Chao
on 30 Jan 2021
Cris LaPierre
on 30 Jan 2021
Edited: Cris LaPierre
on 30 Jan 2021
That is the correct line to fix, but wrong fix. The intent was to besically get the row numbers, subtract 1 so time starts at 0, then divide by fs to turn it into time. However, the '-1' is only being subtracted from height and not the entire vector. That can be fixed by adding parentheses to force the desired order of operations.
t = ((1:height(T))-1)/fs;
Your fix has it now starting at a negative value.
As for creating and mp4, that can be done following this example. Starting at the "Create a video writer object" part, adapt it to your code and just change the video extension in the example from 'avi' to 'mp4'.
Cris LaPierre
on 30 Jan 2021
Edited: Cris LaPierre
on 30 Jan 2021
One caution. The default framerate of videowriter is 30. Your data is at 256. You can set the FrameRate, but if you save 47039 frames, your mp4 is going to be very large (and take a very long time). Consider creating an mp4 that uses a subset of the frames.
Cherie Chao
on 1 Feb 2021
Cris LaPierre
on 1 Feb 2021
Have you looked at the documentation page for videowriter? That will give you the correct syntax and input for an mp4.
Cherie Chao
on 2 Feb 2021
Edited: Cherie Chao
on 2 Feb 2021
Cris LaPierre
on 2 Feb 2021
The only difference was variable names and columns. Once you've selected the correct data, the rest of the code remains the same.
Cherie Chao
on 4 Feb 2021
Categories
Find more on Animation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!