在Matlab GUIDE中实时绘制多条曲线
Plotting several curves in Matlab GUIDE in real time
我需要使用 MATLAB GUIDE 在同一轴上实时绘制 2 个变量。现在我成功地为每个子图绘制了 1 个变量。
为了做到这一点,我在 _OpeningFcn 中创建了一个计时器和 2 个 handles.plot:
handles.timer = timer(...
'ExecutionMode', 'fixedRate', ... % Run timer repeatedly
'Period', 1, ... % Initial period is 1 sec.
'TimerFcn', {@update_display,hObject}); % Specify callback function
handles.subplot=subplot(2,1,1,'Parent',handles.uipanel3);
handles.subplot1=subplot(2,1,2,'Parent',handles.uipanel3);
handles.plot = plot(handles.subplot,0,0,'b');
handles.plot1 = plot(handles.subplot1,0,0,'r');
然后,在函数 update_display 中,我将最后的值与前面的值连接起来,如下所示:
x = get(handles.plot,'XData');
x = [x, x(length(x))+1]; % (time=1sec)
y = get(handles.plot,'YData');
y = [y, yf]; % A/D value = yf
set(handles.plot,'XData',x);
set(handles.plot,'YData',y);
e = get(handles.plot1,'YData');
e = [e, error];
set(handles.plot1,'XData',x);
set(handles.plot1,'YData',e);
我想做的是在同一张图中绘制这两个变量。我想也许我应该用 handles.plot_parent 和 'Parent' handles.uipanel3 来改变 handles.subplot,但是我在配置它时遇到了麻烦,因为我不确定它是哪个参数期待。
感谢您的建议。
最好的开始可能是清除 plot/subplot/axes/figure 等之间的混淆...
- 一个
figure
是一个"window"。图形 object,使用类似命名的命令 figure
. 创建
- 一个
axes
也是一个图形对象。它是一个 容器,可以包含各种其他低级图形对象,如 lines
、surfaces
、patches
等...
它可以包含不止一种类型的多个子对象。它可以使用命令 axes
或像使用 subplot
一样创建。 subplot
的特殊性在于它可以让您轻松地在一张图中放置多个 axes
。如果只打算在图中创建单个axes
,则不需要调用subplot,直接调用axes
. 即可
line
是基本的线条图形对象。可以修改属性以显示一条连续的线(具有不同的样式),有或没有标记,甚至只有标记,不一定 "joined" 一行。命令 plot
确实使用您在输入中提供的参数创建了一个 line
对象。
解决了这个问题,让我们来解决您的问题:
根据你的评论,我知道你想要你所有的情节(你的lines
),在同一个"subplot"(例如:在同一个axes
)。
你就快完成了,你只需要在你的打开函数中定义一个axes
,然后修改这个axes
的属性,这样它就可以接受多行(通过默认每一个新行都会删除现有的一行)。之后你像你一样初始化你的行,然后在更新函数中更新它们。
所以在实践中:
将计时器定义下的代码替换为:
handles.axe = axes('Parent',handles.uipanel3,'NextPlot','Add'); %// c reate an "axes" object which can accept multiple plots
handles.plot0 = plot( handles.axe , 0,0 , 'b' ); %// create empty line in the axes "handles.axe"
handles.plot1 = plot( handles.axe , 0,0 , 'r' ); %// create empty line in the axes "handles.axe"
然后在你的更新函数中:
%// update your first line
y = get(handles.plot0,'YData');
y = [y, yf]; %// A/D value = yf
x = 0:numel(y)-1 ; %// This will create a vector [0 1 2 3 ...] the same size as "y"
set(handles.plot0,'XData',x , 'YData',y ); %// you can set both XData and YData in the same instruction
%// update your second line
e = [ get(handles.plot1,'YData') error ] ; %// you can concatenate the new value directly with the old data
set(handles.plot1,'XData',x ,'YData',e );
我冒昧地稍微改变了你的更新功能,只是为了向你展示一些其他的做事方式。如果你想坚持下去,你最初的方法应该很好用。真正的诀窍是在同一个 axes
对象中创建 2 个初始行。
我需要使用 MATLAB GUIDE 在同一轴上实时绘制 2 个变量。现在我成功地为每个子图绘制了 1 个变量。
为了做到这一点,我在 _OpeningFcn 中创建了一个计时器和 2 个 handles.plot:
handles.timer = timer(...
'ExecutionMode', 'fixedRate', ... % Run timer repeatedly
'Period', 1, ... % Initial period is 1 sec.
'TimerFcn', {@update_display,hObject}); % Specify callback function
handles.subplot=subplot(2,1,1,'Parent',handles.uipanel3);
handles.subplot1=subplot(2,1,2,'Parent',handles.uipanel3);
handles.plot = plot(handles.subplot,0,0,'b');
handles.plot1 = plot(handles.subplot1,0,0,'r');
然后,在函数 update_display 中,我将最后的值与前面的值连接起来,如下所示:
x = get(handles.plot,'XData');
x = [x, x(length(x))+1]; % (time=1sec)
y = get(handles.plot,'YData');
y = [y, yf]; % A/D value = yf
set(handles.plot,'XData',x);
set(handles.plot,'YData',y);
e = get(handles.plot1,'YData');
e = [e, error];
set(handles.plot1,'XData',x);
set(handles.plot1,'YData',e);
我想做的是在同一张图中绘制这两个变量。我想也许我应该用 handles.plot_parent 和 'Parent' handles.uipanel3 来改变 handles.subplot,但是我在配置它时遇到了麻烦,因为我不确定它是哪个参数期待。
感谢您的建议。
最好的开始可能是清除 plot/subplot/axes/figure 等之间的混淆...
- 一个
figure
是一个"window"。图形 object,使用类似命名的命令figure
. 创建
- 一个
axes
也是一个图形对象。它是一个 容器,可以包含各种其他低级图形对象,如lines
、surfaces
、patches
等... 它可以包含不止一种类型的多个子对象。它可以使用命令axes
或像使用subplot
一样创建。subplot
的特殊性在于它可以让您轻松地在一张图中放置多个axes
。如果只打算在图中创建单个axes
,则不需要调用subplot,直接调用axes
. 即可
line
是基本的线条图形对象。可以修改属性以显示一条连续的线(具有不同的样式),有或没有标记,甚至只有标记,不一定 "joined" 一行。命令plot
确实使用您在输入中提供的参数创建了一个line
对象。
解决了这个问题,让我们来解决您的问题:
根据你的评论,我知道你想要你所有的情节(你的lines
),在同一个"subplot"(例如:在同一个axes
)。
你就快完成了,你只需要在你的打开函数中定义一个axes
,然后修改这个axes
的属性,这样它就可以接受多行(通过默认每一个新行都会删除现有的一行)。之后你像你一样初始化你的行,然后在更新函数中更新它们。
所以在实践中:
将计时器定义下的代码替换为:
handles.axe = axes('Parent',handles.uipanel3,'NextPlot','Add'); %// c reate an "axes" object which can accept multiple plots
handles.plot0 = plot( handles.axe , 0,0 , 'b' ); %// create empty line in the axes "handles.axe"
handles.plot1 = plot( handles.axe , 0,0 , 'r' ); %// create empty line in the axes "handles.axe"
然后在你的更新函数中:
%// update your first line
y = get(handles.plot0,'YData');
y = [y, yf]; %// A/D value = yf
x = 0:numel(y)-1 ; %// This will create a vector [0 1 2 3 ...] the same size as "y"
set(handles.plot0,'XData',x , 'YData',y ); %// you can set both XData and YData in the same instruction
%// update your second line
e = [ get(handles.plot1,'YData') error ] ; %// you can concatenate the new value directly with the old data
set(handles.plot1,'XData',x ,'YData',e );
我冒昧地稍微改变了你的更新功能,只是为了向你展示一些其他的做事方式。如果你想坚持下去,你最初的方法应该很好用。真正的诀窍是在同一个 axes
对象中创建 2 个初始行。