第十九章 颜色的使用
MATLAB提供了许多在二维和三维空间内显示可视信息的工具。例如,看一条sin函数的曲线图就会比一堆数据提供更多的信息。这种用图表和图形来表示数据的技术叫做数据可视化。MATLAB不仅是一个强大的计算工具,并且在以引人入胜和直观方式可视地表示数据方面也很有特色。
但是很多时候,一个简单的二维或三维图形不能一次显示出想要提供的全部信息。这时,颜色可以对图形提供一个附加的维数。前面章节讨论的许多绘图函数都可以接受一个可用的颜色参量,来增加这附加的维数。
本章的讨论以研究颜色映象开始:如何使用、显示、修改和如何创建用户自己的颜色映象。然后,阐述在一个图形窗口中仿真多个颜色映象的技术或只使用颜色映象的一部分的技术。最后,讨论照明模型并提供例子。
19.1 颜色映象理解
MATLAB有一个叫颜色映象的数据结构来代表颜色值。颜色映象定义为一个有三列和若干行的矩阵。利用0到1之间的数,矩阵的每一行都代表了一种色彩。任一行的数字都指定了一个RGB值,即红、黄、蓝三种颜色的强度,形成一种特定的颜色。一些有代表性的RGB值在表19.1中给出。
表19.1
简单颜色
Red(红)
Green(绿)
Blue(蓝)
颜色
0
0
0
黑
1
1
1
白
1
0
0
红
0
1
0
绿
0
0
1
蓝
1
1
0
黄
1
0
1
洋红
0
1
1
青蓝
2/3
0
1
天蓝
1
1/2
0
橘黄
.5
0
0
深红
.5
.5
.5
灰色
有十个MATLAB函数产生预定的颜色映象。见表19.2
表19.2
标准颜色映象
hsv
色彩饱和值(以红色开始和结束)
hot
从黑到红到黄到白
cool
青蓝和洋红的色度
pink
粉红的彩色度
gray
线性灰度
bone
带一点蓝色的灰度
jet
hsv的一种变形(以蓝色开始和结束)
copper
线性铜色度
prim
三棱镜。交替为红色、橘黄色、黄色、绿色和天蓝色
flag
交替为红色、白色、蓝色和黑色
按缺省,上面所列的各个颜色映象产生一个64×3的矩阵,指定了64种颜色RGB的描述。这些函数都接受一个参量来指定所产生矩阵的行数。比如hot(m)产生一个m×3的矩阵,它包含的RGB颜色值的范围从黑经过红、橘红和黄,到白。
大多数计算机在一个8位的硬件查色表中一次可以显示256种颜色,当然有些计算机的显示卡可以同时显示更多的颜色。这就意味着在不同的图中,一般一次可以用三或四个64×3的颜色映象。如果使用了更多的颜色映象输入项,计算机必须经常在它的硬件查色表中调出输入项。比如,当在画MATLAB图形时背景图案发生了变化,就是发生了这种情况。所以,除非计算机有一次显示更多种颜色的显示卡,最好任何一次所用的颜色映象输入项数都小于256。
19.2 颜色映象使用
语句colormap(M)将矩阵M作为当前图形窗口所用的颜色映象。例如,colormap(cool)装入了一个有64个输入项的cool颜色映象。colormap default装入了缺省的颜色映象(hsv)。
函数plot、plot3、contour和contour3不使用颜色映象,它们使用列在plot颜色和线形表中的颜色。而大多数其它绘图函数,比如mesh、surf、fill、pcolor和它们的各种变形函数,使用当前的颜色映象。
接受颜色参量的绘图函数中的颜色参量通常采用以下三种形式之一:(1)字符串。代表plot颜色或线型表中的一种颜色,比如,’ r ‘代表红色;(2)三个输入的行向量。它代表一个单独的RGB值,比如[.25,50,75];(3)矩阵。如果颜色参量是一个矩阵,其元素作了调整,并把它们用作当前颜色映象的下标。最后一种形式会在以后作更多讨论。
19.3 颜色映象显示
可以用多种途径来显示一个颜色映象。其中一个方法是观察颜色映象矩阵的元素。
? hot(8)
ans =
0.3333 0 0
0.6667 0 0
1.0000 0 0
1.0000 0.3333 0
1.0000 0.6667 0
1.0000 1.0000 0
1.0000 1.0000 0.5000
1.0000 1.0000 1.0000
上面的数据显示出第一行是1/3红色,而最后一行是白色。另外,函数pcolor可以用来显示一个颜色映象。例如:
? n=16;
? colormap(jet(n))
? pcolor([1:n+1;1:n+1]’ )
? title( ‘Using Pcolor to Display a Color Map’ )
输出见图19.1.

