MATLAB技巧之绘图篇

MATLAB技巧之绘图篇

0 前言

编程方面我最早接触的是C,然后是C++、C#等,都是用于实现工程项目类的任务,但目前自己用得多的还是MATLAB。因为其数学计算方面功能相当强大,实现及验证算法非常便利,同时具有非常强的编程和结果的可视化功能。本篇就常用的绘图功能进行总结。

内容安排如下:

  • 1、基本绘制
  • (图画大小、图形名称、图画背景、坐标轴名称、刻度范围、曲线颜色、坐标轴字体颜色等)
  • 2、多条曲线
  • (plot hold on;plotyy;subplot;)
  • 3、日期及时间轴绘图
  • 4、区域填充绘制
  • 5、不连续段落绘制

1 基本绘制

想使用MATLAB绘制想要的图像,无非是搞懂各部分参数设置的方法,其实很多方法是通用的,图1为典型的曲线图,不妨先整理几个概念:

包含关系如下:

1)图像figure

figure就是指一个图像对话框,

gcf——get current figure,获取当前图形句柄,如果不存在图形,则创建新的图形。

用法:

①设置布画大小

set(gcf,'unit','centimeters','position',[10 5 14 7]);

②设置布画颜色

fig = gcf; % current figure handle
fig.Color = [0 0.5 0.5];
fig.ToolBar = 'none';

2)坐标轴axes/axis

axes——在指定位置建立轴坐标

axis——完成axes坐标轴设置,传回坐标轴句柄。

gca——get current axis or chart,获取当前图形坐标句柄,可用于设置坐标轴标注格式。

用法示例:

①建立新的轴坐标

axes('Color',[0 0 0], 'ZColor',[0 0.5 0], 'XColor',[0 0.5 0], 'YColor',[0 0.5 0]);

②设置同一坐标内两条曲线句柄

[hAx,hLine1,hLine2] = plotyy(x,y1,x,y2);
ylabel(hAx(1),'Slow Decay') % left y-axis 
ylabel(hAx(2),'Fast Decay') % right y-axis

③获取axis子项句柄设置属性

set(get(gca,'XLabel'),'FontSize',figure_FontSize,'Vertical','top');
ax = gca; % current axes
ax.FontSize = 12;
ax.TickDir = 'out';
ax.TickLength = [0.02 0.02];
ax.YLim = [-2 2];

3)数据标注

legend——为图形或坐标轴添加数据标注。

用法示例:

y1 = rand(3);
ax1 = subplot(2,1,1); 
plot(y1)
legend(ax1,'Line 1','Line 2','Line 3')

以下为一段完整的代码,供参考。

x = 0:pi/100:2*pi;
y1 = sin(x);
y2 = sin(x-0.25);
y3 = sin(x-0.5);

% 新建图画,若figure(1)即指定图画句柄1
figure;
% 设置布画大小,合适的大小可防止粘贴到word文档时图片模糊
set(gcf,'unit','centimeters','position',[10 5 14 7]);
% 设置布画背景色
set(gcf,'Color',[0.9 0.9 0.9]);
% 绘制曲线,绘制多条曲线时可使用下列方法,也可用hold on
% hold on 在曲线实时逐点更新绘制时比较好用
plot(x,y1,x,y2,'--',x,y3,':');
% 设置坐标轴范围,等效于xlim、ylim
axis([0 2*pi -1.5 1.5]);

% 设置坐标格
grid on;
% 曲线标注,设置标注位置及排列方法,注意上标下标、及转义字符的使用
legend('曲线_1','曲线^2','曲线\_3','Location','northeast','Orientation','vertical');
% 更广泛的,matlab绘图中支持latex公式,例如
% legend('\itu_{max}','\itu','\itu_{maxt}');
% 设置坐标轴标注,设置坐标轴字体
figure_FontSize=8;
xlabel('时间(s)','FontSize',figure_FontSize,'FontWeight','bold','Color','r');
ylabel('幅值');
% 有的老版本的MATLAB设置字体只能通过以下方式生效
set(get(gca,'XLabel'),'FontSize',figure_FontSize,'Vertical','top');
set(get(gca,'YLabel'),'FontSize',figure_FontSize,'Vertical','middle');
% 批量设置字体格式
set(findobj('FontSize',10),'FontSize',figure_FontSize);
% 设置xy轴在图片中占的比例,可能需要自己微调。
set(gca,'Position',[.13 .17 .80 .74]);
% 批量设置曲线粗细
set(findobj(get(gca,'Children'),'LineWidth',0.5),'LineWidth',2);
% 设置标题
title('sin函数示例图');

2 多条曲线绘制

根据不同表达需求,多条曲线绘制大致可以分以下几类:

1)一个轴坐标里同时绘制多条曲线,适用于多条取值范围相近曲线的比对分析。

x = 0:pi/100:2*pi;
y1 = sin(x);
y2 = sin(x-0.25);
y3 = sin(x-0.5);
plot(x,y1,x,y2,'--',x,y3,':');

