Real time plotting - Matlab GUI

Hey y'all. I'm running into a little problem. Can y'all please help?
I am reading values from an instrument and trying to plot these values continuously when the push button (converted it to a toggle button) is pressed. I am using Guide for my GUI.
please note that the code isn't complete yet, but I am testing the real time plotting at this point. I'm not sure how to get the while (when pressed) condition for the push_button. Also, I took the section of code within the loop to a seperate file and was able to plot it. However, Matlab plots one point at a time and I was not able to get it such that it connected the points.
Thanks.
function pushbutton11_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton11 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Establish Device (Boonton 4500C RF Power Analyzer) Communication
ni=NET.addAssembly('NationalInstruments.VisaNS');
res=NationalInstruments.VisaNS.ResourceManager.GetLocalManager.FindResources('?*').cell;
dev=NationalInstruments.VisaNS.ResourceManager.GetLocalManager.Open(res{1});
% Change device units to Watts
dev.Write('CALC:UNIT W')
grab_avg_time = datetime();
grab_avg = [];
while get(pushbutton11, 'value')
grab_avg= strsplit((string(dev.Query('FETC1:ARR:CW:POW?'))),','); %Fetch data from PM and convert to string
pause(2)
grab_avg = str2num(c(2)) %Average Power - Convert String to Number and place in array
pause(0.5)
grab_avg_time = datetime('now');
pause(0.5)
plot(grab_avg_time,grab_avg, '--*')
hold on
end
% Update handles structure
guidata(hObject, handles);

 Risposta accettata