图19.1 用伪彩色来显示颜色映象
因为上面这一段程序很有用处,它已经装入精通MATLAB工具箱中的函数mmshow中。
? help mmshow
MMSHOW PCOLOR Colormap Display
MMSHOW uses pccolor to display the current colormap.
MMSHOW(MAP) displays the colormap MAP.
MMSHOW(MAP(N)) displays the colormap MAP having N elements.
Examples:MMSHOW(hot)
MMSHOW(pink(30))
帮助信息:
MMSHOW 显示PCOLOR颜色映象
MMSHOW 使用pcolor来显示当前颜色映象
MMSHOW(MAP) 显示MAP颜色映象
MMSHOW(MAP(N)) 显示一个有N个元素的MAP颜色映象
例子:MMSHOW(hot)
MMSHOW(pink(30))
函数mmshow取和colormap同样的输入参量,但在这种情况下它用自己的伪彩色显示而不是把颜色映象施加到当前图形。
另一种途径是使用MATLAB的函数rgbplot,它可以把颜色映象的各列分别画成红、绿和蓝色。例如:
? rgbplot(hot)
输出见图19.2.

图19.2 用红、绿和蓝色画颜色映象
图中显示红色分量首先增加,然后是绿色,最后是蓝色。rgbplot(gray)表示所有三列数据均匀线性地增加(三条线重叠)。
最后,函数colorbar在当前的图形窗口中增加水平或垂直的颜色标尺以显示当前坐标轴的颜色映象。 colorbar( ‘horiz’ ) 在当前的图形下面放一个水平的颜色条。 colorbar( ‘vert’ ) 在当前的图形右边放一个垂直的颜色条。对无参量的colorbar,如果当前没有颜色条就加一个垂直的颜色条,或者更新现有的颜色条。下面的例子就演示了colorbar的用法。
? [x,y,z]=peaks;
? mesh(x,y,z);
? colormap(hsv)
? axis([-3 3 -3 3 -6 8])
? colorbar
输出见图19.3.