等同于:

plot(x,y1);hold on;
plot(x,y2,'--');hold on;
plot(x,y3,':');hold on;

这里有个小技巧,若只想比对y1、y2、y3,不在意x轴,则可用多维数据方式绘图:

plot([y1' y2' y3']);

注意,数组需按列排列n*3

2)一个图形里同时绘制两个轴坐标,适用于取值范围差异较大曲线的趋势比对分析。这里其实也是可以绘制三条以上曲线的,但纵坐标轴只有左右两个,多的曲线只能看趋势了。

x = 0:0.01:20;
y1 = 200*exp(-0.05*x).*sin(x);
y2 = 0.8*exp(-0.5*x).*sin(10*x);

figure % new figure
[hAx,hLine1,hLine2] = plotyy(x,y1,x,y2);

title('Multiple Decay Rates')
xlabel('Time (\musec)')

% 设置曲线样式
hLine1.LineStyle = '--';
hLine2.LineStyle = ':';

% 设置左右坐标轴
ylabel(hAx(1),'Slow Decay') % left y-axis 
ylabel(hAx(2),'Fast Decay') % right y-axis

3)一个图画figure里多个轴坐标,适用于一个系列的分图显示,写报告时可用,但写论文时大多要求子图也要有题注,具体使用的话自己取舍啦。

subplot(2,2,1);
x = linspace(-3.8,3.8);
y_cos = cos(x);
plot(x,y_cos);
title('Subplot 1: Cosine')

subplot(2,2,2);
y_poly = 1 - x.^2./2 + x.^4./24;
plot(x,y_poly,'g');
title('Subplot 2: Polynomial')

subplot(2,2,[3,4]);
plot(x,y_cos,'b',x,y_poly,'g');
title('Subplot 3 and 4: Both')

3 日期及时间轴绘制

日期及时间轴的绘制很多场合下会遇到,这里主要用到两个函数:datenum和dateaxis。

1)datenum——将指定格式的日期或时间转换为时间序列数据。

datenum可将字符串转为double

DateString = {'09/16/2007';'05/14/1996';'11/29/2010'};
formatIn = 'mm/dd/yyyy';
datenum(DateString,formatIn)

也可将数组类数据转换为时间序列

DateNumber = datenum(Y,M,D)
DateNumber = datenum(Y,M,D,H,MN,S)

mData = load('datedata.txt');
tDate = datenum(mData(:,1:6)); 
plot(tDate,mData(:,7));
dateaxis('x',13);

2)dateaxis——将坐标轴刻度显示为指定格式

dateaxis(Tickaxis,DateForm,StartDate)

以下为从文件中读取当天绝对秒,绘制时间轴图形示例:

% 读取数据文件,第一列为当天绝对秒,第二列为数值
mData = load('exampleTime.txt');
% 设置一个其实日期点
dt0 = datenum('2019-11-16');
% 计算当天时间
mT = dt0 + mData(:,1)/3600;
% 绘图
plot(mT,mData(:,2));
dateaxis('x',13);
ylabel('幅值');
% 防止横坐标过于密集,调整标注角度
set(gca,'XTickLabelRotation',-45);
% 设置背景和曲线风格
set(gca,'Color',[0 0 0],'XColor',[0 0.5 0],'YColor',[0 0.5 0]);

4 区域填充绘制

区域填充图可以表达更形象丰富的数据,绘制函数为fill。

fill(X,Y,ColorSpec)

这里只需理解一下fill的工作方式,即沿着描述路径填充中间闭合区间,路径的描述通过(X,Y)指定的一系列点来标识,一下给出一个误差范围的绘图示例:

x = 0:0.01:40;
y = x.^2.*sin(x)+cos(x);   % 某序列值
stdY = std(y);           % y的标准差
y_up = y+3*stdY;       % y的上限值
y_low = y-3*stdY;       % y的下限值

figure;
% 先绘制曲线
plot(x,y,'r-','LineWidth',2);hold on;
% 设置绘制路线
yForFill=[y_up,fliplr(y_low)];
xForFill=[x,fliplr(x)];
% 填充并设置图形格式
fill(xForFill,yForFill,'c','FaceAlpha',0.5,'EdgeAlpha',1,'EdgeColor','c'); 

5 不连续段落绘制

遇到不连续段落时,绘图通常会因为中断而出现不想要的连线,此时可将X轴补充完整,y轴缺失段落值设为NaN,绘图时中断数据自然跳过了。以下为示例代码:

x = 0:pi/100:2*pi;
y = sin(x);

% 产生缺失数据
omX = x;
omY = y;
NaNY = y;
% 剔除50至100的数据
omX(50:100) = [];
omY(50:100) = [];
% 将50至100至为无意义数据
NaNY(50:100) = NaN;

% 画出比对效果图
figure;
subplot(2,1,1);plot(omX,omY);
subplot(2,1,2);plot(x,NaNY);

参考文献

发布于 2019-11-17

文章被以下专栏收录