MATLAB的坐标区用于作为绘图区,绘制线段等,而当数据较多时,一般有3种选择以显示绘图:
第2种方式不用多说,plot函数会自动调整坐标轴的长度,因此通过plot函数不断绘制即可,第1种方式又可以分为两种,单向绘制和循环绘制,单向绘制即数据指按时间顺序从左到右绘制,此时最左边的数据会最先被舍去,数据从最右边添加。循环绘制即绘制到图的最右边后,从坐标区的最左边开始绘制。
当然根据需求可能会有其它选择。
下面介绍循环绘制和绘制所有数据,两种绘制方法的MATLAB程序设计。
创建1个简单的.fig文件,只有两个控件,按钮用来启动绘图,坐标区用来显示绘图。

假设图形文件名为Draw.fig,那么对应放置各种回调函数的文件为Draw.m文件,此时除了这两个文件,我们还需要编写1个图形绘制文件Graph.m(当然,名字随意起),该文件为函数文件,用于被定时器调用时进行图形绘制(定时器下面会介绍怎么使用)。该文件的参数除了图形控件必须的参数handles外,应增加1个数据参数,传入需要绘制的数据。当然,一般不会将其设为函数的参数,而是将其设置为全局变量,方便数据的传入和使用。
注:本程序需要绘制的数据为已准备好的数据,因此通过定时器定时绘制。若需要绘制的数据为不定时传入的,可以取消定时器,转而每传入相应数量的数据,绘制1次。
首先将Draw_OpeningFcn函数修改为以下所示,主要是将Graph函数设置为定时器回调函数,以及准备好数据。
function Draw_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
global gPlayTimer; %定时器变量,点击按钮后打开定时器启动绘制
global gDataCnt; %计数器,存储绘制线段的x坐标
global Data_Draw; %存放已绘制的数据
global Data_All; %存放所有数据(即已准备好的数据)
global MAX_DATA_LEN; %可绘制的最大数据数目
gPlayTimer = timer('TimerFcn', {@Graph, handles}, 'Period', 0.01,...
'ExecutionMode', 'fixedDelay'); % 创建一个定时器对象,周期为10ms
gDataCnt=1;
x_sin = 0:0.01:10*pi;
Data_All=sin(x_sin); %准备好的数据
MAX_DATA_LEN = length(x_sin);
Data_Draw= NaN(1, MAX_DATA_LEN); %数组初始化
注意,MATLAB最低周期为0.001s,即1ms,但实际上误差比较大,一般将周期设置为0.009时周期约为10ms,可能与电脑有关。
其次,编写按钮的回调函数,用于开关定时器:
function pushbutton1_Callback(hObject, eventdata, handles)
global gPlayTimer;
switch get(gPlayTimer, 'Running') %获取定时器状态
case 'off'
start(gPlayTimer); % 如果定时器关闭,则打开定时器
case 'on'
stop(gPlayTimer); % 如果定时器开启,则关闭定时器
end
最后,建议在整个UI界面的DeleteFcn函数中添加定时器的删除函数,如下所示:
function figure1_DeleteFcn(hObject, eventdata, handles)
global gPlayTimer;
switch get(gPlayTimer, 'Running')
case 'on'
stop(gPlayTimer); % 如果定时器打开,则关闭定时器
end
delete(gPlayTimer); % 删除定时器
在当前文件夹中添加函数文件Graph.m,并对应加入下面的代码即可。
function Graph(~,~,handles)
global gDataCnt; % 计数器
global Data_Draw;
global Data_All;
global MAX_DATA_LEN;
Data_Draw(gDataCnt) = Data_All(gDataCnt); %定时器每调用1次,获取1个数据
xLeft = 1 : gDataCnt; % 左半部分波形的横坐标
xRight = gDataCnt + 10 : MAX_DATA_LEN; % 右半部的波形的横坐标,有10个数据的间距
yLeft = Data_Draw(xLeft); % 左半部分波形的纵坐标
yRight = Data_Draw(xRight); % 右半部分波形的纵坐标
% 绘制波形
plot(handles.axes1, xLeft, yLeft, xRight, yRight);
% 设置横坐标
set(handles.axes1, 'XLim', [1 MAX_DATA_LEN]);
drawnow; % 刷新屏幕
gDataCnt = gDataCnt + 1;
if (gDataCnt > MAX_DATA_LEN) % 循环绘制的重点,绘制完后,绘制位置变为最前
gDataCnt = gDataCnt - MAX_DATA_LEN;
end
function Graph(~,~,handles)
global gDataCnt; % 计数器
global Data_All;
global MAX_DATA_LEN;
persistent y; %y用于绘制曲线(类似Data_Draw,这里定义为静态变量防止被覆盖,不使用Data_Draw是因为该变量(数组)大小固定了)
x = 1 : gDataCnt; % 波形的横坐标
y(gDataCnt) = Data_All(mod(gDataCnt,MAX_DATA_LEN)+1); %+1:防止取余为0,导致数据索引出错
% 绘制波形
plot(handles.axes1, x, y);
% 设置横坐标
set(handles.axes1, 'XLim', [1 gDataCnt+10]);
drawnow; % 刷新屏幕
gDataCnt = gDataCnt + 1;
将Draw.m和Graph.m两个文件对应加上上述代码即可实现不同坐标区的绘制,当然,一般这种数据都是外部定时或不定时输入。根据该工程,定义全局变量Data_All,适当修改少量代码,应该就可以运行了。
刚开始绘制时,纵坐标轴的值会不断变化,则是由于坐标轴在适应绘制曲线的最大纵坐标,如果觉得绘制太慢了,可以将定时器周期调小一点(最小0.001)或者将每次显示的数据增多,本工程每次只显示1个。