



图形(Graph)和图表(Chart)是LabVIEW用于图形显示的控件。考虑到以下几点原因,在本章对它们进行简要介绍:
(1)图形显示对于虚拟仪器项目来说非常重要。
(2)图形和图表的操作涉及数组和簇的概念,因此放在簇的讲解之后,更容易使读者接受。
(3)在数组和簇的概念后讲解图形和图表的操作,可以使读者更多地了解数组和簇的使用方法。
在LabVIEW的图形显示功能中,图形和图表是两个基本概念,二者的区别在于各自不同的数据显示和更新方式。一般来说,Graph用于对已采集数据进行事后处理。含有Graph控件的VI通常先将数据采集到数组中,再将数据绘制到Graph控件中。Graph控件绘制数据过程类似于在Excel中绘图,即先存储数据,再生成数据的曲线。数据绘制到Graph上时,它不显示之前绘制的数据,而只显示当前的新数据。Graph一般用于连续采集数据的快速过程。它的缺点是没有实时显示,但是它的表现形式要丰富得多。例如采集一个波形后,经处理可以显示其频谱图。
与Graph相反,Chart用于将数据源(例如采集得到的数据)在某一坐标系中,实时地显示出来。Chart是把新获得的数据点追加到已显示的数据上形成数据历史记录,因此可反映被测物理量的变化趋势。在Chart中,可结合先前采集的数据查看当前读数或测量值。当在Chart中新增数据点时,绘制的曲线将会滚动显示,即Chart右侧将出现新增的数据点,同时旧数据点在左侧消失。Chart一般用于每秒只增加少量数据点的慢速过程,这与传统的模拟示波器、波形记录仪非常相似。由于中文图形和图表从字面意义上容易混淆,且较难区分它们在显示和更新方式上的差异,因此建议在实际使用中不对这两种控件名做中文翻译,直接称为Graph和Chart即可。
LabVIEW的控件箱中有多种风格的Graph和Chart控件可供选用,包括“NXG风格”(NXG Style)、“银色”(Silver)、“经典”(Classic)和“现代”(Modern)风格。这些控件在使用上略有不同,表3-7列出了一些常用的控件。由表3-6可以看出,Chart尽管能实时、直接地显示结果,但其表现形式非常有限;相反,Graph的表现形式虽然丰富,但却牺牲了实时性。
表3-7 LabVIEW Graph控件
 
   波形图表(Waveform Chart)是显示一条或者多条曲线的特殊数值控件,一般用于显示以恒定速率采集的数据。Waveform Chart会在缓冲区保留历史数据并在历史数据后添加新数据。Waveform Chart的默认数据缓冲区大小为1024个数据点(右击图形表,从弹出的菜单中选择“图形表历史长度”选项可配置缓冲区大小)。在Waveform Chart上用户可以实时看到当前的数据和历史数据,向Waveform Chart传送数据的频率决定了它重绘的频率。当要显示的数据超出显示范围时,Waveform Chart控件会自动滚屏,它通常用于处理的数据量较小,但需对数据进行实时查看的情况。
Waveform Chart有三种刷新模式,如图3-44所示。右击控件,在弹出的菜单中选择“高级”→“刷新模式”选项,即可选择以下几种绘图模式。
(1)带状(Strip):从左到右连续滚动地显示运行数据,类似于纸带表记录器。
(2)示波器(Scope):当曲线到达绘图区域的右边界时,LabVIEW将清除已经绘制的图形,并从左边界开始绘制新图形,类似于示波器。
(3)扫描(Sweep):扫描模式下,显示控件中有一条垂线将右边的旧数据和左边的新数据隔开。类似于心电图绘图仪。
 
    图3-44 Waveform Chart的三种绘图模式
有时需要在相同的纵坐标下,将几条曲线显示在同一个图区,这时可以组织出一种纵坐标相同、而有各自横坐标的堆叠式图区,这种情况称为堆叠图表(Stack Plots)。可通过右击图表控件,在弹出的菜单中选择“堆叠图表”选项进入堆叠图表模式。要使用Waveform Chart显示多条曲线,可将多条曲线数据捆绑成簇再传递给控件,如图3-45所示。
 
    图3-45 Waveform Chart中显示多条曲线
