Real time plotting - Matlab GUI
이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
이전 댓글 표시
0 개 추천
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);
채택된 답변
Geoff Hayes
2019년 2월 20일
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
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.
Geoff Hayes
2019년 2월 20일
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)?
George Diamond
2019년 2월 20일
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. 

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.
George Diamond
2019년 2월 20일
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.
George Diamond
2019년 2월 20일
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.
Geoff Hayes
2019년 2월 20일
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.
Emma Donnelly
2019년 11월 21일
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.
추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Graphics Performance에 대해 자세히 알아보기
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
