5.5.3 句柄图形——控制绘图的每一个细节

5.5.3 句柄图形——控制绘图的每一个细节

MATLAB绘图功能的强大,不仅是因为能绘制上述那么多种图形,更因为其可以用程序精细地控制绘图的各个细节。在一些情况下,对一些人来说,这样的控制是非常舒服的。因此,MATLAB与那些只靠鼠标单击按钮绘图的工具,如Tecplot、Surfer、Origin等,在绘图方面还是有区别的。

MATLAB在绘图细节上的控制,依靠的就是句柄。

(1)什么是句柄?

句柄的英文名是Handle[6],通俗地讲,就是把手的意思。上文说过,MATLAB可以用程序控制[7]绘图的各个细节,如改变一条曲线的线型、颜色、标记、粗细等,改变坐标轴标注文字的大小、颜色、字体等。线条、字体等在MATLAB绘图中都是对象(Object),编程的人都知道,要控制和操作对象,就需要有一个变量代表这个对象。这个变量在编程中就叫Handle。用Handle可以对该Handle代表的绘图元素(图5-36)[8]进行各种操作。

图5-36是MATLAB的绘图元素结构图。

图5-36 MATLAB绘图元素

1)Figure

前文说过,MATLAB所有图形都是绘制在Figure上的。Figure是最基本的绘图元素,可以将其想象为要在上面画图的“白纸”。从图5-36中看出,在Figure之上还有一个Root层。Root层是虚的,只是用来保存一些基本的绘图设置,是给MATLAB绘图系统服务的,用户并不能在其上绘图,也不能更改Root层的参数。

2)坐标系Axes

Figure的下一层是“UI Objects”和“Axes”。“UI Objects”是用户界面对象(UI Objects)。在每一个绘图的Figure上,都有一个菜单和工具条,菜单、工具条及其上所有细节都隶属于“UI Objects”。菜单项和工具条上的按钮是可以添加和改动的(不是所有的都可以改动),要改动就要用到“UI Objects”。在用MATLAB做GUI(图形用户界面)[9]时,肯定要用到“UI Objects”。如果暂时不做GUI,可以暂停使用“UI Objects ”。

“Axes”是MATLAB绘图的坐标系,MATLAB的所有图形都是绘在坐标系上的。一个Figure上可以放置多个Axes。图5-7中的subplot就是在一个Figure上放置了两个Axes。

一个“Axes”有三个“axis”(坐标轴)。二维图形也有三个坐标轴,但MATLAB在绘制二维图形时,将坐标系的视角放置在垂直于xOy面的方向上,相当于从xOy面正上方往下看,就看不到z轴了。读者可以做这样一个试验:单击一个二维图形(最简单的如用plot(1∶10)画一条直线);单击Figure工具条上的旋转按钮,用鼠标旋转曲线,可以发现z轴出现了。

画图时常需要对坐标轴进行设置,MATLAB专门设置了一些简单的函数调用形式来完成这些功能。查阅axis的“Help”可以发现axis命令的许多简单调用形式。下面介绍几种常用的调用形式。

axis ij与axis xy

MATLAB默认坐标系的原点在左下角。但一般数字图像处理领域中图像坐标系的原点在左上角,即y轴向下。axis ij用于将从标系设置成图像坐标系,而axis xy用于将坐标系设置成默认坐标系。

axis equal

MATLAB的坐标系在默认情况下所占区域为正方形(对于二维来说),因此,当x数据和y数据的值域不同时,x轴和y轴的比例是不同的。

在绘制三维数据时,经常会遇到一些问题。例如,原来长方形的区域也画成了方形,使区域失真。此时可用axis equal命令设置各坐标轴的比例,使之保持同样的比例,就解决这个问题了。

axis tight

将坐标轴的范围设置为与数据范围一致,这样,在矩形区域,即使用axis equal将坐标轴比例设成一样,也不会在图形边界出现空白区。

3)MATLAB的主要绘图元素