图19.3 使用颜色条
19.4 颜色映象的建立和修改
颜色映象就是矩阵,意味着你可以象其它数组那样对它们进行操作。函数brighten就利用这一点通过调整一个给定的颜色映象来增加或减少暗色的强度。brighten(n)(0<1<=1)使当前颜色映象变亮;而brighten(n)(-1<=n<0)使它变暗。brighten(n)后加一个brighten(-n)使颜色映象恢复原来状态。newmap=brighten(n) 命令创建一个比当前颜色映象更暗或者更亮的新的颜色映象,而并不改变当前的颜色映象。命令? newmap=brighten(cmap,n)对指定的颜色映象创建一个已调整过的式样,而不影响当前的颜色映象或指定的颜色映象cmap。
可以通过生成m×3的矩阵mamap来建立用户自己的颜色映象,并用colormap(mymap)来安装它。颜色映象矩阵的每一个值都必须在0和1之间。如果企图用大于或小于3列的矩阵或者包含着比0小比1大的任意值,函数colormap会提示一个错误然后退出。
也可以在算术上来组合颜色映象,虽然结果有时是不可预料的。比如,一个叫pink的颜色映象仅仅是:
? pinkmap=squr(2/3*gray+1/3*hot);
只当所有元素都在0与1之间时,才能保证结果是一个有效的颜色映象。精通MATLAB工具箱中包含了一个名叫rainbow的颜色映象,它把可视范围扩展到整个颜色映象。函数rainbow的在线帮助为:
? help rainbow
RAINBOW Colormap varient to HSV.
RAINBOW(M) Rainbow Colormap with M entries.
Red-Orange-Yellow-Green-Blue-Violet
RAINBOW by itself is the same length as the current colormap.
Apply using,colormap(rainbow)
帮助信息:
RAINBOW HSV颜色映象的变形
RAINBOW(M) 有M个入口项的RAINBOW颜色映象
红—橘黄—黄—绿—蓝—天蓝
RAINBOW本身和当前颜色映象的长度相同
应用:colormap(rainbow)
精通MATLAB工具箱中还包含了一个名叫mmap的函数,它可以根据你所提供的颜色建立一个单色(比如粉红、灰色或铜黄色)的颜色映象。函数mmap的在线帮助是:
? help mmap
MMAP Single Color Colormap.
MMAP(C,M) makes a colormap of length M starting with the basic colorspec C.The map changes from dark to light.
MMAP(C) is the same length as current colormap.
Examples:mmap( ‘y’ ) is a yellow colormap.
mmap([.49 1,83]) is an aquamarine colormap.
mmap( ‘c’,20) is a cyan colormap having length 20.
帮助信息:
MMAP 单色颜色映象
MMAP(C,M) 制作一个以颜色C为基色的长度为M的颜色映象。该表的颜色从暗到明 变化。
MMAP(C) 颜色映象的长度和当前颜色映象相同
例子:mmap( ‘y’ )是一个黄色颜色映象
mmap([.49 1,83])是一个水色的颜色映象
mmap( ‘c’,20)是一个长度为20的青蓝色的颜色映象
应用:colormap(mmap(c,m))
一个颜色映象定义了用于绘制图形的调色板。一个缺省的颜色映象允许对数据使用64种不同的RGB值。MATLAB使用函数cxis来决定哪一个数据值映射到颜色映象中输入项。
通常,颜色映象进行过调节,把数据从最小扩展到最大,也就是说整个颜色映象都用于绘图。有时也许想改变颜色使用的方法。函数caxis代表颜色轴,因为颜色增加了另一个维数,它允许对数据范围的一个子集使用整个颜色映象或者对数据的整个集合只使用当前颜色映象的一部分。
[cmin,cmax]=caxis返回映射到颜色映象中第一和最后输入项的最小和最大的数据。它们通常被设成数据的最小值和最大值。比如,函数mesh(peaks) 会画出函数peaks的网格图,并把颜色轴caxis设为[-6.5466,8.0752],即Z的最小值和最大值。这些值之间的数据点,使用从颜色映象中经插值得到的颜色。
caxis([cmin,cmax])对cmin和cmax范围区内的数据使用整个颜色映象。比cmax大的数据点用与cmax值相关的颜色绘图,比cmin小的数据点的颜色用与cmin值相关的颜色绘图。如果cmin小于min(data)和/或cmax大于max(data),那么与cmin和/或cmax点相关的颜色将永远用不到。也就是说,只用到和数据相关的那一部分颜色映象。 caxis( ‘auto’ )设置cmin和cmax的缺省值。
由于下面的例子很难在书中清晰区分灰度,运行脚本M文件mmcaxisd.m可显示所包含的一系列更多的例子。缺省的颜色范围由下例说明:
? pcolor([1:17;1:17]’ ),colormap(hsv(8))
? title( ‘Default Color Range’ )
? caxis( ‘auto’ )
? colorbar
? caxis
ans =
1 17
输出见图19.4.

图19.4 缺省的颜色范围
可见对整个数据集合,当前颜色映象使用了所有8种颜色。每种颜色有两条。如果颜色被映射到从-3到23的数据,那么,图中只用到五种颜色。这可以通过下面的命令实现:
? title( ‘Extended Color Range’ )
? caxis([-3,23]) % extended the color range
? colorbar % redraw the color scale
输出见图19.5.

图19.5 扩展的颜色范围
如果颜色映射到从5到12的值,会用到所有的颜色。但是,比5小的数据和比12大的数据分别映射到与数据值5和12相关的颜色。这可以通过下面的命令产生:
? title( ‘Restricted Color Range’ )
? caxis([5,12]) % resstrict the color range
? colorbar % redraw the color scale
输出见图19.6.

