Continuous X-Axis plot in Real Time

I am plotting some data from arduino in Matlab in real-time. The problem is that I am unable to get the x-axis (samples) to increase in samples without starting from 0 again. So I have the data with an interval of 200 samples (interv = 200;) and the axis are plotted using: axis([0,interv,0,3]). All this is under a while(1) loop so it plots the graph continuously but once the samples reach 200, its starts to plot again from 0 and the process is repeated. So what I would like to do is once 200 is reached then continue the samples to display from 200-400 and then 400-600 and so on. I don't want to use auto-axis since it will just squash the data.

 采纳的回答

bilal - please see https://www.mathworks.com/matlabcentral/answers/284202-how-to-plot-a-real-time-signal-with-axes-automatically-updating which has an example that is similar to yours. It proposes that a timer be used to update the axes (rather than a while loop) and updates the data for the graphics object that was used to plot the data
xdata = [get(handles.hPlot,'XData') handles.T(end)];
ydata = [get(handles.hPlot,'YData') handles.array(end)];
set(handles.hPlot,'XData',xdata,'YData',data);
where
handles.hPlot = plot(NaN,NaN); % creates the graphics object with no data
Or, if you just want to set the limits on the x-axis, you could probably use xlim to set the limits on the x-axis given the current set of samples
numSamples = 200;
atBlock = 1;
xlim([(atBlock-1)*numSamples atBlock*numSamples]);

6 个评论

Thanks for your response Geoff, I think that example is a lot more complex than what I am trying to do. I have added my code below.
I don't want to set a limit on the x-axis but I just simply want it to plot continuously on the x-axis so from 0 - 200 samples, then from 200-400, 400-600, 600-800 and so on until the code is aborted.
clc
clear all
a = arduino('COM4', 'Due');
while(1)
interv = 200;
k = 1;
t=1;
x=0;
while(t<interv)
b=readVoltage(a, 'A0');
x=[x,b];
plot(x);
xlabel('Samples')
ylabel('Voltage')
title('Phonocardiogram')
axis([0,interv,0,3]);
grid
t=t+k;
drawnow;
pause(0.002)
end
end
bilal - ok, the problem may be with your initialization of x
x = 0;
which is reset on each iteration of the outer while loop...which would explain why the data starts to plot again from 0. I would either initialize it to be an empty array as
x = [];
or after the end of the inner while loop (so once it completes) set it to be the last element of x
x = 0;
while(1)
% etc.
while t<interv
% etc.
end
x = x(end);
end
In the second example, x is initialized to zero before we start the outer while loop and re-initialize it once the inner while loop completes.
But either of the above might not be sufficient because you still set the axis limits as
axis([0,interv,0,3]);
and interv never changes from 200 so you will always be fixing the x axis limits to [0, 200]. If you want to shift the interval by 200 on each iteration of the inner while loop, you may have to do something like
clc
clear all
a = arduino('COM4', 'Due');
y=0;
hPlot = plot(NaN);
intervalSize = 200;
currentInterval = 200;
t = 1;
atInterval = 1;
while(1)
k = 1;
while(t<currentInterval)
b=readVoltage(a, 'A0');
y=[y,b];
set(hPlot, 'YData', y);
xlabel('Samples')
ylabel('Voltage')
title('Phonocardiogram')
axis([currentInterval - intervalSize,currentInterval,0,3]);
grid
t=t+k;
pause(0.002)
end
currentInterval = currentInterval + intervalSize;
atInterval = atInterval + 1;
end
In the above, I've changed some of the variable names to distinguish between the interval size (200) and the current interval. I've also replaced x with y since the voltage (which is what you are reading) is the variable along the y-axis whereas the number of samples is along the x-axis.
Note the
axis([currentInterval - intervalSize,currentInterval,0,3]);
which ensures that the x-axis limits are always (currentInterval-200, currentInterval) which would be (0,200), (200,400), etc.
Each time that you call plot, you create a new graphics object. Given that you have two while loops, this means that you are creating several hundred objects when all you really need is one that you update again and again. I've simplified this to a single graphics object which you can re-use on each iteration of the loop.
There are probably other improvements that you can make to the code (one being that all samples are kept even those from intervals that are no longer being shown because of the limits to the axes, so you can exclude all of this old data if no longer needed).
Thank you very much Geoff. This is exactly what I was after. :)
Hi Geoff - on the above code it works fine but when I close the graph, the following displays in the command window:
Error using matlab.graphics.chart.primitive.Line/set
Invalid or deleted object.
Error in newPCG (line 24)
set(hPlot, 'YData', y);
Do you have any ideas as to why that my be? Thanks
Hi bilal - you are closing the figure so the handle hPlot (of the graphics object drawn on the figure) is no longer valid. You're while loop doesn't know this and so throws an error when it tries to call
set(hPlot, 'YData', y);
since hPlot is no longer valid. I suppose you could put a check around this as
if ishandle(hPlot)
set(hPlot, 'YData', y);
else
break; % break out of the loop
end
You would then need another check in the outer while loop to decide whether you should break out of that one too
while(1)
k = 1;
while(t<currentInterval)
b=readVoltage(a, 'A0');
y=[y,b];
if ishandle(hPlot)
set(hPlot, 'YData', y);
else
break; % break out of the loop
end
xlabel('Samples')
ylabel('Voltage')
title('Phonocardiogram')
axis([currentInterval - intervalSize,currentInterval,0,3]);
grid
t=t+k;
pause(0.002)
end
currentInterval = currentInterval + intervalSize;
atInterval = atInterval + 1;
if ~ishandle(hPlot)
break;
end
end
% close connection to arduino
That makes sense and has solved the problem. Thank you :)

请先登录,再进行评论。

更多回答(0 个)

类别

帮助中心File Exchange 中查找有关 Graphics Performance 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by