波形图形(Waveform Graph)控件的显示和更新方式与Waveform Chart不同,它通常先缓冲所有数据至数组中,然后一次性绘图。当数据被绘制后,会丢弃先前绘制过的数据,显示新数据。Waveform Graph控件支持多种数据类型,可以有效降低数据在显示为图形前进行类型转换的工作量,从而提高程序的运行效率,通常用于在数据连续采集的项目中,进行曲线的快速实时绘制。
在使用Waveform Graph控件显示单个曲线时,一般使用数组或包含初始 x 值、 x 值的增量信息dx和 y 值数组的图形数据簇。对于数值数组,每个数据被视为图形中的点,从 x =0开始,以1为增量递增 x 索引。若传递的数据为簇,图形控件就以 x 初始值开始,以增量信息dx为步长,将 y 值数组中的值逐个绘制出来。图3-46所示实例使用For循环生成 y 数值数组,并分别以数组和簇的方式将数据传递至图形控件进行显示。在使用簇方式时, x 轴的初始值为10,增量dx为2。
 
    图3-46 在Waveform Graph中显示多条曲线
要在Waveform Graph控件中显示多条曲线,可以将代表各条曲线的数据合成多维数组输入至控件进行绘制。具体方法如图3-47所示。
 
    图3-47 在Waveform Graph中显示多条曲线
在Waveform Graph控件中显示多条曲线的方法可以概括为以下几种。
(1)将代表各条曲线的数组进一步组合成多维数组传递给Waveform Graph控件。数组中的一行即一条曲线,Waveform Graph将数组中的数据视为图形上的点,从 x = 0开始,以1为增量递增 x 索引(图3-47(a))。
(2)将代表各条曲线的数组分别打包为簇,再以各簇为元素构建数组传递给Waveform Graph控件。曲线数组中每个元素为一个簇,该簇中包含一个 y 数据的一维数组(图3-47(b))。如果每条曲线所包含的元素个数不同,例如,从几个通道采集数据且每个通道的采集时间不同,那么就应该使用以簇为元素的曲线数组而不是二维数组。这是因为二维数组每行中的元素个数必须相同;而簇数组内部数组的元素个数可以不同。
(3)将包含初始 x 值、dx及 y 数据数组的簇数组传递给Waveform Graph控件。绘制多条曲线时经常使用这种数据类型,用它可灵活指定唯一的起始点和每条曲线的 x 标尺增量(图3-47(c))。
(4)Wav eform Graph还支持动态数据类型,该数据类型常用于Express VI。动态数据类型除了包括与信号相关的数据外,还包括提供信号信息的属性(例如,信号名称或数据采集的日期和时间等)。属性指定了信号在图形中的显示方式。当动态数据类型包含多个通道时,图形为每个通道数据显示一条曲线,并自动格式化标绘图例和 x 标尺的时间标识。
特别地,LabVIEW为信号处理过程中各种图形的显示,提供“波形”(Wave form)数据簇类型,包括模拟波形(Anal og Waveform)和数字波形(Digi tal Waveform),如图3-48所示。它们可以在Express VI使用过程中转换为动态数据类型。一个波形数据类型的一维数组可表示多个波形。
LabVIEW在默认状态下以模拟波形数据簇和数字波形数据簇分别表示模拟和数字波形。模拟波形数据簇类型以时间为横轴,同时封装了起始时间和时间增量变化信息,以及各时间点上的 y 值数组。起始时间t0是相对于波形中第一个测量点的时间标识,用于同步一个多曲线波形图或多曲线数字波形图上的曲线,并用于指定波形之间的延迟。增量变化信息dt是信号中两个点之间的间隔,以秒为单位。 y 值数组中的数值用于表示波形的值,其中数据的数量通常与数据采集设备的扫描次数直接对应。
 
    图3-48 模拟和数字波形数据簇
