图1.1显示了联合国数据库中27个选定国家的1990年死亡率与每100,000人口出生率的图表。 该图包含两个图形元素:一个点(点的集合),其标签显示国家名称,以及一个核密度估计值的轮廓(Silverman,1986),代表国家的集中度。 我们还提供了三个指南,可帮助我们理解图形。 第一个是称为形式的一般几何对象,在这种情况下,它是描绘零人口增长的线。 这条线左边的国家往往会失去人口,右边的国家往往会增加人口。 另外两个是为所表示空间描绘轴的参考线。 指南的其他示例包括图例和标题。
该图形引人注目,因为它清楚地揭示了爆炸性人口增长的方式。 密度等值线显示了两个国家的集中度。 左边的一个具有相对较低的死亡率,而中低出生率。 第二个位于右上方,具有很高的死亡率和非常高的出生率。 后者国家正在发展。 我们将国家/地区的样本保留得很小,以便我们可以阅读国家/地区标签。 从数据库中添加其他国家并不会改变整体情况。
ELEMENT: point(position(birth*death), size(0), label(country))
ELEMENT: contour(position(
smooth.density.kernel.epanechnikov.joint(birth*death)),
color.hue())
GUIDE: form.line(position((0,0),(30,30)), label("Zero Population Growth"))
GUIDE: axis(dim(1), label("Birth Rate"))
GUIDE: axis(dim(2), label("Death Rate"))
1.4.1 规范
图上方的规范仅使用ELEMENT
和GUIDE
组件。假定数据已组织在“按变量排列”矩阵中,没有任何变换,并且坐标为矩形,因此我们可以采用默认设置。前两行显示绘图中的两个图形元素:点和轮廓。这两个图形元素均通过变量birth
和death
进行定位,变量按百分比缩放。嵌入它们的框架由代数表达birth * death
确定。点图形实际上不显示,因为其大小属性设置为零。通常,我们会看到每个国家/地区country
的符号(也许是点)。相反,我们将云中每个点的国家/地区标签设置为数据中可变国家/地区的值。轮廓图表示框架不同区域中国家的密度。彼此靠近的国家越多,密度等值线就越高。这些轮廓是由内核平滑算法计算的,我们将在第7章中进一步讨论。点符号smooth.density.kernel.epanechnikov.joint()
表示Epanechnikov
内核平滑是密度平滑方法层次结构的成员。根据每个轮廓级别的内核密度值,为不同的轮廓赋予颜色色调美感color.hue
。
辅助线包括直线,坐标轴及其相应的比例和标签。 表单指南在由两个费率度量锚定的度量中以从(0,0)
到(30,30)
的一行显示。 此行标记有关联的文本字符串(“零人口增长”("Zero Population Growth" ))。 在大多数图中,我们将省略GUIDE
规范,以使描述更简单。
1.4.2 部件
从规范组装场景需要各种结构,以便彼此索引和链接组件。 我们可以使用的结构之一是网络或树。 图1.2显示了图1.1中的图形的树。 树中的每个节点(用方框显示)表示图1.1中的一种对象。 树中的每个分支(用箭头显示)代表对象之间的一种关系。 三角形箭头表示“是”(is a)关系。 菱形箭头表示“具有”(has a)关系。
“是”(is a)关系提供了一种从一个类派生通用功能的方法。这种关系的结果就是继承。例如,“轴”是“指南”,与钢琴是键盘乐器的含义相同。与作为键盘乐器有关的钢琴的任何方面(例如,具有通过按一个或多个键产生的声音)都由其他键盘乐器继承。与作为键盘乐器(例如,有铁锤)无关的钢琴的任何方面都不一定与其他键盘乐器(如大键琴拨弦,钢琴打击)共享。如果我们从通用类派生通用功能,则子类可以从其父类继承技能,而无需执行任何额外工作。例如,可以在一个Keyboard类中定义和实现与具有按键有关的任务。可以在一个Guide类中实现与指南相关的任务,例如将数字值与文本字符串相关联。以类似的方式,轮廓和点类都是图。他们继承了使自己能够在框架中表示自己的功能。
“具有”(has a)关系提供了一种在类下对相关属性和功能进行分组的方法。 这种关系的结果就是聚合。 例如,“轴”具有“标尺”,“规则”和“标签”,其含义与钢琴具有键盘,琴弦和踏板的含义相同。 这些特征和功能的集合有助于我们将钢琴与其他物体区分开。 图表以类似的方式具有框架,一个或多个参考线以及一个或多个图表。 如果我们能够很好地实现聚合,那么我们的对象将很小而又高效,并且我们的计算机代码将是可理解的和模块化的。
1.4.3 显示
图1.2中的树与一组渲染工具(符号,折线,多边形)(symbols,
polylines, polygons) 和布局设计器一起,提供了一个结构化的环境,图形中的每个对象都可以绘制自己。 无需任何代理即可找出绘制每个对象的所有规则。
图形语法有助于一组相对独立的组件中的协调活动。 通过这种语法,我们可以开发一种系统,在该系统中,除了向“添加此图形”这一简单消息外,无需在框架上添加图形(例如,表面(surface))即可进行调整或更改。类似地,我们可以删除图形,缩放比例, 置换属性,并在不重新定义基本结构的情况下进行其他更改。
1.4.4 调整
从字面上看,修订意味着再次看到。 对于图形,这意味着我们要更改,查询和浏览,而不必完成指定和创建新图形的所有工作。 通过仔细地将图形创建过程分为分层组件,我们可以提供一个灵活的环境,该环境提供新的视图,而无需重新计算系统中的每个步骤。 我们可以将控制器链接到系统中的任何组件或属性,以提供对数据,变量,框架或渲染的直接操作。 如果多个图形依赖于同一子组件,则它们也将被链接。
图1.3显示了一个示例。 即使图形看起来不同,位置框架也与图1.1相同。 我们省略了点和形式,并用多边形代替了轮廓来表示内核密度。 每个多边形的色相来自该位置国家的估计密度。 为了节省空间,我们在本规范和后续规范中省略了指南。 这些将在第12章中详细讨论。
ELEMENT: polygon(position(
smooth.density.kernel.epanechnikov.joint(birth*death)), color.hue())
图1.4在图1.1中的点图说明中增加了一个新变量。 这个变量military
(军事支出),是将人均年度军事支出标准化为美元等值。 我们正在使用此变量来确定每个符号的大小,以便标绘符号的大小代表每个国家的军事支出。
ELEMENT: contour(position(
smooth.density.kernel.epanechnikov.joint(birth*death), color.hue())
ELEMENT: point(position(birth*death), size(military))
图1.4传达了一个令人不安的消息。 相对军事支出最高的国家通常是增长最快,政治不稳定的国家。 不过,这一统计数字掩盖了军事支出的绝对水平。 绝对最高的军费开支是在流行率较高的发达国家
最后,图1.5显示了所选国家的死亡与出生之间的差异图。 目的是揭示人口快速增长的国家的位置。 我们使用了绘图符号的大小来表示差异的大小(少数小的负差异已设置为零)。
有两套定义框架的定位变量。第一个(纬度和经度)代表被测国家的位置。这些用于绘制显示死亡与出生(death-birth
)差异的圆圈。第二个经度和纬度用于表示地图上的位置,这些位置锚定了定义大陆边界的多边形的边界。从包含其顶点的形状文件中读取地图的多边形。地图数据功能处理文件中的多边形ID和多边形顶点到多边形几何函数的分割变量以及经度和纬度顶点的转换。点point
图形和多边形polygon
图形都使用position
属性来控制哪些变量确定其位置。位置尺寸通过墨卡托制图投影进行转换。轴和网格线响应投影以及框架中的图形。我们将在第9章中研究更适合于表示国家/地区数据的地图投影。
DATA: longitude, latitude = map(source("World"))
TRANS: bd = max(birth-death, 0)
COORD: project.mercator()
ELEMENT: point(position(lon*lat), size(bd), color(color.red))
ELEMENT: polygon(position(longitude*latitude))