• 【MATLAB】根据已有数据绘制Bode图、时域曲线等(进阶版)


    前期教程

      建议查看上面的专栏。

    前言

      最近上了一个自控相关的实验,因为打印需要,报告里面的图片不能用实验过程中保存的图片(黑色背景,而且样式复古),因此想到使用MATLAB来实现,因此研究了一下进阶版的MATLAB绘图,收获颇多,记录一下。

    读取数据

      既然要根据已有数据绘图,那么如何有效读取数据就成为非常重要的一步。我这个实验保存的数据是txt格式,于是找到这个链接,记录的方法比较全面,具体使用方法建议去啃help文档。
      本实验记录的数据格式是类似于表格的形式,但是上面还有题头,如下图所示。
    在这里插入图片描述
    在这里插入图片描述

      一个行之有效的方法是在MATLAB中选择导入数据,然后选择对应的txt文件,然后有选择性地只导入数据部分,但是这样有一个很大的缺点,那就是非常慢!!! 毕竟,我这实验有近50个数据文件呢。。。
      因此,使用代码实现势在必行!由于文件中中英文混杂,还有题头等数据的干扰,只有部分数据是表格形式的有效数据,于是采用的是textscan函数,这里介绍两种方式。

    方法一:按行读取

      这种方法适用于上面第二张图,数据是根据时间顺序按行写入的,因此可以按照读取文件的方式来读取。

    fID = fopen(filename, 'r');   %以读取的方式打开文件,返回文件ID
    data_cell = textscan(fID,'%s','CommentStyle','\n');  %以忽略回车的方式读取文本文件中的数据,cell格式
    fclose(fID);  %及时关闭文件,以免产生后患
    
    • 1
    • 2
    • 3

    这种方式巧妙之处在于,这个函数恰好可以将同一行的数据分开,最后得到的就是一个一个数据,只是需要将“3.478伏”变成数据3.478即可。具体实现是采用sscanf函数:

    value(i) = sscanf(A{i}, "%f%*s"); %A为cell数组,读取到的浮点数返回到value中
    
    • 1

    其中用%*s表示读取一个字符串但忽略,不输出,这种操作非常好用。

    方法二:按列读取

      除了根据时间顺序按行写入的数据文件,还有按列写入的数据(tmd。。。),不能直接套用上面的方法,而是需要先整体读入数据,得到一个矩阵(二维数组),然后将其按列组合成一个向量。因此textscan得换一种应用方式:

    fID = fopen(filename, 'r'); %需要注意,这个数据是按列写入的,所以要进行后续处理
    data_cell = textscan(fID,'%s','Delimiter','\n'); %按换行符划分,先分行
    fclose(fID);
    d = data_cell{1};
    
    • 1
    • 2
    • 3
    • 4

    得到数据之后去掉题头部分,剩下的部分仍然使用sscanf函数进行数据提取:

    value(i) = sscanf(D{i}, '%*s%*s%d');
    
    • 1

    这里还需要注意,不要认为只有一个字符就可以使用%*c,建议优先考虑%*s,因为读取字符是可以读取空格的!!!

    设置figure属性

      一般来说,我们使用MATLAB绘图,就是直接复制图窗,顶多是点开属性栏简单设置一下属性,但是如果图片较多的话,逐个设置就会很麻烦,使用代码来设置才是最佳选项
      在MATLAB中,每次绘制的曲线图像实际上就是一个对象,它具有非常多的属性,于是可以通过代码来修改这个对象的属性。这里用到的对象主要有两个:

    • gcf:Figure对象,主要用于设置那个figure窗口的属性。
    • gca:axes对象,主要用于设置坐标轴相关的属性。

      下面简单介绍常用的两种设置。

    自定义横纵坐标刻度

      有时候画图时,我们想要看到一些特定值对应曲线函数值是多少,但是由于默认的自动坐标没有显示该值,那么就可以通过设定刻度来实现特定函数值的观察。方法如下。

    x=1:10;
    set(gca, 'xtick', x);
    
    • 1
    • 2

    或者对于R2014b之后的版本,可以这样:

    ax = gca;
    ax.XTick = 1:10;
    
    • 1
    • 2

    即以直接赋值的方式设置相关的参数。

    使横坐标按对数刻度显示,即Bode图的形式

      一般我们绘制系统的Bode图,都是直接使用bode命令,即必须先要有一个系统。但实际上如果有现成的数据,也可以快速绘制Bode图,方法就是按照正常的函数绘图,使用plot函数,然后再将横坐标调整为对数显示。方法如下。

    set(gca,'xscale', 'log')
    
    • 1

    或者新版本可以用直接赋值的方式进行参数修改。

    去掉复制的图片的空白边距

      相信很多人都会有这样的体验:使用MATLAB绘图后直接选择复制图窗,然后粘在word里面,但是发现图片周围有一圈白边,还需要再次裁剪一下。如果是一两张图片倒是影响不大,但如果是多张图片,那再一张一张裁剪就吃不消了,所以最好的办法是使用代码使得复制的图片就没有空白边距
      其实这个边距的宽度也是图像属性中的一部分,打开属性栏,搜索position,就可以找到对应的属性。
    在这里插入图片描述

    可以看到它是由四个数字组成的数组,分别表示x, y, width, height,可以手动调整图片的宽度,然后复制得到的数据,然后粘贴到设置的代码中:

    x = [0.0957,0.1105,0.8886,0.8781];
    set(gca,'position',x)
    
    • 1
    • 2

    在同一个figure中画不同的图——plotyy

      有时候为了对比两个函数曲线,会将两个函数曲线绘制在同一张图内,比如Bode图的幅频特性曲线和相频特性曲线。

    plotyy(x,y1,x,z1);
    
    • 1

    效果如下图所示
    在这里插入图片描述

    补充:WORD转PDF时MATLAB图片失真

      问题描述:将word转pdf时,发现粘贴的MATLAB的图片出现了失真,具体表现为legend错位,字体变小等。
      解决办法:不要直接使用另存为,而是使用Adobe的打印。

  • 相关阅读:
    大数据时代下统计数据质量的控制方法
    十三、【分布式微服务企业快速架构】SpringCloud分布式、微服务、云架构之Eclipse 创建 XML 文件
    Node.js的多版本管理工具 gnvm(win环境)的详细安装教程(图解步骤、通俗易懂、亲测有效)
    【科技素养】蓝桥杯STEMA 科技素养组模拟练习试卷E
    实战 Creator 2.x 项目升级 3.x!避坑要点与基础 API 写法差异总结
    苹果电脑专业的条形码工具iBarcoder:助力高效条形码生成,提升工作效率
    红细胞膜包被雷公藤甲素-红素仿生共载脂质体/双重细胞膜包裹负载siEFNA1蛋黄脂质纳米制备
    H5游戏分享-全民找房祖名qmxzfzm
    java Suspicious regex expression "." in call to 'replaceAll()' 问题延展
    深度解读DBSCAN聚类算法:技术与实战全解析
  • 原文地址:https://blog.csdn.net/ZHOU_YONG915/article/details/126673259