• MATLAB坐标区应用


    简介

           MATLAB的坐标区用于作为绘图区,绘制线段等,而当数据较多时,一般有3种选择以显示绘图:

    1. 舍去之前的数据,只绘制最后部分的数据:可以使图形比例不变
    2. 绘制所有数据:可以更好地看出数据总体趋势变化,但精确的点较难体现。

           第2种方式不用多说,plot函数会自动调整坐标轴的长度,因此通过plot函数不断绘制即可,第1种方式又可以分为两种,单向绘制和循环绘制,单向绘制即数据指按时间顺序从左到右绘制,此时最左边的数据会最先被舍去,数据从最右边添加。循环绘制即绘制到图的最右边后,从坐标区的最左边开始绘制。

    当然根据需求可能会有其它选择。

           下面介绍循环绘制和绘制所有数据,两种绘制方法的MATLAB程序设计。

    图形文件

           创建1个简单的.fig文件,只有两个控件,按钮用来启动绘图,坐标区用来显示绘图。
    在这里插入图片描述

    程序编写

           假设图形文件名为Draw.fig,那么对应放置各种回调函数的文件为Draw.m文件,此时除了这两个文件,我们还需要编写1个图形绘制文件Graph.m(当然,名字随意起),该文件为函数文件,用于被定时器调用时进行图形绘制(定时器下面会介绍怎么使用)。该文件的参数除了图形控件必须的参数handles外,应增加1个数据参数,传入需要绘制的数据。当然,一般不会将其设为函数的参数,而是将其设置为全局变量,方便数据的传入和使用。

    注:本程序需要绘制的数据为已准备好的数据,因此通过定时器定时绘制。若需要绘制的数据为不定时传入的,可以取消定时器,转而每传入相应数量的数据,绘制1次。

    Draw.m文件编写

           首先将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);  %数组初始化
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    注意,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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

           最后,建议在整个UI界面的DeleteFcn函数中添加定时器的删除函数,如下所示:

    function figure1_DeleteFcn(hObject, eventdata, handles)
    global gPlayTimer;
    
    switch get(gPlayTimer, 'Running')
        case 'on'
            stop(gPlayTimer); % 如果定时器打开,则关闭定时器
    end
    delete(gPlayTimer); % 删除定时器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Graph.m

           在当前文件夹中添加函数文件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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    保留绘制

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行

           将Draw.m和Graph.m两个文件对应加上上述代码即可实现不同坐标区的绘制,当然,一般这种数据都是外部定时或不定时输入。根据该工程,定义全局变量Data_All,适当修改少量代码,应该就可以运行了。

           刚开始绘制时,纵坐标轴的值会不断变化,则是由于坐标轴在适应绘制曲线的最大纵坐标,如果觉得绘制太慢了,可以将定时器周期调小一点(最小0.001)或者将每次显示的数据增多,本工程每次只显示1个。

  • 相关阅读:
    传统运维与云运维到底有什么不同呢?
    初中数学三角函数
    安全架构中的前端安全防护研究
    关系数据库:mysql
    Python21天学习挑战赛Day(8)·pdfplumber读取PDF写入Excel(应用)
    golang学习笔记系列之go语言的环境搭建(linux系统下)
    后端程序员入门react笔记(八)-redux的使用和项目搭建
    blender怎么设置中文界面
    Spring Boot EasyPOI 使用指定模板导出Excel
    Java导出请求头
  • 原文地址:https://blog.csdn.net/weixin_47447179/article/details/126301603