数字波形数据簇类型包括起始时间、时间增量信息和表格形式表示的数字数据,用于表示一个数字波形。表格数字数据中从右到左的每一列代表一个通道中的数字数据,在数字图形控件中显示为行。波形数据还可以包含信号的各种信息,如信号名称、采集信号的设备等,这些信息成为波形的属性。NI数据采集软件可自动设置某些属性。LabVIEW提供专门的VI,用于访问和操作波形数据及其属性(位于LabVIEW的Programing→Waveform函数子选版中),以简化与之相关的开发工作,如创建波形数据、读取和设置波形属性等。图3-49显示了一个构建带有属性元素波形数据簇的实例。
 
    图3-49 构建带有属性元素波形数据簇的实例
XY图形(XY Graph)控件是对一维Graph图形控件的扩展,可以通过在程序中指定二维曲线的 x 、 y 的坐标值来画出曲线。这意味着XY Graph可用于绘制诸如圆形的多值函数或 x 轴增量不均匀的可变时基波形。XY Graph可显示任何均匀采样或非均匀采样的点的集合。
XY Graph接受以下三种类型的数据,以绘制单条曲线:
(1)由 x 值数组和 y 值数组构成的簇表示一条曲线。
(2)用以簇为元素的数组代表一条曲线,其中每个簇元素由单个点的 x 值和 y 值构成。
(3)复数数组,其中 x 轴和 y 轴分别是虚数的实部和虚部。
若要在XY Graph中显示多条曲线,则需要将各曲线的数据打包为数组,然后再作为XY Graph的输入,具体来说主要包括以下几种方法:
(1)每条曲线数据由包含 x 值数组和 y 值数组的一个簇构成。将多个代表单条曲线的簇作为元素先构成数组,再输入XY Graph进行显示。
(2)每条曲线数据由一个点数组构成,每个点是包含该点 x 值和 y 值的簇。将多个代表单条曲线的点数组先分别打包为簇,再作为元素构成数组,输入XY Graph进行显示。此处将点数组打包成簇的目的,是为了将可能不同类型和长度的数组先统一为同一类型,这样才能将其作为数组元素。
(3)XY Graph也接收曲线簇数组,其中每条曲线是一个复数数组, x 轴和 y 轴分别显示复数的实部和虚部。
图3-50给出了一个使用XY Graph的实例。程序中For循环负责生成每个点的 x 、 y 值,四种图形绘制方法的结果分别显示在不同的XY Graph控件中。下面对四种绘制方法分别进行介绍。
 
    图3-50 XY Graph的四种图形绘制方法
(1)将每个点的坐标捆绑为簇,再将代表每个点的簇作为数组元素,构成代表单个曲线的数组,传递给XY Graph,如图3-51(a)所示。
(2)将两个与(1)中所述结构类似的数组构成二维数组,传递给XY Graph,画出两条曲线,如图3-51(b)所示。
(3)将代表 x 坐标的一维数组和代表 y 坐标的一维数组捆绑为簇,直接传递给XY Graph,如图3-51(c)所示。
(4)将两个与(3)中所述结构类似的数组构成二维数组,传递给XY Graph,画出两条曲线,如图3-51(d)所示。
 
    图3-51 使用XY Graph绘制的效果
二维图形(2D Graph)控件是一些比较常用的特殊的XY Graph控件,主要包括位于LabVIEW控件工具箱中Modern→Graph选项中的几种,如图3-52所示。
(1)罗盘图(Compass Plot):绘制由罗盘图形的中心发出的向量。
(2)误差线图(Error Bar Plot):绘制线条图形上、下各点的误差线。
(3)羽状图(Feather Plot):绘制由水平坐标轴上均匀分布的点发出的向量。
(4)XY曲线矩阵(XY Plot Matrix):绘制多行和多列曲线图形。
与一般的XY Graph不同,当在前面板添加二维图形控件时,LabVIEW并不仅仅在后面板上放置与之对应的图标,还会将图标连接至与所选图形对应的一个“助手”(Helper VI)。Helper VI封装了将输入数据类型转换为2D Graph可接受的通用数据类型的处理过程。这种封装过程基于LabVIEW面向对象程序设计技术,会使用类和对象等高级数据类型和操作,相关细节将在第13章进行讲解。
 
    图3-52 LabVIEW二维图形控件
