第5 章 数据可视化 本章讨论数据可视化问题。数据可视化是MATLAB的一个特色,可以将计算结果 直接以图形的形式直观地显示出来。例如,单变量函数y=f(x)的图像是二维(2D)的, 也就是平面的,而空间曲线与曲面显示的是三维(3D)的图形。 5.1 二维作图 计算机作图实际上是逐点描绘的,需要给出一系列的点对(xi,yi)(i=1,2,…,n)。 其中,数据xi(i=1,2,…,n)作为一个n 维的向量,需要我们录入或产生。而yi 则是根 据函数表达式与xi 计算出来的值。作图需要的数据xi 有它的特殊性。其前后两个数值 的差是一样的。也就是说,xi 是一个等差数列,即线性等距(linearsquallyspaced)数据。 2.2节已经介绍,有两种方法产生线性等距数据:用带冒号的指令与用内置函数linspace。 5.1.1 用内置函数plot 作图 MATLAB函数“plot”是一个功能非常强大的作“线状”图形(linearplot),即平面图 形的工具。它的形参可以是一个、两个或多个。它除了可以作通常的实线条以外,还可以 作出多种样式的线条,如由小点、冒号、小短线形成的线条,或由小方块、“+”号、“*”号、 小菱形和字母“x”形成的线条,等等,还可以使画出的线条带各种颜色。 plot命令的基本用法如下。 (1)plot(X,Y);创建Y 中数据对X 中对应值的二维线图。 . 如果X 和Y 都是向量,则它们的长度必须相同。plot函数绘制Y 对X 的图。 . 如果X 和Y 均为矩阵,则它们的大小必须相同。plot函数绘制Y 的列对X 的列 的图。 . 如果X 或Y 中的一个是向量b 而另一个是矩阵A,则矩阵A 的行、列向量的长度 中必须有一个与向量的长度相等。如果A 的行向量的长度等于b 的长度,则plot 函数绘制A 中的每一行对b 的图。如果A 的列数等于b 的长度,则该函数绘制 A 的每一列对向量b 的图。如果A 为方阵,则该函数绘制A 的每一列对b 的图。 . 如果X 或Y 之一为标量,而另一个为标量或向量,则plot函数会绘制离散点。但 是,要查看这些点,必须指定标记符号,例如,plot(X,Y,'o')。 (2)plot(X,Y,LineSpec);LineSpec设置线型、记号与颜色属性。 (3)plot(X1,Y1,…,Xn,Yn);用同一个坐标轴绘制多条曲线。 58 MATLAB 与机器学习应用 (4)plot(X1,Y1,LineSpec1,…,Xn,Yn,LineSpecn);LineSpecn 用来设置不同的 线型、记号与颜色以绘制多条曲线。 (5)plot(Y);创建Y 中数据的二维折线图。 (6)plot(Y,LineSpec);LineSpec指定Y 中数据的二维折线图的线型、记号与颜色 绘制。如 要详细了解指令plot的用法,可以使用plot的帮助命令“helpplot”。 1.绘制一般曲线 指令plot(x,y)绘制以首末相连直线段连接而成的(折线)图形,x 与y 都是n 个分 量的向量。用此指令绘制由n 个点对(xi,yi)(i=1,2,…,n)连接而成的曲线。 例5.1 由默认值100个点对linspace(-pi,pi)和指定值10个点对linspace(-pi, pi,10)作出的不同光滑度的二维“曲线”图,如图5.1所示。 >> x = linspace(- pi, pi); y = sin(x); plot(x, y); > >x = linspace(-pi, pi, 10); y = sin(x); plot(x, y); 图5.1 曲线图 对比图5.1(a)和图5.1(b),图5.1(a)看上去是一条曲线,而图5.1(b)明显是一条折 线。这是因为,绘制图5.1(b)的指令串b指定了(-pi,pi)间绘制10段线,逼近sin曲线 的精度较低。而绘制图5.1(a)的指令串a没有指定(-pi,pi)间绘制线段的数目,此时采 用默认逼近段数100,逼近sin曲线的精度较高,看起来更像曲线。只有当点的个数足够 多,即点足够密时,逐点描绘的图才能像一条曲线。 2.图片窗口名字的命名 绘制指令产生的图形将在一个默认的图片窗口名“Figure1”中显示。例如例5.1中 绘制的sin曲线,输入(产生图5.1(a)的)指令串a后,图5.1(a)左边顶上标有默认的图 片窗口名“Figure1”。如果紧接着输入(产生图5.1(b)的)指令串b后,新产生的图形将 仍在名为“Figure1”原图片窗口中显示,前一个图就被指令串b产生的图形替代了。 第5 章 数据可视化 59 如果想同时保留这两个图形,则可在指令串a与b的最前面分别加上图片窗口命名 指令“figure(1);”与“figure(2);”。这样,两个指令产生的图形将在不同的图片窗口中 显示。此时,两个指令就会分别变成: . 指令串a:“figure(1);x=linspace(-pi,pi);y = sin(x);plot(x,y);”(在 Figure1窗口中显示图形)。 . 指令串b:“figure(2);x=linspace(-pi,pi,10);y=sin(x);plot(x,y);” (在Figure2窗口中显示图形)。 仅用指令“figure(1);”或“figure(2);”本身,则会创建一个新的图片窗口。如果在 指令串a的最后加上指令“holdon;”,则保持当前的图形,此后接着输入的绘图指令把新 的内容加到现有的图形上,即所产生的图形都在Figure1窗口中显示。 最好在最后一个绘图指令后加上一个指令“holdoff;”,表示在当前图片窗口的绘图 指令已结束。 3.绘制向量(直线) 指令plot([x1,x2],[y1,y2])是plot(x,y)在向量x 和y 都只有两个分量时的特 殊情况。它给出一条连接(x1,y1)与(x2,y2)的直线段。 例5.2 在例5.1的曲线图5.1(a)上再画两条直线段:从(-4,0)到(4,0)和从(0, -1)到(0,1),这两条直线段相当于两条坐标轴,如图5.2所示。 >>x = linspace(-pi, pi); y = sin(x); plot(x, y); hold on; %绘制两条直线段(坐标轴)。 plot([-4,4],[0,0]); plot([0,0],[-1,1]); hold off; >>x = linspace(0,2*pi,100); y = sin(x) ; plot(x,y); %标记坐标区并添加标题。 xlabel('x'); ylabel('sin(x)'); title('Plot of the Sine Function'); 图5.2 绘制正弦曲线 这里,图5.2(a)用了“holdon;… holdoff;”指令保证了sin曲线与后加的两条直线 段显示在同一个窗口内。图5.2(b)用了xlabel和ylabel指令分别作了横向和竖向标记, 60 MATLAB 与机器学习应用 用title指令加了标题。 图5.2(a)中的向上与向右的箭头是这样画上去的:在MATLAB作图上方的菜单 中,单击Insert→Arrow,此时鼠标会变成“+”字。把鼠标移到要画箭头的直线段附近, 顺着直线移动。如果所画的箭头不对,右键单击箭头,在打开的菜单,单击Delete,即可删 去箭头。图5.2(b)中的“xlable(x轴标记)”“ylable(y轴标记)”与“title(标题)”也可以在 作出的图上单击Insert再选择有关项来完成。 4.设置绘制属性 指令plot(x,y,s)中s 是字符串,它用来指定线条的颜色和/或类型。代码的格式 见后面的例子。 (1)s 指定线条的颜色。 MATLAB可供选择的线条颜色有以下几种,字符所表示的颜色写在括号中。除k 表示黑色(black的字尾)以外,其他字符都是所表示的颜色的英文首字母。 b(blue,蓝); g (green,绿); r(red,红); y (yellow,黄); c(cyan,青); m(magenta,洋红);k(black,黑)。 (2)s 指定线条的类型。 线条的主要类型有以下几种(其他类型可用指令“helpplot”来查找)。 - (solid,实线)。 :(dotted,小点组成的虚线)。 O (大小写均可,circle,小圆圈)。 --(dashed,小短线组成的虚线)。 . (point,点)。 -.(dashdot,小短线与小点组成的虚线)。 * (star,星号)。 s(square,小方块)。 d(diamond,菱形)。 (3)s 指定字符串的写法。 线条的类型与颜色要写在单引号(')内的字符串s 中,表示类型与颜色的字符,其先 后次序是任意的。例如,绿色的菱形线条,可以写为'gd'或'dg'。 例5.3 以下指令串画出了图5.3,程序中有简单说明,作完图后有详细说明。 >>x=linspace(0,2*pi,200); %[0,2*pi] 中200 个分点 y=sin(x); z=cos(x); v=sin(x-pi/2); %3 个函数在200 个分点上的值 plot(x,y,'r:'); %作sin(x) 曲线 hold on; %要继续作图 ix=[1,40,80,120,160,200]; %要描的6 个点的x 的下标向量 plot(x,z,'b.'); plot(x,v,'gd'); %作另外2 条曲线 plot(x(ix),z(ix),'sk'); %黑色小方块描出6 个离散点 legend('sin(x)', 'cos(x)', 'sin(x-pi/2)','6 points'); %图例 hold off; %作图结束 第5 章 数据可视化 61 图5.3 三种类型与颜色不同的曲线及6个离散点 (1)上面最后一个plot指令描出的6个离散点中,横坐标是下标为ix分量的x 值, 而纵坐标为对应的余弦值。在数据拟合的图示中,常常需要这样来描出观察(实验)数据 的离散值。 (2)指令legend()是给出图例,括号内的字符串的个数应与曲线的个数相同,而且 字符串的次序与plot曲线的次序一致。在图上显示在小方框内。把鼠标移入小方框内, 按住鼠标,这时可将小方框拖移到任何地方(例如不挡住曲线的地方)。 例5.4 以下的指令串画出了图5.4。它与图5.3是同样的三条曲线,只是线条的类型 与s 中的字符次序不同。这里还把绘图5.3的三个plot指令合并成一个。而且,那些使用 实参y、z、v 的地方,这里直接用它们的表达式来代替。所以,两者画出了三条同样的曲线。 >> x=linspace(0,2*pi,200); plot(x, sin(x),' -ro', x, cos(x),' -.b',x, sin(x-pi/2),'--g'); legend('sin(x)', 'cos(x)', 'sin(x-pi/2)'); 图5.4 三种线条类型与图5.3不同的曲线 62 MATLAB 与机器学习应用 5.绘制数列 指令plot(y)用于创建Y 中数据的二维折线图。一个数列yn (n=1,2,…)可以看作 y 是它的下标n 的函数。此时,plot(y)是plot(n,yn)的特例。另外,当y 是一个复向量 时,plot(y)等价于plot(real(y),imag(y))。其中,指令real(y)与imag(y)分别取y 的实 部与虚部。 (1)实数列y。 例5.5 绘制实数列yn =ln(n)(n=1,2,…,10),如图5.5所示。 >>n=1:10; y=log(n); plot(y); 图5.5 数列yn =ln(n)相对于下标n 的图形 (2)复向量y。 例5.6 指令串“x=linspace(-pi,pi);y= x+i*sin(x);plot(y);”也可以得到 图5.1(a)。 这里可以用“sum(abs(real(y)-x))”与“sum(abs(imag(y)-sin(x)))”的答案是否 都等于0来检查y 的实部real(y)是否等于x,以及y 的虚部imag(y)是否等于sin(x)。 回忆一下:其中内置函数abs(z)是求z 的绝对值;而sum(a)当a 是向量时,是求它的各 分量的和。 例5.7 以下三行指令串都得到图5.6,只是在Figure1、Figure2和Figure3这3个窗 口里。 >>figure(1); x=linspace(0, pi/2); y=cos(x)+i*sin(x); plot(y); figure(2); x=linspace(0, pi/2); y=exp(i*x); plot(y); figure(3); x=linspace(0, pi/2); x1=cos(x); y1=sin(x); plot(x1,y1); 以上第1、2行指令串的等价性说明了欧拉公式(eix =cos(x)+isin(x))的正确性; 第5 章 数据可视化 63 图5.6 复向量eix 的实部与虚部点对所描绘的图形 而第1、3行指令串的等价性说明了plot(y)在y 为复向量时,图形是实数点对(cos(xi), sin(xi))描绘出的曲线。 5.1.2 辅助作图的内置函数与参数 1.绘制网格 内置函数grid在图上加上网格,见例5.8;而gridminor加上细网格,见例5.9。 2.加图标题 内置函数title(' ')在图顶上加上标题,见例5.8。标题内容写在单引号内,可以是中 文。写中文内容时要注意,先在英文状态下写好单引号,再切换到中文状态后,在单引号 内打印中文。 3.水平或垂直标记 内置函数xlabel(' ')与ylabel(' ')分别在X 轴与Y 轴上写上标记,见例5.2与例5.8。 其内容写在单引号内,可以是中文。 4.绘制坐标轴 内置函数axis是画坐标轴的,可用help指令来查看详情。 例5.8 以下是添加网格、水平与垂直标记以及标题的作图例子(见图5.7)。 >> x = linspace(-pi, pi); y = sin(x); plot(x, y); grid; xlabel('弧度'); ylabel('正弦值'); title('Graph of y = sin(x)'); 例5.9 以下是添加细网格的作图例子(见图5.8)。 >>x = linspace(-pi, pi); y = sin(x); plot(x, y); grid minor; 5.曲线“宽度”的设置 参数LineWidth(一个词)控制曲线的“宽度”,其后必须写上宽度值,用“,”号分开。 64 MATLAB 与机器学习应用 图5.7 加了网格,x、y 坐标轴标记等的正弦曲线图 图5.8 加上细网格的正弦曲线图 下例是用不同的宽度绘制两条曲线。 例5.10 以下指令串画出了例5.3中的两条曲线,线条的类型与颜色与前例相同。 这里只是加了参数,并给出不同的宽度值。从图5.9可以看出,宽度值为4的曲线比值为 3的粗曲线。 >> x=linspace(0,2*pi,200); plot(x, cos(x),' -.b','LineWidth',3); %颜色blue,宽度值为3 hold on; plot(x, sin(x-pi/2),'--g','LineWidth',4); %颜色green,宽度值为4 hold off; 第5 章 数据可视化 65 图5.9 宽度值为3与4的两条曲线 5.1.3 用矩阵作为plot 的参数作图 内置函数plot(x,y)当x、y 中x 为向量,y 为矩阵时,且x 的长度等于y 的行(列) 数,则x 相对于y 的每一行(列)作出一条曲线。 例5.11 我们把例5.3中生成的三个向量合成一个矩阵,然后用来画出三条曲线。 即用如下的程序画出图5.10。注意,在程序中,并不设置曲线的颜色与类型。这里用的是 默认值,曲线类型都用实线。 >> x=linspace(0,2*pi,200); %产生200 个x 点 y=sin(x); z=cos(x); %计算3 个向量的值 v=sin(x-pi/2); Y=[y',z',v']; %用此指令,把这3 个向量作为列,合并成矩阵Y %Y=[y;z;v]; %或用此指令,把这3 个向量作为行,合并成矩阵Y。结果相同 plot(x,Y) ; %同时画出3 条曲线 legend('sin(x)', 'cos(x)', 'sin(x-pi/2)') %图例 图5.10 用矩阵表达式同时画出3条曲线 66 MATLAB 与机器学习应用 5.2 三维作图 三维(3D)作图包括空间曲线与曲面作图。3D作图也可以用单变量函数作图时用的 内置函数grid、title、xlabel、ylabel(加上zlabel)、legend等。 5.2.1 空间曲线作图 1.曲线方程 空间曲线作图时,所用的曲线方程应为参数方程:x=f(t),y=g(t),z=h(t)。与 单变量函数作图时一样,数据ti(i=1,2,…,n)作为一个n 维的向量,需要我们录入或产 生。三列向量(xi|yi|zi)(i=1,2,…,n)则是根据参数方程与ti 计算出来的值。 2.曲线作图用的内置函数 空间曲线作图时,所用的内置函数与单变量函数作图的内置函数类似,有plot3(x,y, z)与plot3(x,y,z,s),其中,s 是用来设置曲线的类型、所用的画线符号与颜色的符号串。 3.用内置函数plot3(x,y,z,s)作曲线 例5.12 以下指令串作出在参数区间[0,10π]内的一条螺旋线,其参数方程为x= sin(t),y=cos(t),z=t。以及过a(-1,1,0)与b(1,-1,20)两点的直线,其参数方程为 x=t/(5π)-1,y=-t/(5π)+1,与z=2t/π。 得到图5.11。指令串中的legend是两个分量都是字符串的向量。另外,这里的两个 plot3指令可以合并为一个指令(可去掉holdon;与holdoff;)。 >> t = 0:pi/50:10*pi; %产生数据t,步长pi/50 plot3(sin(t),cos(t),t, 'r*'); %用红色*作螺旋线 grid; xlabel('x=sin(t)'); %加网格与X 轴的标记 ylabel('y=cos(t)'); zlabel('z=t'); %加Y、Z 轴的标记 hold on; %准备加上另一个图 %以下用蓝实线画过a(-1,1,0), b(1,-1,20) 两点的直线 plot3([-1,1],[1,-1],[0,20], 'b- '); %也可以用下一参数方程 %plot3(t/(5*pi)-1,-t/(5*pi)+1,2*t/pi,'b-'); title('Helix & straight line '); %加上标题 legend('螺旋线' ,'直线'); %加上图例 hold off; 5.2.2 曲面作图 给出两个变量的曲面方程z=f(x,y),如何作出在区域a