图19.6 受限的颜色范围
19.5 图形中使用一个以上的颜色映象
有时,在一幅图的不同部分使用不同的颜色是很有作用的。由于颜色映象是图形窗口本身的一个属性,在任意一个图形窗口中,只能用一个颜色映象。但是,可以创建自己的颜色映象来达到想要的效果。例如,精通MATLAB工具箱中含有脚本M文件mmcmapd.m,它执行下述操作。
? figure % create a figure window
? mymap=[rainbow(32);copper(32)]; % stack two color maps into one
? colormap(mymap) % install it
? mesh(peaks+8);view(0,0); % create two sample polots
? hold on ;mesh(peaks-8);
? colorbar % and add a color scale
? title( ‘Merging two colormaps’ )
? hold off
输出见图19.7.
图19.7 合并两个颜色映象
19.6 用颜色描述第四维
一些函数,比如mesh和serf,除非给出颜色参量,颜色将沿z轴数据变化。比如,surf(X,Y,Z)等效于surf(X,Y,Z,Z)。将颜色施加于z轴能够产生色彩漂亮的图画,但由于z轴已经存在,它并不提供新的信息。为更好的利用颜色,建议用颜色来描述不受三个轴影响的数据的某些属性。为此需要赋给三维作图函数的颜色参量不同的数据。
如果作图函数的颜色参量是一个向量或矩阵,那么就用作颜色映象的下标。这个参量可以是任何实向量或与其参量维数相同的矩阵。考虑下面这些例子:
? x=-7.5,.5,7.5; y=x; % create a data set - the frame scmbrero
? [X Y]=meshgrid(x,y); % create placid data
? R=sqrt(X.^2+Y.^2)+eps;
? Z=sin(R)./R
? surf(X,Y,Z,Z) % default color order
? surf(X,Y,Z,-Z) % reverse the default color order
? surf(X,Y,Z,X) % color varies along the X-axis
? surf(X,Y,Z,X+Y) % color varies along the XY diagonal
? surf(X,Y,Z,R) % color varies radially from the center
? surf(X,Y,Z,abs(del2(Z))) % color varies with absolute value of Laplacian
? [dZdx,dZdy]=gradient(Z); % compute gradient or slope of surface
? surf(X,Y,Z,abs(dZdx)) % color varies with absolute slope in x-direction
? surf(X,Y,Z,abs(dZdy)) % color varies with absolute slope in y-direction
? dz=sqrt(dZdx.^2+dZdy.^2);
? surf(X,Y,Z,dZ) % color varies with magnitude of slope
输出分别见图19.8、图19.9、图19.10、图19.11、图19.12、图19.13和图19.14.

图19.8 surf(X,Y,Z,Z)

图19.9 surf(X,Y,Z,-Z)

图19.10 surf(X,Y,Z,X)

图19.11 surf(X,Y,Z,X+Y)

图19.12 surf(X,Y,Z,R)

图19.13 surf(X,Y,Z,abs(del2(Z)))

图19.14 surf(X,Y,Z,dZ)
图19.15 surf(X,Y,Z,abs(dZdx))
图19.16 surf(X,Y,Z,abs(dZdy))
注意到上面后五个例子中,颜色如何为所画的曲面提供了一个附加的维数。函数del2是离散拉氏函数,它根据表面弯曲程度来使用颜色。函数del2描述如下:
? help del2
DEL2 Five-point discrete Laplacian.
V=del2(U) is a matrix the same size as U with each element equal to the difference
between an element of U and the average of its four neighbours.For the,corners” and “edges”,only two or three neighbours are used.
See also GRADIENT,DIFF

