平台:Win7 64 bit,Matlab R2014a(8.3)
Matlab绘图功能强大,本文以“图解Matlab绘图”的形式介绍Matlab绘图的常用元素。
1.以图识图
在Matlab中新建一个矩阵,在左侧工作区窗口中选中这个变量,点击菜单“绘图”,即可以查看Matlab的各种图形:
点击“显示更多”小箭头:
点击左下角“目录”按钮:
从这里可以看到所有Matlab的图形。另外,从Matlab R2014a帮助文档的“Types of MATLAB Plots”(搜索即可)中也可以看到Matlab支持的所有图形。我的另一篇博文也总结了Matlab的所有绘图函数——Matlab绘图函数一览。
这里想说的是,数据可视化的目的本来就是让人易于理解数据,学习Matlab绘图也是这样,应该以一种直观的、图形的、易于理解的方式进行(本文努力做到这点)。其实,如果只是要用Matlab绘图,并非要系统掌握Matlab绘图相关语法,只需要了解各个绘图函数的输入数据格式,其他的如坐标轴控制、注解、颜色图等都可以通过在窗口中进行图形界面上的操作进行,毕竟,没有必要把时间浪费在记忆大量的语法上。
2.输入数据格式
Matlab面向数学处理,输入数据格式也是数学风格的,比如对于平面上的点集(点数组),Matlab用两个一维数组来表示:x,y,这样第i个点的坐标就是(x(i),y(i))。这对于程序员来说可能有些不适应,因为面向对象程序设计思想要求封装性,也就是要将一个点的x,y坐标放在一起构成Class“点”,然后用“点”这个类型来声明数组。所以在使用Matlab绘图功能时最好尽量用数学的思维方式,而不是编程思维。
要查看绘图函数的调用格式,请用“help xxx”指令,下面是一个例子:
在说具体数据格式之前,先要说一下“采样”和“插值”。这里说的Matlab绘图,很多是要绘制连续函数的图像,计算机存储空间有限,连续(无限)的定义域要被“采样”或者说“离散化”之后才能处理,而在绘制时,为了显示连续的的曲线或曲面,而不是仅仅绘制一系列点,需要进行“插值”,最常见的插值就是线性插值。其实,“采样”和“插值”的概念在计算机科学中有广泛的存在。
下面以最常见的几个绘图函数为例,介绍Matlab绘图函数的输入数据格式:
Function |
Syntax |
描述 |
plot |
plot(X,Y) plot(X,Y,LineSpec) plot(X1,Y1,...,Xn,Yn) plot(X1,Y1,LineSpec1,...,Xn,Yn,LineSpecn) plot(Y) plot(Y,LineSpec) plot(___,Name,Value) plot(axes_handle,___) h = plot(___) |
若X,Y均为向量,则点(X(i),Y(i))作为第i个被绘制的点,根据格式控制的不同,相邻点间可能被插值(连一条直线段); 若X,Y为尺寸相同的矩阵,X(:,i),Y(:,i)被绘制为一条曲线,默认不同曲线将有不同颜色; 若X被省略,则相当于X=1:n,n为点数。 |
bar |
bar(Y) bar(x,Y) bar(___,width) bar(___,style) bar(___,bar_color) bar(___,Name,Value) bar(axes_handle,___) h = bar(___) |
在x(i)处绘制一组(grouped)或一条堆叠(stacked)的条形,条形高度由Y(i,:)指定; 若x被省略,则相当于x=1:n,n为Y的行数。 |
scatter |
scatter(X,Y) scatter(X,Y,S) scatter(X,Y,S,C) scatter(___,'fill') scatter(___,markertype) scatter(___,Name,Value) scatter(axes_handle,___) h = scatter(___) |
对每个点(X(i),Y(i)),绘制一个圆圈; 若S是向量,圆圈大小由S(i)指定,若S是标量,由S指定; 若C是向量,圆圈的颜色由C(i)对应的颜色组成,若C是矩阵,由C(i,1:3)指定RGB颜色值。 |
contour |
contour(X,Y,Z) contour(Z) contour(…,n) contour(…,v) contour(...,LineSpec) contour(axes_handle,...) [C,h] = contour(...) |
Z为MxN的二维数组,若X,Y也是MxN二维数组,则Z(i,j)=F(X(i,j),Y(i,j)),若X,Y是向量,则Z(i,j)=F(X(j),Y(i))(即把X,Y看做列向量),F为二维函数; 若X,Y被省略,则相当于X=1:N,Y=1:M; 标量n设定等值线条数; 单调递增向量v设定等值线的值。 |
surf |
surf(X,Y,Z) surf(Z) surf(…,C) surf(...,'PropertyName',PropertyValue) surf(axes_handles,...) h = surf(...) |
Z为MxN的二维数组,若X,Y也是MxN二维数组,则Z(i,j)=F(X(i,j),Y(i,j)),若X,Y是向量,则Z(i,j)=F(X(j),Y(i))(即把X,Y看做列向量),F为二维函数; 若X,Y被省略,则相当于X=1:N,Y=1:M; C(i,j)的值对应到曲面上i,j点的颜色。 |
mesh |
mesh(X,Y,Z) mesh(Z) mesh(...,C) mesh(...,'PropertyName',PropertyValue,...) mesh(axes_handles,...) h = mesh(...) |
X,Y,Z,C的含义同surf。 注:对于向量x,y,可以用“[X,Y]=meshgrid(x,y)”构造二维数组X,Y,使得mesh(x,y,Z)和mesh(X,Y,Z)等价,也即有MxN个采样点,(X(i,j),Y(i,j))是索引为i,j的格点的x,y坐标。 |
slice |
slice(V,sx,sy,sz) slice(X,Y,Z,V,sx,sy,sz) slice(V,XI,YI,ZI) slice(X,Y,Z,V,XI,YI,ZI) slice(...,'method') slice(axes_handle,...) h = slice(...) |
V为MxNxP的三维数组,若X,Y也是MxNxPs三维数组,则V(i,j,k)=F(X(i,j,k,Y(i,j,k),Z(i,j,k)),若X,Y,Z是向量,则V(i,j,k)=F(X(j),Y(i),Z(k)) ,F为三维函数; 若X,Y,Z被省略,则相当于X=1:N,Y=1:M,Z=1:P; 向量sx,sy,sz指定垂直于x,y,z轴的切片位置; 矩阵XI,YI,ZI定义更复杂的切片(可能不是平面)。 |
coneplot |
coneplot(X,Y,Z,U,V,W,Cx,Cy,Cz) coneplot(U,V,W,Cx,Cy,Cz) coneplot(...,s) coneplot(...,color) coneplot(...,'quiver') coneplot(...,'method') coneplot(X,Y,Z,U,V,W,'nointerp') coneplot(axes_handle,...) h = coneplot(...) |
X,Y,Z,U,V,W都是MxNxP的三维数组,U(i,j,k)=Fu(X(i,j,k),Y(i,j,k),Z(i,j,k)),Fu为三维向量函数F的x分量,类似定义Fv,Fw; 若X,Y,Z被省略,则相当于[X,Y,Z]=meshgrid(1:N,1:M,1:P); Cx,Cy,Cz定义圆锥起点的x,y,z坐标; s定义缩放因子; color指定圆锥颜色; 'quiver'指定用箭头代替圆锥; 'method'在Cx,Cy,Cz指定点上的插值方法。 |
3.格式控制及注解
前面也说了,如果仅是要绘图,通过窗口操作这种“所见即所得”的方式不但可以快速生成美观的图形,而且节省大量时间,下面就首先来看看在Matlab的图形窗口如何进行图形格式控制。下面是Matlab的图形窗口:
Z=peaks;
surf(Z);
上图中已经可以对图形进行缩放、平移、旋转、拾取数据、刷亮、图形链接、插入颜色栏、插入图例等功能,通过在菜单中选择还可以添加光照、坐标轴标签等,点击上图中的红色箭头所指按钮后将显示更多绘图工具栏:
可以看到这已经是一个非常强大的编辑界面了,点击上图右下角按钮“更多属性…”,将看到:
这里可以进行更为全面的控制,很容易猜到,这里的项和指令代码有很好的对应。通过一番调整,且没有写任何代码,我的图已经变成如下样子(峰值数据是通过拾取工具得到的):
如果觉得格式调整的好,还可以将所有的设置和调整“打包”成代码,在图形窗口中点击菜单“文件 >> 生成代码…”即生成一个M函数文件,以后调用这个函数对新数据进行绘图时,所有设置便自动应用到新数据上,也可以查看生成的代码来学习绘图相关语法。这种以“从图形到代码”的方式和传统“从代码到图形”的方式相比效率定会高出很多。
Matlab绘图格式控制的详细说明参考Matlab帮助文档“Matlab/Graphics/Formatting and Annotation”,下面仅对最为常用的指令进行介绍:
坐标系:
指令 |
说明 |
axis on/off |
打开/关闭坐标轴显示 |
Axis(V) V=[x1,x2,y1,y2]或[x1,x2,y1,y2,z1,z2] |
设定坐标范围 |
axis equal |
x,y坐标采用等长刻度 |
axis vis3d |
三维旋转观察时保持高宽比不变,避免图形大小变化 |
grid on/off |
打开/关闭分格线 |
xlabel(S)/ylabel(S)/zlabel(S) |
设定x/y/z轴标签为S |
注解:
指令 |
说明 |
title(S) |
设定图的标题 |
legend(S1,S2,…) |
加入图例 |
text(xt,yt,S) |
在(xt,yt)处书写注释S |
关于字符串显示的格式及转移符号参考Matlab帮助文档“Text Properties”。
重叠绘图:
指令“hold on/off”控制是重叠绘制还是覆盖已有图形。
多子图:
指令“subplot(m,n,p)”将绘图区分为mxn个区域,并指定以行优先的第p个子区为当前绘制区,例如下(取自Matlab帮助文档):
x = linspace(0,10); y1 = sin(x); y2 = sin(2*x); y3 = sin(4*x); y4 = sin(8*x); figure subplot(2,2,1); plot(x,y1); title('Subplot 1: sin(x)') subplot(2,2,2); plot(x,y2); title('Subplot 2: sin(2x)') subplot(2,2,3) plot(x,y3); title('Subplot 3: sin(4x)') subplot(2,2,4) plot(x,y4); title('Subplot 4: sin(8x)')
Colormap, Shading, Light:
为了直观呈现数据,花哨的颜色是少不了的,除了直接指定所绘制对象的颜色外,颜色可以由标量数据映射到颜色表得到,从而得以利用颜色来呈现第四维度的信息。这里又涉及“采样”和“插值”,一个Colormap定义一个颜色表,这是采样后的有限个颜色值,待映射函数值f首先根据Cmax和Cmin算出一个1-N的数c,N是颜色表颜色值的个数,对c进行上下取整作为索引得到两个颜色值,再根据c和这两个颜色值插值得到f映射的颜色,f映射的颜色只是一个格点的颜色,由四个格点围成的小四边形的颜色由这四个格点插值得到,shading和light指令就是用来控制映射的颜色值如何影响显示颜色的。
参考Matlab帮助文档“Matlab/Graphics/Formatting and Annotation”。
参考文献:
博客:Matlab绘图函数一览;
《MATLAB R2011a教程》(张志涌等,北京航空航天大学出版社,2011),第5章;
Matlab R2014a帮助文档,“MATLAB/Graphics”(在线版本)。