在坐标系下面,就是MATLAB所有重要的绘图元素了。其中“Annotation Objects”是标注用绘图元素(如文字、箭头等)。“Group Objects”用于将一些绘图元素成组,如将若干条线成组,然后统一设置属性。“Plot Objects”是由若干特定的绘图函数生成的绘图元素,如等值线函数生成的若干条等值线就是一个“Plot Objects”。从这个意义上讲,“Plot Objects”与“Group Objects”有些类似。

Axes下面最核心的是“Core Objects”,其下包括了7种MATLAB的基本绘图元素(图5-37),MATLAB所有的图形都是由这7种绘图元素构成的。如例3中绘制的曲线属于“Line”;图5-26中的填充等值线属于“Patch”等。具体的细节请读者通过“Help”自行学习。

图5-37 MATLAB的核心绘图元素

(2)句柄有什么用?

有了句柄就可以查看,最主要的是可以修改绘图对象的属性,也就完成了对绘图对象的控制和操作。

每个对象都有若干个属性(property),属性的取值决定了图形中各对象的表现。用get函数可以查看对象的属性值。

例17:绘制曲线并查看其属性。

有了前面的知识,读者可以明白上面的程序是用红色的细实线(数据点用圆圈表示)画了一条正弦曲线和一条余弦曲线,如图5-4所示。与前面例子不同的是,plot函数返回了一个参数h。

h是一个lineseries对象,是一个2×1的向量,h(1)代表y1曲线,h(2)代表y2曲线。

用get函数可以查看两个Handle的属性。get(h(1))和get(h(2))可以列出两个曲线的所有属性,两者的对比见表5-4。从表中属性可以看出两条曲线的相同和不同之处。

表5-4 两条曲线属性的对比

续表

如果只想查看或者获得某一个属性,可以用get函数的另一种形式,即

例18:查看曲线属性。

则从曲线中重新获得数据点。可以用此数据重新绘制曲线,以测试上面得到的数据的正确性:

结果会生成和图5-4完全相同的两条曲线。

用set函数可以设置对象的属性值,其格式为

需要注意的是,在设置时一定要注意该属性的数据类型。有些是字符串(如线型、符号等),要包括在引号中;有些是数据(如线宽等),要写成数或变量,不能括在引号中;有些是向量(如颜色)或矩阵(如绘图数据等),也要按照规定的写法书写。

下面用例子来说明如何设置图形的细节。接着例18的程序:

其结果如图5-38所示。

图5-38 经过更改的曲线

可见,如果有绘图元素的句柄,又掌握了get和set函数的应用,控制绘图细节是很容易的。

(3)如何获得句柄?

获得一个绘图对象的句柄是控制和操作这个对象的第一步,也是最重要的一步。有两种方法可以获得句柄:

1)返回法

如果仔细查看MATLAB的“Help”,会发现几乎所有的绘图函数都提供了返回所绘对象句柄的调用形式,如果想获得句柄,在绘图时采用这些调用形式就可以了。上面的例子就是这样做的。

2)追踪法

用户有时可能事先不能确定要对哪个对象进行操作,而要在运行过程中才确定要操作的对象(如交互操作中,用鼠标单击选择要操作的对象,或者前面忘了在程序中返回句柄了),那么就要用追踪的方法寻找该对象的句柄。

例19:查找绘图元素的句柄。

其输出也会得到两条曲线的句柄。

有两个函数在获取句柄时非常有帮助,分别为gcf与gca。gcf获得当前图形的句柄,gca获得当前坐标系的句柄。事实上,这两个函数也很好记:gcf=get current figure,而gca=get current axes 。

(4)不用句柄行吗?

大部分情况下不用句柄是可以的。

MATLAB的Figure上提供了菜单和工具条,用其中的命令及相应的对话框可以完成绝大部分图形的控制。这一点完全类似于其他绘图软件。如果不习惯用编程的方式画图,可以用这种方法。但作者还是坚持建议读者用编程调用句柄的方法画图。