帮助信息:
DEL2 五点的离散Laplacian
V=del2(U)是一个和U同样大小的矩阵。它的每个元素是U中的对应位置的元素和它 的 四个相邻点元素的平均值的差值。对于角上和边上的元素,只使用两个或三个相邻点。
参阅函数:GRADIENT,DIFF
如上述,函数gradient逼近表面的梯度或坡度。为了方便,通过运行精通MATLAB工具箱中的脚本M文件mm4d,便可执行上述命令。
19.7 照明模型
基于运用漫射、镜面反光和环境照明模型,函数surfl画出了一个类似于函数surf产生的带彩色的曲面。使用一个单色颜色映象(如灰色,纯白,铜黄或粉红色)和插值色彩,会画出效果最好的曲面。
正常的参量表为surfl(X,Y,Z,S),这里X,Y和Z与surf(X,Y,Z)相同。而S以[Sx,Sy,Sz]或[az,el]的形式定义了光源的方向。如果没有指明,其缺省光源是逆时针45度,即从现在的视角向右转45度。
环境照明,漫射反射,镜面反光对视觉效果的相对贡献以及镜面扩展因子可以通过K=[ka,kd,ks,spread]的五个元素来设定,这里K是函数surfl的第五个参量,即surfl(X,Y,Z,S,K)。K的缺省值是[.55,6,4 10]。为了了解这些参量如何影响图形照明,可以参阅下面这些例子。
? [X,Y,Z]=peaks(32); % data to plot
? surfl(X,Y,Z),colormap(copper),title( ‘Default Lighting’ ),shading interp
? surfl(X,Y,Z,[7.5 30],[.55,6,4 10]),shading interp
? surfl(X,Y,Z,[-90 30],[.55,6 2 10]),shading interp
如前所述,插值上色会极大地降低打印速度。这是因为每一象素都有一个不同的颜色值,打印机对每点都要分别地上色。
19.8 小结
本章所用的函数总结在表19.3、表19.4、表19.5和表19.6中。
表19.3
简单颜色
Red(红)
Green(绿)
Blue(蓝)
颜色
0
0
0
黑
1
1
1
白
1
0
1
红
0
1
0
绿
0
0
1
蓝
1
1
0
黄
1
0
1
洋红
0
1
1
青蓝
2/3
0
1
天蓝
1
1/2
0
橘黄
.5
0
0
深红
.5
.5
.5
灰色
表19.4
标准颜色映象
hsv
色彩饱和值(以红色开始和结束)
hot
从黑到红到黄到白
cool
青蓝和洋红的色度
pink
粉红的彩色度
gray
线性灰度
bone
带一点蓝色的灰度
jet
hsv的一种变形(以蓝色开始和结束)
copper
线性铜色度
prim
三棱镜。交替为红色、橘黄色、黄色、绿色和天蓝色
fag
交替为红色、白色、蓝色和黑色
表19.5
在surf,mesh和pcolor图中作第四维的颜色
surf(X,Y,Z,fun(X,Y,Z))
根据函数fun(X,Y,Z)来施加颜色
surf(X,Y,Z)=surf(X,Y,Z,Z)
缺省动作,加颜色于Z轴
surf(X,Y,Z,X)
加颜色于X轴
surf(X,Y,Z,Y)
加颜色于Y轴
surf(X,Y,Z,X.^2+Y.^2)
根据z=0平面距原点(x=0,y=0)的距离施加颜色
surf(X,Y,Z,del2(Z))
根据曲面的拉氏函数值施加颜色
[dZdx,dZdy]=gradient(Z);
surf(X,Y,Z,abs(dZdx))
根据X轴方向的曲面斜率施加颜色
dz=sqrt(dZdx.^2+dZdy.^2);
surf(X,Y,Z,dz)
根据曲面斜率大小施加颜色
表19.6
颜色和照明函数
colormap(map)
在当前的图形窗口中安装一个颜色映象
coorbar
在当前的图形上显示一个水平的或垂直的颜色标尺
rgbplot(map)
颜色映象中红、绿、蓝分量的直线图
brighten(a)
0<a<1,当前颜色映象加亮;-1<a<0,当前颜色映象加暗
m=brighten(map,a)
返回加亮的颜色映象m
[cmin,cmax]=caxis
返回颜色轴的界限
caxis([cmin,cmax])
设置颜色轴的界限
关键词索引
chap 19
data visualization 数据可视化
lighting model 照明模型
hardware color lookup table 硬件查色表
entry 输入项
color scale 颜色标尺
color bar 颜色条
dark color 暗色
color axis 颜色轴
discrete Laplacian function 离散拉氏函数
diffuse 漫射
specular 镜面反光
ambient lighting model 环境照明模型
specular-spread coefficient 镜面扩展因子