第二十章 句柄图形 ` 什么是句柄图形?句柄图形是对底层图形例程集合的总称,它实际上进行生成图形的工作。这些细节通常隐藏在图形M文件的内部,但如果想使用它们也是可得到的。 MATLAB用户指南给人的一种印象是,句柄图形非常复杂,只对熟练的高级用户才有用。而实际上不是这样的。句柄图形可以被任何人用来改变MATLAB生成图形的方式,不论是只想在一幅图里做一点小变动,还是想做影响所有图形输出的全局变动。 句柄图形允许你定制图形的许多特性,而这用高级命令和前几章里描述的函数是无法实现的。例如,如果想用橘黄色来画一条线,而不是plot命令中可用的任何一种颜色,该怎么做呢?句柄图形就可以提供一种方法。 本章不对句柄图形作详细讨论,因为那样涉及问题太细。这里的目的只是对句柄图形概念作基本了解,并提供足够多的信息,使得即使是偶尔使用一下MATLAB的用户也可以利用句柄图形。在这个背景下,在本章最后给出了关于句柄图形对象属性和它们的值,它不仅很有用也很有意义。 20.1 谁需要句柄图形? 开始,我们要强调本章主要是针对那些不满足于MATLAB普通图形特性的读者。如果对所画的图形已经很满意,那么就跳过当前的讨论。如果以后要定制图形,只要记住这里有可用的信息。 现在,对于那些还在犹豫的用户,我们要强调学习使用句柄图形并不困难。如果只想改变图形的标题字体,或者改变一个图形窗口的背景颜色,那么,你不必成为一个句柄图形的专家也可做到。 另一方面,如果想定制图形,并且要打算对图形的每个可能方面进行控制,那么句柄图形会为此提供强有力的工具。 前面那些章提供的图形功能被认为是高级的命令和函数,包括plot,mesh,axis及其它。这些函数是建立在底层函数和属性的基础上,总称为句柄图形。 20.2 什么是句柄图形对象 句柄图形是基于这样的概念,即一幅图的每一组成部分是一个对象,每一个对象有一系列句柄和它相关,每一个对象有按需要可以改变的属性。 当今计算机行业最流行的术语之一便是对象这个词。面向对象的编程语言,数据库对象,操作系统和应用程序接口都使用了对象的概念。一个对象可以被粗略地定义为由一组紧密相关、形成唯一整体的数据结构或函数集合。在MATLAB中,图形对象是一幅图中很独特的成分,它可以被单独地操作。 由图形命令产生的每一件东西都是图形对象。它们包括图形窗口或仅仅说是图形,还有坐标轴、线条、曲面、文本和其它。这些对象按父对象和子对象组成层次结构。计算机屏幕是根对象,并且是所有其它对象的父亲。图形窗口是根对象的子对象;坐标轴和用户界面对象(在下一章讨论)是图形窗口的子对象;线条、文本、曲面、补片和图象对象是坐标轴对象的子对象。这种层次关系在图20-1中给出。  图20-1 对象层次结构 根可包含一个或多个图形窗口,每一个图形窗口可包含一组或多组坐标轴。所有其它的对象(除了在下一章讨论的uicontrol和uimenu外)都是坐标轴的子对象,并且在这些坐标轴上显示。所有创建对象的函数当父对象或对象不存在时,都会创建它们。例如,如果没有图形窗口,plot(rand(size([1:10])))函数会用缺省属性创建一个新的图形窗口和一组坐标轴,然后在这组坐标轴内画线。 20.3 句柄对象 假设已打开了三个图形窗口,其中两个有两幅子图。并要改变其中一幅子图坐标轴内一条线的颜色,如何认定想要改变的那条线?在MATLAB中,每一个对象都有一个数字来标识,叫做句柄。 每次创建一个对象时,就为它建立一个唯一的句柄。计算机屏幕作为根对象常常是0。? Hf_fig=figure命令建立一个新的图形窗口,变量Hf_fig中返回它的句柄值。图形窗口的句柄为整数,通常显示在图形窗口标题条中。其它对象句柄是MATLAB满精度的浮点值。 MATLAB可以用来获得图形、坐标轴和其它对象的句柄。例如,? Hf_fig=gcf返回当前图形窗口的句柄值,而? Ha_ax=gca返回当前图形窗口内当前坐标轴的句柄值。这些函数和其它对象操作的工具在本章以后讨论。 为了提高可读性,在本书中包含句柄对象的变量取名以大写的H开头,跟之以一个辨识对象类型的字母,然后是一个下划线,最后是一个或几个描述符。因此,Hf_fig是一个图形窗口的句柄,Ha_ax1是坐标轴对象的句柄,而Ht_title是一个文本对象的句柄。当对象类型不知道时,用字母x,比如Hx_obj。虽然句柄变量可以取任意名字,遵循这种规则使得能在M文件中很容易找到句柄变量。 所有产生对象的MATLAB函数都为所建立的每个对象返回一个句柄(或句柄的列向量)。这些函数包括plot,mesh,surf及其它。有一些图形由一个以上对象组成。比如,一个网格图由一个曲面组成,它只有一个句柄;而waterfall图形由许多线条对象组成,每个线条对象都有各自的句柄。例如,? Hl_wfall=waterfall(peaks(20)) 对线条返回一个包含着20个句柄的列向量。 20.4 通用函数get和set 所有对象都有属性来定义它们的特征,正是通过设定这些属性来修正图形显示的方式。尽管许多属性所有的对象都有,但与每一种对象类型(比如坐标轴,线,曲面)相关的属性列表都是独一无二的。对象属性可包括诸如对象的位置、颜色、类型、父对象、子对象及其它内容。每一个不同对象都有和它相关的属性,可以改变这些属性而不影响同类型的其他对象。和每一种对象类型(图形,坐标轴,线,文本,曲面,补片和图象)相关的完整的属性列表在本章的后面给出。 对象属性包括属性名和与它们相联关的值。属性名是字符串,它们通常按混合格式显示,每个词的开头字母大写,比如:’ LineStyle ‘ 。但是,MATLAB识别一个属性时是不分大小写的。另外,只要用足够多的字符来唯一地辨识一个属性名即可。例如,坐标轴对象中的位置属性可以用 ‘ Position ‘ , ‘ position ‘ ,甚至是 ‘ pos ‘ 来调用。 当建立一个对象时,它用一组缺省属性值,该值可以用两种方法来改变。可以用{属性名,属性值}对来建立对象生成函数;或者在对象建立后改变属性。前一种方法的例子是: ? Hf_1=figure( ‘color’, ‘white’ ) 它用缺省的属性值建立一个新的图形窗口,只是背景颜色被设为白色而不是缺省的黑色。 为了获得和改变句柄图形对象的属性只需要两个函数。函数get返回某些对象属性的当前值。使用函数get的最简单语法是get(handle, ‘ PropertyName’ )。例如: ? p=get(Hf_1, ‘position’ ) 返回具有句柄Hf_1图形窗口的位置向量。 ? c=get(Hl_a, ‘color’ ) 返回具有句柄Hl_a对象的颜色。 函数set改变句柄图形对象属性,使用语法set(handle, ‘PropertyName’ ,value)。例如: ? set(Hf_1, ‘Position’ ,p_vect) 将具有句柄Hf_1的图形位置设为向量p_vect所指定的值。同样 ? set(Hl_a, ‘color’ , ‘r’ ) 将具有句柄Hl_a的对象的颜色设置成红色。 一般情况下,函数set可以有任意数目的( ‘PropertyName’ ,PropertyValue)对。比如: ? set(Hl_a, ‘Color’ , ‘r’ , ‘Linewidth’ ,2, ‘LinStyle’ , ‘--’ ) 将具有句柄Hl_a的线条变成红色,线宽为2点,线型为破折号。 除了这些主要功能,函数set和函数get还能提供帮助。例如? set(handle, ‘PropertyName’ )返回一个可赋给由handle所描述对象的属性值列表。例如: ? set(Hf_1, ‘Units’ ) [inches|centimeters|normalized|points|{pixels}] 表明由Hf_1所引用的图形的 ‘Unites’ 属性是五个可允许的字符串,而其中 ‘pixels’ 是缺省值。 如果指定一个没有固定值的属性,那么,MATLAB就会通知如下: ? set(Hf_1, ‘Position’ ) A figure’s ‘Position’ property does not have a fixed set of property values。 除了set命令,句柄图形对象创建函数(例如figure,axis,line等等)接受多个属性名和属性值对。例如: ? figure( ‘Color’ , ‘blue’ , ‘NumberTitle’ , ‘off’ , ‘Name’ , ‘My Figure’ ) 创建一个图形窗口,背景为兰色,标有‘My Figure’而不是缺省标题‘Figure No. 1’。 为了形象说明上述概念,考虑下面的例子: ? Hf_fig =figure % create a figure having an interger handle Hf_fig= 1 ? Hl_line=line % create a line having a floating-pointer handle Hl_line = 59.0002 ? set(Hl_line); % list settable properties and potential values Color EraseMode: [ {normal} | background | xor | none ] LineStyle: [ {-} | -- | : | -. | + | o | * | . | x ] LineWidth MarkerSize Xdata Ydata Zdata ButtonDownFcn Clipping: [ {on} | off ] Interruptible: [ {no} | yes ] Parent UserData Visible: [ {on} | off ] ? get(Hl_line); % list properties and current property values Color = [1 1 1] EraseMode = normal LineStyle = - LineWidth = [0.5] MarkerSize = [6] Xdata = [0 1] Ydata = [0 1] Zdata = [ ] ButtonDownFcn = Children = [ ] Clipping = on Interruptible = no Parent = [58.0002] Type = line UserData = [ ] Visible = on 在上例中,所创建的线条中的 ‘Parent’ 属性就是包含线条的坐标轴的句柄。而且所显示的图形列表被分为两组。在空行上的第一组,列出了该对象的独有属性,而空行下的第二组列出所有的对象共有的属性。注意到函数set和函数get返回不同的属性列表。函数set只列出可以用set命令改变的属性,而get命令列出所有对象的属性。在上面的例子中,函数get列出了 ‘Children’ 和 ‘Type’ 属性,而set命令却没有。这一类属性只可读,但不能被改变,它们叫做只读属性。 与每一个对象有关的属性数目是固定的,但不同的对象类型有不同数目的属性。象上面所显示的,一个线条对象列出了16个属性,而一个坐标轴对象列出了64个属性。显然,透彻地说明和描述所有对象类型的全部属性超出本书的范围。但是,其中的很多属性本书以后要详细讨论,并且列出全部属性。 作为一个使用图象句柄的例子,可以考虑前面提出的问题。它要用非标准颜色画一条线。在这里,线的颜色用RGB值[1 .5 0]来指定,它是适中的橘黄色。 ? x=-2*pi:pi/40:2*pi; % create data ? y=sin(x); % find the sine of x ? Hl_sin=plot(x,y) % plot sine and save line handle Hl_sin= 59.0002 ? set(Hl_sin, ‘Color’ ,[1 .5 0], ‘LineWidth’ ,3) % Change the color and width 现在加一个浅蓝色的cosine曲线: ? z=cos(x); % find the cosine of x ? hold on % keep the sine curve ? Hl_cos=plot(x,z); % plot the cosine and save the handle ? set(Hl_cos, ‘Color’ ,[.75 .75 1]) % color it light blue ? hold off 也可以用较少的步骤来实现同样的功能: ? Hl_lines=plot(x,y,x,z); % plot both curves and save both handles ? set(Hl_line(1), ‘Color’ ,[1 .5 0], ‘LineWidth’ ,3) ? set(Hl_line(2), ‘Color’ ,[.75 .75 1]) 如何加上一个标题并且使字体比正常大一些呢? ? title( ‘Handle Graphics Example’ ) % add a title ? Ht_text=get(gca, ‘Title’ ) % get a handle to the title ? set(Ht_text, ‘FontSize’ ,16) % customize the font size 最后一个例子说明了关于坐标轴对象令人感兴趣的性质。每一个对象都含有 ‘Parent’ 属性和 ‘Children’ 属性,该属性包含属于派生对象的句柄。画在一组坐标轴上的线,具有当作 ‘Parent’ 属性值的坐标轴对象的句柄,而 ‘ Children ‘ 属性值是一个空距阵。同时,这个坐标轴对象具有当作 ‘ Parent ‘ 属性值的图形句柄,而 ‘ Children ‘ 属性值是线条对象的句柄。标题字符串和坐标轴的标志不包含在坐标轴的 ‘ Children ‘ 属性值里,而是保存在 ‘ Title ‘ 、 ‘ Xlabel ‘ 、 ‘ Ylabel ‘ 和 ‘ Zlabel ‘ 的属性内。创建坐标轴对象时,这些文本对象就建立。title命令设置当前坐标轴内标题文本对象的 ‘String’ 属性。最终,标准MATLAB的函数title,xlabel,ylabel和zlabel不返回句柄,而只接受属性和数值参量。例如下面的命令给当前图加一个24点的绿色标题: ? title( ‘This is a title.’ , ‘Fontsize’ ,24, ‘Color’ , ‘green’ ) 除了函数set和get,MATLAB还提供了另外两个函数来操作对象和它们的属性。任意对象和它们的子对象可以用 ? delete(handle) 来删除。同样 ? reset(handle) 将与句柄有关的全部对象属性(除了 ‘Position’ 属性)重新设置为该对象类型的缺省值。 20.5 查找对象 正如你所见,句柄图形提供了对图形对象的访问途径,并且允许用函数get和set定制图形。但是,如果忘记保存句柄或图中对象的句柄将会怎样呢?或者,也许变量被覆盖又如何呢?如果不知道它们的句柄,怎么改变对象的属性呢?为解决这个问题,MATLAB提供了查找对象句柄的工具。 gcf和gca这两种工具前面已经介绍过了。 ? Hf_fig=gcf 返回当前图形的句柄,而 ? Ha_ax=gca 返回当前图形的当前坐标轴的句柄。 除了这些,还有一个获取当前对象的gco。 ? Hx_obj=gco 返回当前图形的当前对象的句柄。或者用另一种方法: ? Hx_obj=gco(Hf_fig) 返回与句柄Hf_fig有关的图形中当前对象的句柄。 当前对象的定义为用鼠标刚刚点过的对象。这种对象可以是除根对象(计算机屏幕)之外的任何图形对象。但是,如果鼠标指针处在一个图形中而鼠标按钮未点,gco返回一个空距阵。为了让当前对象存在,我们必须选择一些东西。 一旦获得了一个对象的句柄,它的对象类型可以通过查询对象的 ‘Type’ 属性来获得。该属性是一个字符串对象名,比如 ‘figure’ ,’axes’ 或 ‘text’ 。例如: ? x_type=get(Hx_obj, ‘Type’ ) MATLAB中的函数gcf,gca和gco是很好的例子,它们说明如何利用句柄图形来获得有关对象的信息。函数gcf获得根对象的 ‘CurrentFigure’ 的属性值,即是当前图形的句柄。gcf M文件包含: function h=gcf() % GCF Get current figure handle. % H=GCF returns the handle to the current figure.The current fugure is the figure(graphics window)that graphics commands like PLOT,TITLE,SURF,etc.draw to if issued. % % Use the commands FIGURE to change the current figure to a diffent figure,or to create new % ones. % % See also FIGURE,CLOSE,CLF,GCA. % Copyright (c) 1984-94 by The MathWorks,Inc. h=get(0, ‘CurrentFigure’ ); 类似的,函数gca返回当前图形的 ‘CurrentAxes’ 属性值,它的M文件描述如下。 function h=gca() % GCA Get current axis handle. % H=GCA returns the handle to the current axis.The current axis is the axis that graphics % command like PLOT,TITLE,SURF,etc.draw to if issued. % % Use the commands AXES or SUBPLOT to change the current axis to a different axis,or to % create new ones. % see also AXES,SUBPLOT,DELETE,CLA,HOLD,GCF. % Copyright (c) 1984-94 by The MathWorks,Inc. h=get(get(0, ‘CurrentFigure’ ), ‘CurrentAxes’ ); 函数gco也相同,只是它在试图获得当前对象之前先检查图形是否存在。注意函数gcf和gca能促使建立相关的对象,如果它们不存在的话。如下所示的函数gco,它先检查子对象( ‘Children’ )是否存在,如果不存在,就不创建图形对象。 function object=gco(figure) %GCO Handle of current object. % OBJECT=GCO returns the current object in the current figure. % % OBJECT=GCO(FIGURE) returns the current object in figure FIGURE. % % The current object for a given figure is the last object clicked on with mouse. %Copyright (c) 1984-94 by The MathWorks,Inc. if isempty(get(0, ‘Children’ )) object=[ ]; return; end; if (nargin==0) figure=get(0, ‘CurrentFigure’ ); end object=get(figure, ‘CurrentObject’ ); 当需要一些除了 ‘CurrentFigure’ 、 ‘CurrentAxes’ 和 ‘CurrentObject’ 之外的某些东西时,可以用函数get来获得一个对象的子对象的句柄向量。例如: ? Hx_kids=get(gcf, ‘Children’ ) 返回一个向量,它包含当前图形子对象的句柄。 可以用获得子对象 ‘Children’ 句柄的技术彻底搜索句柄图形的层次结构中来找到所要的对象。例如,在画出一些数据后,寻找绿色线条句柄的问题。 ? x=-pi:pi/20:pi; % create some data ? y=sin(x);z=cos(x); ? plot(x,y, ‘r’ ,x,z, ‘g’ ); % plot two lines in red and green ? Hl_lines=get(gca, ‘Children’ ); % get the line handles ? for k=1:size(Hl_lines) % find the green line ?if get(Hl_lines(k), ‘Color’ )==[0 1 0] ? Hl_green=Hl_lines(k) ? end ? end Hl_green= 58.0001 尽管这种技术有效,但是如果有很多对象存在就变得复杂。该技术也丢失了标题和坐标轴标志中的文本对象,除非能逐个检测这些对象。 当有多个图形,每个图形上又有多个坐标轴时,考虑查找所有绿色线条的句柄的问题。 ? Hf_all=get(0, ‘Children’ ); % get all figure handles ? for k=1:length(Hf_all) ? Ha_all=[Ha_all;get(Hf_all(k), ‘Children’ )]; % get all axes handles ? end ? for k=1:length(Ha_all) ? Hx_all=[Hx_all;get(Ha_all(k), ‘Children’ )]; % get axes child handles ? end ? for k=1:length(Hx_all) ? if get(Hx_all(k), ‘Type’ )== ‘line’ ? Hl_all=[Hl_all;Hx_all(k)]; % get line handles only ? end ? end ? for k=1:length(Hl_all) ? if get(Hl_all(k), ‘Color’ )==[0 1 0] ? Hl_green=[Hl_green;Hl_all(k)]; % find green ones ? end ? end 为了简化查找对象句柄的过程,MATLAB 4.2版本和以后的版本提供了内置函数findobj。该函数返回有指定属性值的所有对象句柄。它的在线帮助如下: ? help findobj FINDOBJ Find objects with specified property values. H=FINDOBJ( ‘PlName’ ,PlValue,...) returns the handle of the objects at the root level and below whose property values match those as param-value pairs to the FINDOBJ command. H=FINDOBJ(ObjectHandles, ‘PlName’ ,PlValue,...) restricts the search to the objects listed in ObjectHandle and their descendents. H=FINDOBJ(ObjectHandles, ‘flat’ , ‘PlName’ ,PlValue,...) restrics the search only to the objects listed in ObjectHandles.Their descendents are not searched. H=FINDOBJ returns the handles of the root object and all its descendents. H=FINDOBJ(ObjectHandles) returns the handles listed in Objecthandles ,and the handles of all their descendents. See also SET,GET,GCF,GCA. 帮助信息: FINDOBJ寻找具有指定的属性值的对象 H=FINDOBJ( ‘P1Name’ ,P1Value,…)返回根部和根部以下那些属性值与FINDOBJ参数 对相匹配的对象句柄。 H=FINDOBJ(ObjectHandles, ‘P1Name’ ,P1Value,…)搜索限定在ObjectHandles中列 出的对象和它们的子对象。 H=FINDOBJ(ObjectHandles, ‘flat’ , ‘P1Name’ ,P1Value,…)搜索限定在ObjectHandles 中列出的对象,不搜索它们的子对象。 H=FINDOBJ返回根对象和它所有的子对象的句柄。 H=FINDOBJ(ObjectHandles)返回ObjectHandles中列出的对象和它们的子对象的句柄。 参阅 SET,GET,GCF,GCA。 函数findobj返回符合所选判据的对象的句柄。它检查所有的 ‘Children’ ,包括坐标轴的标题和标志。如果没有对象满足指定的判据,findobj返回空距阵。 用函数findobj,前面的例子变成一行: ? Hl_green=findobj(0, ‘Type’ , ‘line’ , ‘Color’ ,[0 1 0]); 20.6用鼠标选择对象 gco命令返回当前对象的句柄,该对象就是用鼠标刚刚点击过的对象。然而,MATLAB怎么知道哪个对象被选中了呢?例如,当点击一幅图中两条线的交点时,应该返回哪个句柄?或者当鼠标点击时指针离线有多远仍能选中该线?这些答案要根据MATLAB选择对象规则和堆积次序。 堆积次序决定哪一对象叠加在其它对象上。开始时,堆积次序在对象被创建时就被决定,最后创建的对象在堆栈的顶部。例如,如果发出两条figure命令,就产生两个图形。第二个图画在第一个的上面。而最终的堆积次序是图2在图1的上面,当前图形gcf是图2。如果发出figure(1)命令,或者点击图1,堆积次序就改变,图形框架1移动到堆栈的顶端,成为当前图形。 在前面的例子中,在计算机屏幕上,堆放次序可以从窗口交叠中显而易见。但是,情况并不总是这样的。如果画了两条线,在它们的交叉点,第二条线在第一条线的上面。如果用鼠标在第一条线其它一些点上点击,那么第一条线条就在栈顶,用鼠标点击交叉点会选中第一条线。当前的堆积次序是由一个给定的对象 ‘Children’ 句柄出现的次序给出的。也就是说,? Hx_kids=get(handle, ‘Children’ )按堆积次序返回Children句柄。存储句柄的向量Hx_kids的第一个元素在栈顶,而最后一个元素在栈底。 除了堆积次序,当用鼠标在一个对象附近点击时,该对象也会被选中。每一种对象类型都有与之相关的它自己的选择区域。例如,对于一条线来说,如鼠标的指针在线条的5个象素之内,它就会被选中。曲面,补片和文本对象的选择区域是包含对象的最小矩形。坐标轴对象的选择区域是坐标框本身加上标题和标志出现的区域。坐标轴内的对象,例如线条和曲面,在堆积次序中处于较高地位。因此,点击它们时会选择相关的对象而不是坐标轴。选择坐标轴选择区以外的区间就会选中图形本身。 这里讨论的堆积次序和对象选择规则是针对MATLAB 4.02c的版本。但要注意,MATLAB定义、使用堆积次序和对象选择的方法在5.0版本中可能会扩充。 20.7 位置和单位 一个图形对象和许多其它句柄图形对象的位置属性 ‘ Position ‘ 是一个4元素的行向量。在该向量中的值是[left,bottom,width,height]。其中[left,bottom]是该对象相对于它的父对象的的左下角的位置,而[width,height]是该对象的宽度和高度。参阅图20.2。 图20.2 Position属性示意图 这些位置向量中的值的单位是由该对象的单位属性 ‘ Units ‘ )所指定的。例如: ? get(gcf, ‘Position’ ) ans= 360 544 560 420 ? get(gcf, ‘Units’ ) ans= pixels 表明了当前图形对象的左下角,相对于屏幕左下角的位置是:向右360个象素,向上544个象素;且图形对象的宽度为560个象素点,高度为420个象素点。要注意,位置向量给出的是图形本身的可画区域,它并不包括该窗口的边界、滚动条或标题条。 ‘Units’ 属性的缺省值是象素,但它也可以是英寸、厘米、点或归一化坐标。象素代表了屏幕象素,即在屏幕上可表示出来的最小的矩形对象。例如,一个分辨率设置为800×600的计算机显示区宽为800个象素,高为600个象素。点是一种打印设置标准,每一点等于1/72英寸。归一化坐标是在0到1范围内。在归一化坐标中,屏幕的左下角在[0 0],右上角在[1.0 1.0]。至于英寸和厘米是不言而喻的。 为了形象说明不同的 ‘ Units ‘ 属性值,重新考虑上面的例子。 ? set(gcf, ‘Units’ , ‘inches’ ); ? get(gcf, ‘Position’ ) ans = 3.7764 5.7203 5.8907 4.4245 ? set(gcf, ‘Units’ , ‘centimeters’ ) ? get(gcf, ‘Position’ ) ans = 9.5847 14.5185 14.9511 11.2297 ? set(gcf, ‘Units’ , ‘normalized’ ) ? get(gcf, ‘Position’ ) ans = 271.9001 411.8597 424.1339 318.5655 ? set(gcf, ‘Units’ , ‘normalized’ ) ? get(gcf, ‘Position’ ) ans = 0.2805 0.5303 0.4375 0.4102 对于特定的显示器,这些值代表了相对于计算机屏幕的相同位置。 坐标轴对象的位置也是四元素向量,具有同样形式[left,bottom,width,height]。但它指定的是相对于它的父对象图形左下角的位置。一般来说,一个子对象的 ‘ Position ‘ 属性的值是相对于其父对象的位置。 为了更好描述,计算机屏幕或根对象的位置属性不叫做 ‘ Position ‘ ,而叫做 ‘ ScreenSize ‘ 。这时,[left,bottom]总是[0 0],而[width,height]是计算机屏幕的尺寸,它的单位由根对象的 ‘ Units ‘ 属性指定。 20.8 图形打印 除了将图形放置在计算机屏幕上,MATLAB还提供了控制打印页上图形位置的属性,以及指定打印纸本身特性的属性。例如,MATLAB的orient命令使用函数get和set来改变打印纸属性。函数orient的帮助如下: ? help orient ORIENT Hardcopy paper orientation. ORIENT LANDSCAPE causes subsequent PRINT operation from the current figure window to generate output in full-page landscape orientation on the paper. ORIENT PORTRAIT returns to the default PORTRAIT orientation with the figure window occupying a rectangle with aspect ratio 4/3 in the middle of the page. ORIENT TALL causes the figure window to map to the whole page in portrait orientation. ORIENT ,by itself,returns a string containing the current paper orientation,either PORTRAIT,LANDSCAPE or TALL. ORIENT is an M-file that sets the PaperOrientation and PaperPosition properties of the current figure window. 帮助信息: ORIENT 硬拷贝纸张反向 ORIENT LANDSCAPE使得以后从该图形窗口的打印操作时,图形在打印纸上的设置为景象 方向的全幅方式。 ORIENT PORTRAIT使得以后从该图形窗口的打印操作时,图形在打印纸的中间占据一个肖 像方向4/3长宽比的矩形。 ORIENT TALL使得以后从该图形窗口的打印操作时,图形在在打印纸上的设置为肖像方向 的全幅方式。 ORIENT不加参数时,返回一个包含当前纸张设置的字符串,值为LANDSCAPE, PORTRAIT或TALL。 ORIENT 是一个M文件,它设置当前图形窗口对象中的PaperOrientation和PaperPosition属性。 参阅PRINT 影响打印输出的图形属性在表20.1中: 表20.1 图形的打印纸属性  PaperUnits [{inches}|centimeters|normalized|points]  PaperOrientati-on [{portrait}|landscape]  PaperPosition 位置向量,形式为[left,bottom,width,height]。[left,bottom]代表了从打印页左下角的偏移,[width,height]是图形尺寸  PaperSize 包含纸张尺寸([8.5 11])的两元素向量  PaperType [{usletter}|uslegal1|a3|a4letter|a5|b4|tabloid]   ‘PaperPosition’ 和 ‘PaperSize’ 属性的返回值的单位由 ‘PaperUnits’ 属性指定。与改变图形对象 ‘Position’ 属性以改变屏幕上图形窗口的大小和位置一样,改变 ‘PaperPosition’ 属性可以改变图形在打印页上的大小和位置。 考虑下面的例子,说明如何使用纸张属性。 ? set(gcf, ‘PaperType’ , ‘a4letter’ ) 将当前图形打印所用纸张设为 ‘ a4letter ‘ 。 ? set(gcf, ‘PaperOrientation’ , ‘landscape’ ) 将当前图形窗口的图的方向设为 ‘ landscape ‘ 。 象其它图形属性一样,上面的纸张属性用于单个图形。关于修改所有图形属性在下节“缺省属性”中进行讨论。 20.9 缺省属性 MATLAB在建立对象时把缺省属性赋给各对象。如果想不采用这些缺省值,那么,必须使用句柄图形工具对它们进行设置。当每次都要改变同一属性时,MATLAB允许设置用户自己的缺省属性。MATLAB让用户改变对象层次结构中任意一点上的单个对象或对象类型的缺省属性。 可以使用一个特殊性质名字符串来设置缺省值,该字符串以 ‘Default’ 开头,跟之以对象类型和属性名。使用set命令中的句柄,确定对象父—子等级图中的点,在该点使用缺省值。例如: ? set(0, ‘DefaultFigureColor’ ,[.5 .5 .5]) 将所有的新图形对象设为适中的灰色,而不是MATLAB缺省的黑色。该属性值应用于根对象(它的句柄总是0),所以所有新图形会有一个灰色的背景。 下面是另外一些可改变缺省值的例子。 ? set(0, ‘DefaultAxesFontSize’ ,14) % larger axes fonts - all figures ? set(gcf, ‘DefaultAxesLineWidth’ ,2) % thick axes lines - this figure ? set(gcf, ‘DefaultAxesColor’ , ‘y’ ) % yellow X-axis lines and labels ? set(gcf, ‘DefaultAxesGrid’ , ‘on’ ) % Y axis grid lines - this figure ? set(0, ‘DefaultAxesBox’ , ‘on’ ) % enclose axes - all figures ? set(gcf, ‘DefaultLineLineStyle’ , ‘:’ ) % dotted linestyle - these axes 当应用已存在对象工作时,使用后把它们恢复到初始的状态是一个很好的想法。如果想在一段例程中改变对象的缺省属性,那么保存原来的设置并在激活例程时将它们恢复。例如,考虑下面一段函数: oldunits=get(0, ‘DefaultFigureUnits’ ); set(0, ‘DefaultFigureUnits’ , ‘normalized’ ); <MATLAB statements> set(0, ‘DefaultFigureUnits’,oldunits); return 如果在所有的时刻用自己的缺省值来设定MATLAB,那么只要在startup.m文件里包括进所需的set命令就可以了。例如,如果在所有的轴上想要缺省的网格和坐标轴框,并且经常在A4纸上打印,就把下面这些行加到start.m文件中即可。 set(0, ‘DefaultAxesXGrid’ , ‘on’ ) set(0, ‘DefaultAxesYGrid’ , ‘on’ ) set(0, ‘DefaultAxesZGrid’ , ‘on’ ) set(0, ‘DefaultAxesBox’ , ‘on’ ) set(0, ‘DefultFigurePaperType’ , ‘a4paper’ ) 关于脚本M文件start.m的更详细的信息,可参阅第二章。 有三个特殊的属性值字符串 ‘remove’ 、 ‘factory’ 和 ‘default’ ,它们逆转、取消或获得用户自定义缺省属性。如果改变了一个缺省属性,可以使用 ‘remove’ 逆转这种变化,把它重新设为初始的缺省值。使用 ‘remove’ 说明如下: ? set(0, ‘DefaultFigureColor’ ,[.5 .5 .5]) % set a new default ? set(0, ‘DefaultFigureColor’ , ‘remove’ ) % return to MATLAB defaults 对一特殊对象,为了暂时取消缺省值并用最初的MATLAB缺省值,就用特殊的属性值 ‘factory’ 。例如: ? set(0, ‘DefaultFigureColor’ ,[.5 .5 .5]) % set a new user default ? figure( ‘Color’ , ‘factory’ ) % create a new figure using the MATLAB default 第三个特殊的属性值字符串是 ‘default’ 。这个属性值迫使MATLAB搜索对象层次结构,直到查到所需属性的一个缺省值。如果找到,它就使用该缺省值。如果查到根对象,没有找到用户定义的缺省值,MATLAB就使用factory缺省值。在用不同的属性值创建一个对象后,要把对象缺省设成缺省属性值时,这个概念是很有用的。为了弄清 ‘default’ 的使用,考虑下面的例子。 ? set(0, ‘DefaultFigureColor’ , ‘r’ ) % set the default at the root level ? set(gcf, ‘DefaultFigureColor’ , ‘g’ ) % current figure level default ? set(gca, ‘DefaultFigureColor’ , ‘b’ ) % current axes level default ? Hl_rand=plot(rand(size([1:10]))) % plot a yellow line ? set(H1_rand, ‘Color’ , ‘default’ ) % the line become blue ? set(gca, ‘DefaultFigureColor’ , ‘remove’ ) % the axes level default is removed ? set(Hl_rand, ‘Color’ , ‘default’ ) % the line become green ? close(gcf) % close the window ? Hl_rand=plot(rand(size([1:10]))) % plot a yellow line in a new window 1 ? set(Hl_rand, ‘Color’ , ‘default’ ) % the line becomes red 注意到plot命令并不对线的颜色设为线条对象的缺省值。如颜色参量未指定,plot命令使用坐标轴 ‘ColorOrder’ 属性来指定它所产生的每条线的颜色。 20.10 非文件式属性 用函数get和set对每一个对象列出的属性是文件式属性。也有由MATLAB开发者所用的非文件式属性。其中一些可以被设置,但另外一些是只读的。 每一对象类型的一个有用的非文件式属性是 ‘Tag’ 属性。这个属性用用户自定义的文本字符串来标志一个对象时有用。例如: ? set(gca, ‘Tag’ , ‘My axes’ ) 就把字符串 ‘My axes’ 加到当前图形的当前坐标轴。这个字符串不在图形或坐标轴中上显示出来,但可以查询 ‘Tag’ 属性来辨别对象。例如,有许多个坐标轴,可以通过 ? Ha_myaxes=findobj(0, ‘Tag’ , ‘My Axes’ ); 来寻找上面的坐标轴对象的句柄。象在下一章讨论的 ‘UserData’ 属性一样, ‘Tag’ 属性备作专门使用。没有任何MATLAB函数和M文件改变或对这些属性所含值作出假设。然而,如在下章要讨论的,有一些用户提供的M文件和几个精通MATLAB工具箱函数使用 ‘UserData’ 属性来存储临时数据。 由于一些非文件式属性是故意作成非文件式的,所以在使用时必须非常小心。它们有时比文件式属性脆弱,并且常常引起变化。在以后的MATLAB版本中,非文件式属性也许会仍保持或消失,或者改变功能,甚至会成为文件式属性。 在MATLAB 5.0中应变成文件式属性的非文件式属性列在表20.2中。 表20.2 属性 对象  ‘TerminalHideGraphCommand’ 根  ‘TerminalDimensions’ 根  ‘TerminalShowGraphCommand’ 根  ‘Tag’ 所有对象  ‘Layer’ 坐标轴  ‘PaletteModel’ 曲面,补片