使用类和对象对相关实现细节进行封装后,开发人员在使用这些2D Graph时就不必再关心这些细节,只需传递输入数据即可。若要修改2D Graph的显示方式,可以使用程序修改其属性来完成。图3-53显示了2D羽状图的实例。程序先通过属性将羽状线的宽度更改为2,然后再将两个羽状图的数据传递给Plot Helper VI,该VI使用这些数据创建羽状图的类对象,完成数据转换等处理后将两个羽状图先后绘制在同一幅图中。
 
    图3-53 2D羽状图实例
大量实际应用中的数据,需要在三维空间进行可视化显示。如研究某个平面的温度分布或飞机的运动等。LabVIEW提供两类三维图形(3D Graph)控件,一类基于面向对象技术,另一类基于ActiveX技术。基于面向对象技术的3D Graph控件与2D Graph控件类似,使用类对象封装了数据类型转换和操作过程,以方便开发人员直接使用。这些控件位于LabVIEW控件工具箱Modern→Graph→3D Graph选项下。基于ActiveX技术的控件位于LabVIEW控件工具箱Classic→Graph选项下。表3-8是对这些控件的汇总及简要描述。
表3-8 LabVIEW两类3D Graph控件汇总
 
   基于面向对象技术的3D Graph控件的使用方法与2D Graph控件的使用方法类似。当在前面板添加3D Graph控件后,LabVIEW会自动在程序框图上放置相应的Helper VI,并将其与3D Graph控件的图标相连。要绘制的数据传递给控件后,Helper VI会将输入数据类型转换为3D Graph接受的通用数据类型进行绘制。也可以在设计时通过右击控件,从弹出的菜单中选择3D Plot Property选项,调出三维图形属性对话框,对绘图过程进行配置。读者可以参考LabVIEW自带的Math Plot-3D实例(代码也可在本书代码中找到)进一步了解其使用方法,此处不再赘述。图3-54显示了Math Plot-3D实例的绘图结果。
ActiveX 3D Graph控件基于ActiveX技术进行三维图形的绘制。选择一个ActiveX三维图形后,LabVIEW将在包含3D Graph控件的前面板上添加一个ActiveX容器。同时还会在程序框图上放置一个对ActiveX 3D Graph控件的引用。根据选择的控件不同,LabVIEW会将该引用连接至3D Surface.vi、3D Parametric.vi或3D Line.vi这三个VI中的一个,完成图形绘制。ActiveX技术将在第13章进行详细介绍,读者可在阅读完第13章后,进一步了解ActiveX 3D Graph控件的实现原理。即使不了解ActiveX技术,也不影响ActiveX 3D Graph控件的使用。
 
    图3-54 Math Plot-3D实例的绘图结果
强度图形(Intensity Graph)和强度图表(Intensity Chart)通过在平面上放置颜色块的方式在二维图上显示三维数据。例如,温度图和地形图(以量值代表高度)的图形数据。Intensity Graph和Intensity Chart以一个包含颜色索引的二维数组和一个定义颜色映射的一维数组作为输入,其中二维数组索引可表示图形颜色的位置,而每一个数值代表一个特定的颜色。默认情况下,数据行在Intensity Graph或Intensity Chart上以列的形式显示,数组索引与颜色块的左下角顶点对应,且最多可显示256种不同颜色。图3-55的实例演示了Intensity Graph的显示原理(Intensity Chart的原理与之相同)。如果希望以行的方式显示数据,可右击该强度图形或图表,从弹出的菜单中选择“转置数组”(Transpose Array)选项进行设置。
 
    图3-55 Intensity Graph显示原理及实例