Geoff Hayes
Geoff Hayes il 20 Feb 2019
George - whenever you call plot like with
plot(grab_avg_time,grab_avg, '--*')
you are creating a new graphics object and so its data cannot be connected to data that has been plotted previously via other graphics objects. What you may want to do instead is to create one plot graphics object and update its data on each iteration of the while loop. For example, you would create the grpahics object as
hPlot = plot(NaN, NaN, '--*);
Then, in the while loop, you would update this object as
xdata = [get(hPlot,'XData') grab_avg_time]; % update the x-data
ydata = [get(hPlot,'YData') grab_avg]; % update the y-data
set(hPlot,'XData',xdata,'YData',data);
Note that instead of using a while loop, you could use a timer. See How to plot a real time signal with axes automatically updating for an example.

12 Commenti

Hey Geoff, thanks so much. I modified the code, but I am still getting some errors. Do you have
any thoughts?
Code:
function pushbutton11_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton11 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
cla reset; %Clear plot window
% Establish Device (Boonton 4500C RF Power Analyzer) Communication
ni=NET.addAssembly('NationalInstruments.VisaNS');
res=NationalInstruments.VisaNS.ResourceManager.GetLocalManager.FindResources('?*').cell;
dev=NationalInstruments.VisaNS.ResourceManager.GetLocalManager.Open(res{1});
% Change device units to Watts
dev.Write('CALC:UNIT W')
grab_avg_time = datetime();
grab_avg = [];
hPlot = plot(NaN, NaN, '--*');
while (1)
grab_avg= strsplit((string(dev.Query('FETC1:ARR:CW:POW?'))),','); %Fetch data from PM and convert to string
pause(2)
grab_avg = str2double(grab_avg(2)) %Average Power - Convert String to Number and place in array
pause(0.5)
grab_avg_time = datetime('now');
pause(0.5)
xdata = [get(hPlot,'XData') grab_avg_time]; % update the x-data
ydata = [get(hPlot,'YData') grab_avg]; % update the y-data
set(hPlot,'XData',xdata,'YData',ydata);
hold on
end
hold off
% Update handles structure
guidata(hObject, handles);
Error:
Error using datetime/horzcat (line 1292)
All inputs must be datetimes or date/time character vectors or date/time strings.
Error in BasicGUI>pushbutton11_Callback (line 307)
xdata = [get(hPlot,'XData') grab_avg_time]; % update the x-data
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in BasicGUI (line 48)
gui_mainfcn(gui_State, varargin{:});
Error in matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)BasicGUI('pushbutton11_Callback',hObject,eventdata,guidata(hObject))
Error using BasicGUI>BasicGUI_OpeningFcn (line 83)
Error while evaluating UIControl Callback.
I modified the code slightly (shown below) to see if I would able to plot only the data obtained from the instrument continuously without errors.
%xdata = [get(hPlot,'XData') grab_avg_time]; % update the x-data
ydata = [get(hPlot,'YData') grab_avg]; % update the y-data
set(hPlot,'YData',ydata);
I got the following error:
grab_avg =
6.5460e-09
Warning: Error creating or updating Line
Error in value of one or more of the following properties: XData YData
Array is wrong shape or size
> In defaulterrorcallback (line 12)
In BasicGUI>pushbutton11_Callback (line 301)
In gui_mainfcn (line 95)
In BasicGUI (line 48)
In matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)BasicGUI('pushbutton11_Callback',hObject,eventdata,guidata(hObject))
The first error message might be because NaN is used to initialze the XData and so conflicts with the datetime that you are trying to add to the array (hence the error All inputs must be datetimes or date/time character vectors or date/time strings). You could possibly add a check like
hPlot = plot(NaN, NaN, '--*');
hasPlotBeenUpdated = false;
while (1)
grab_avg= strsplit((string(dev.Query('FETC1:ARR:CW:POW?'))),','); %Fetch data from PM and convert to string
pause(2)
grab_avg = str2double(grab_avg(2)) %Average Power - Convert String to Number and place in array
pause(0.5)
grab_avg_time = datetime('now');
pause(0.5)
if ~hasPlotBeenUpdated
hasPlotBeenUpdated = true;
set(hPlot,'XData',grab_avg_time,'YData',grab_avg);
else
xdata = [get(hPlot,'XData') grab_avg_time]; % update the x-data
ydata = [get(hPlot,'YData') grab_avg]; % update the y-data
set(hPlot, 'XData', xdata, 'YData', ydata);
end
end
though I suspect there are smarter (more efficient) ways to do this. You could grab the xData and check to see if the size is 1 and the first element is NaN (use isNaN perhaps?) but in the end, the result is the same: for the first iteration, just set the x- and y-data to be the data retrieved on that iteration. For every other iteration, update the existing x- and y-data.
I see that your while loop condition is always true. Is this intentional? How would you exit this loop?
Hey Geoff, Thanks again.
Per my while loop being always true, this is intentional for now. I am just trying to get the continuous plotting going. When I have the plotting going, I plan to have the while loop based on the push button (When depressed, run loop). I'm currently trying to figure out how I'll do that.
I modified the code again and got the following error:
grab_avg =
5.6750e-09
Error using matlab.graphics.chart.primitive.Line/set
Value must be a vector of numeric type
Error in BasicGUI>pushbutton11_Callback (line 310)
set(hPlot,'XData',grab_avg_time,'YData',grab_avg);
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in BasicGUI (line 48)
gui_mainfcn(gui_State, varargin{:});
Error in matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)BasicGUI('pushbutton11_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback.
Is the error because grab_avg_time is a datetime object? What are hoping to show along the x-axis? A string of the date? Could you convert it to a serial date number instead (with datenum)?
Not sure. I implemented a similar plot in another section of the code. The loop for this plot is a for loop that collects a certain amount of data and plots as such.
Please see the attached image. plot.JPG
maybe you need to do something like
set(hPlot,'XData',[grab_avg_time],'YData',[grab_avg]);
so that we now create a vector? Unfortunately, I don't have the datetime class in my version of MATLAB so do not know if the above will work.
Hey Geoff. Thanks. Just tried that option, but it didn't work. I'm in the process of trying to use datenum to see if it'll work.
Hey Geoff,
I used datenum and it worked with a few modifications! Thanks so much for all your help. I'm gonna go ahead and accept the answer.
Glad it worked out, George!
Hi Geoff,
Hope all is well.
Is there a way to plot two different variables on the same axes using the method you recommended. Every time I try, it combines the results into a single plot.
Please let me know.
Thanks.
Hi George,
Was wondering if you ever found a solution to plotting more than one variable on a single graph? I am working on something similar.
Thank you for sharing your work above!
Kindly,
Emma
Hi Emma - I think that you would need two plot objects
hPlot1 = plot(NaN, NaN, '--*);
hPlot2 = plot(NaN, NaN, '--.);
and then update the first and second plots with whatever data you want to plot on each.

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Graphics Performance in Centro assistenza e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by