Intensity Graph和Intensity Chart所显示的颜色与定义颜色映射的一维数组中的数值一一对应。通过Intensity Graph或Intensity Chart的Z标尺标记值属性ZScale.MarkerVals[ ],可用编程方式设置其颜色映射。该属性是一个簇数组,其中每一个簇包含一个索引数值和一个与之对应的显示颜色。通常来说,该属性中包括最小、最大和中值索引及它们分别对应颜色的三个簇元素。也可以指定更多元素来更准确地定义颜色映射,但数组中簇元素的个数应至少为两个,包括最小和最大索引及其对应颜色。以这种方式设定颜色映射时,还可通过Z标尺的属性设置超出索引范围的颜色属性。包括大于最大索引的颜色(ZScale.HighColor属性)和低于最小索引的颜色(ZScale.LowColor属性)。因此,包含两个超出范围的颜色设定值在内,强度图形和强度图表共计可以显示256种颜色。除了Z标尺中索引指定的颜色外,其他在范围内的索引值对应的颜色会基于这些指定的颜色以插值的方式进行创建。
如需在Intensity Graph上显示位图,可用ColorTable属性在一维数组中指定一个最多包含256种颜色的色码表。根据Intensity Graph或Intensity Chart的Z标尺设定,输入的颜色索引会被映射为该色码表中的不同索引。例如,若颜色标尺的范围为0~100,则数据中的0被映射为索引1,而100被映射为索引254,两者之间的索引值则以插值的方式被映射为1~254的数值。任何小于0的值被映射为小于范围的颜色(索引为0,颜色由ZScale.LowColor属性指定),而任何大于100的值被映射为高于范围的颜色(索引为255,颜色由ZScale.HighColor属性指定)。
图3-55显示了一个使用Intensity Graph绘制曼德博分形(Fractal)的实例。分形理论由本华·曼德博(Benoit B. Mandelbrot)首先提出,目的是描述人们在自然界中观察到的不规则形状,反映无限的细节、无限的长度和不光滑的曲线特性。能更加趋近复杂系统的真实属性与状态的描述,更加符合客观事物的多样性与复杂性。曼德博集合(Mandelbrot set,或译为曼德布洛特复数集合)是一种在复平面上组成分形(Fractal)点的集合。它与朱利亚(Julia)集合相似,均使用相同的复二次多项式进行迭代。图3-56的实例中使用了LabVIEW的MathScript节点中的文本代码,实现了色彩映射的数学计算,并最终使用计算结果修改强度图的属性。MathScript节点的使用将在第12章进行详细介绍,读者目前可不必纠结本例中文本代码的细节,只需重点了解通过属性实现颜色映射的过程即可。此外,程序中还通过ZScale.MarkerVals[ ]和ZScale.LowColor属性修改了Z标尺标记值和小于最小索引值的对应颜色。
 
    图3-56 Intensity Graph绘制曼德博分形实例
Intensity Chart是图表(Chart)的一种,因此它也具图表的特点。Intensity Chart有Strip、Sweep和Scope三种显示模式,在绘制过程中会在缓冲区中保留之前已绘制的历史数据。Intensity Chart缓冲区的默认大小为128个数据点。可通过右击Intensity Chart,从弹出的菜单中选择历史长度来配置缓冲区大小。Intensity Chart的显示需要占用大量的内存。如连续运行,历史数据将会越积越多,并要求更多的内存空间。当缓冲区中存满历史数据后,LabVIEW就停止占用内存。注意,LabVIEW不会在VI重新打开时清除图表的历史数据,若要在程序运行过程中清除强度表的历史数据,可将空数组传递给强度表的历史数据属性节点。图3-57是使用强度表扫描模式实时显示5×5矩阵中随机数据的实例。
 
    图3-57 Intensity Chart数据显示实例
Intensity Graph和Intensity Chart类似,但它并不保存历史数据,也没有像Intensity Chart那样的三种刷新模式,并且Intensity Graph每次绘制新数据图时,都会先清除旧数据。和其他图形一样,Intensity Chart也有游标,用来显示某个指定绘制点的X、Y和Z值。