4.3 延续性数据

延续性时间序列数据的可视化和离散型数据的可视化很相似。因为就算是延续性数据,你手中掌握的数据集依然还是离散且有限的。延续型和离散型在结构上并无二致,区别在于它们所呈现的真实世界。正如之前所提到的,延续性数据表现的是不断变化的现象,而为了实现这一目的,我们应当选择合适的可视化形式。

4.3.1 点与点相连

你可能对这种图表也比较熟悉。时间序列图表的绘制和点状图很相似,只不过你还要用线条将圆点连接起来。这些圆点一般也不用显示。图4-33显示了这一颇受欢迎的图表类型的几何特征。

4.3 延续性数据 - 图1

图4-33 时间序列图表的基本框架

图中有节点(或者说圆点,带有各自的x轴及y轴坐标)和边线(或者说连接线,以便观察数据间的变化趋势)。数值轴从0开始比较好,因为从其他数值开始可能会影响到图表的比例范围。

水平轴的长度也会影响到观察到的趋势。如果水平轴过短,点与点间的增长就会看起来比较夸张。如果水平轴过长,你可能就无法发现其中的变化模式。

创建时间序列图表

如果你学会了如何用R创建散点图,那么就能掌握创建时间序列图表的方法。载入数据,然后使用plot( )函数,但在type参数中不用p,而是用l(代表线条,line)。

我们这次用世界银行发布的1960—2009年间的世界人口数据来作演示。和往常一样,用read.csv( )函数来载入数据。

  1. population <-
  2. read.csv("http://datasets.flowingdata.com/world-population.csv",
  3. sep=",", header=TRUE)

以下是最上面几行数据的样子。只有年份和人口数量两种数据。

  1. Year Population
  2. 1 1960 3028654024
  3. 2 1961 3068356747
  4. 3 1962 3121963107
  5. 4 1963 3121963107
  6. 5 1964 3253112403

用plot( )函数并指定x轴和y轴坐标、图表类型、数值轴范围和坐标轴标签。

  1. plot(population$Year, population$Population, type="l",
  2. ylim=c(0, 7000000000), xlab="Year", ylab="Population")

你的图表应该如图4-34所示。

4.3 延续性数据 - 图2

图4-34 R中的默认时间序列图表(3)

现在你可以将图形保存为PDF格式,然后在Illustrator中编辑它。这个操作我们已经做过好几次了,现在尝试一点新花样:用Illustrator的折线图(Line Graph)工具来设计整张图表。Illustrator中提供了数个图表工具,可以让设计师直接创建一些基本图表,折线图工具就是其中之一(参见图4-35)。

4.3 延续性数据 - 图3

图4-35 Illustrator中的图表工具

首先在“工具”面板中选择折线图工具。你会看到一些图表类型的图标。单击各图标选择图表类型。

然后从http://datasets.flowingdata.com/world-population.csv下载人口数据。你不能像在R中那样直接通过URL载入数据,因而必须把文件存在自己的电脑里。用Excel或者Google Documents打开这个CSV文件,如图4-36所示。复制所有的行(第一行除外,因为其内容是各列的名称)。现在要把数据粘贴到Illustrator里面去。

4.3 延续性数据 - 图4

图4-36 在Excel中打开的CSV文件

回到Illustrator。使用从“工具”面板中选择的折线图工具,通过单击并拖动鼠标画一个矩形,其大小约等于你想要的图表尺寸。此时会弹出一个电子表格,如图4-37所示。

4.3 延续性数据 - 图5

图4-37 Illustrator中输入数据的电子表格

把你刚才从Excel里复制的数据粘贴进来,然后单击右上角的勾号。你现在应该能看到类似图4-38的图形。

4.3 延续性数据 - 图6

图4-38 Illustrator中默认的折线图

已经基本成型了,不过我们还需要调整一些选项,以让图表看上去不那么粗糙。鼠标右击图表并选择“类型”(Type)。如图4-39中那样,取消勾选Mark Data Points(标记数据点)前面的复选框。

4.3 延续性数据 - 图7

图4-39 Illustrator中的图表选项

在下拉菜单中选择“类别轴”(Category Axis)选项,然后将刻度线长度设置为“无”(None),单击确定按钮。这会让你的图表看起来更加干净而不那么杂乱。此后的设计步骤和之前由R生成的图表是一样的。

提示 如果你打算绘制一些基础的图表类型,而且要用Illustrator来编辑,那么可以直接在Illustrator里面创建它,这样可以节省时间。并不是所有图表都得先在R里面创建。当然了,也不是所有东西都得在Illustrator里面创建。

你可以清理一下垂直轴、简化数值标签、在水平轴上添加刻度线和年份标签,并且添加标题和说明文字。你还可以调整曲线的样式,让它更加突出。默认的浅灰色曲线给人感觉像是背景元素,而我们应该让它突出显示在画面中央。完成这些调整之后,你的图表效果应该类似图4-40那样。

4.3 延续性数据 - 图8

图4-40 过去50年中的世界人口

这一节想表达的意思是,你可以用Illustrator和R创建出同样的图表——二者生成的结果是相同的。你习惯使用哪种工具就用哪种工具好了,最重要的是得到结果。

4.3.2 一步一个台阶

标准折线图表的缺陷之一是它必须要表现从A点到B点间的稳定变化。它对于表现世界人口这样的数据是没问题的,但有些事物会长时期停留在某个值上,然后突然出现增长或者衰退。比如说,银行利率就会保持几个月不变,然后某天突然下调。对于这种类型的数据可以用阶梯图,如图4-41所示。

4.3 延续性数据 - 图9

图4-41 阶梯图的基本框架

与直接连接A点和B点不同,曲线会保持在同一数值,直到发生变化,那时再直接向上(或向下)跳跃到下一个数值。一般会有多个这种阶梯。

创建阶梯图

Illustrator里面没有能直接创建阶梯图的工具,但是R里面有,所以你可以先在R里面创建基础图表,然后在Illustrator里面进行编辑。你是否已经发觉了这其中的模式?

图4-42显示了最终的图表。它表现的是美国邮政投递信件的资费变化。请注意,这些变化并不是定期发生的。从1995—1999年,邮费一直保持在32美分,4年间并无涨落。然而在最近的2006—2009年间,每年都出现了上涨。

4.3 延续性数据 - 图10

图4-42 显示邮费变化的阶梯图

① 1盎司=28.350克。——编者注

要在R中创建阶梯图,同样需要经过本章中你一直遵循的几个步骤:

(1)载入数据;

(2)确保数据有适当的格式;

(3)通过某个R函数来创建图形。

你可以在美国统计摘要的网站上找到邮政资费的历史数据。我已经把它们整理为一个CSV文件,地址是http://datasets.flowingdata.com/us-postage.csv。直接将URL插入到read.csv( )中,让它作为R的数据源。

  1. postage <- read.csv("http://datasets.flowingdata.com/us_postage.csv",
  2. sep=",", header=TRUE)

以下列出了完整的数据集,其中只有10个数据节点,分别代表1991—2009年间的每一次邮费变动,最后一个数据节点表示当前资费。第一列是变化发生的年份,第二列是资费,单位为美元。

  1. Year Price
  2. 1 1991 0.29
  3. 2 1995 0.32
  4. 3 1999 0.33
  5. 4 2001 0.34
  6. 5 2002 0.37
  7. 6 2006 0.39
  8. 7 2007 0.41
  9. 8 2008 0.42
  10. 9 2009 0.44
  11. 10 2010 0.44

用plot( )函数来创建阶梯图很容易。将年份作为x轴坐标、价格作为y轴坐标,然后将类型设置为s,自然它代表的是阶梯(step)。

  1. plot(postage$Year, postage$Price, type="s")

如果你愿意,还可以指定标题和坐标轴标签。

  1. plot(postage$Year, postage$Price, type-"s",
  2. main="US Postage Rates for Letters, First Ounce, 1991-2010",
  3. xlab="Year", ylab="Postage Rate (Dollars)")

这样就得到了邮费的阶梯图,如图4-43所示。

4.3 延续性数据 - 图11

图4-43 利用R创建的阶梯图

有兴趣的话,你还可以试试看折线图的效果(参见图4-44)。

4.3 延续性数据 - 图12

图4-44 邮费的折线图

图中体现出了增长的趋势,但你是否注意到它看上去好像是在稳定增长?虽然2001—2006年间并没有38美分的资费,但从折线图中你无法得知这一点,除非看到原始数据。

将阶梯图存储为PDF格式,然后在Illustrator中打开。重复之前的过程,按你的喜好来编辑图表。我去掉了整个垂直轴,直接在每一个跳跃处添加标记(使用输入文字工具)。同时我在水平轴上绘制了平均分隔的刻度线,但只在发生变化的年份添加标记。

提示 如果数据集比较小,可以直接在数据节点上进行标记,而无需使用数值轴和网格。这样会更加强调数据本身。而且由于数据节点并不多,因而标记并不会显得过于杂乱。

最后,我使用了灰色背景。这固然是出于个人喜好,但这种背景色有助于强调图表,尤其是当图表隐没在文本中时。它提供了一个包容的空间,同时又不会显得刺眼。要想在所有图形和文字之后创建背景,你需要在Illustrator中创建一个新的图层。可以在“图层”(Layers)面板中进行设置。单击面板右下角倒数第二个按钮来创建新图层。新建的图层默认会被放置在最上方,但我们希望它退后到最底层,所以需要把新图层拖到Layer 1图层的下方。然后你还可以对层进行重命名。这个操作在你开始设计更复杂的图形时会为你带来极大的帮助。我将新图层重命名为“background”,如图4-45所示。

4.3 延续性数据 - 图13

图4-45 Illustrator中的“图层”面板

在此之后,用矩形工具(Rectangle tool)绘制一个矩形,并且按你的想法来改变它的大小,然后在“颜色”面板中改变它的颜色。

4.3.3 平滑和估算

如果你手中的数据太多,或者数据杂乱无章,可能就会很难辨认其中的趋势和模式。为了改善这一点,你可以估算出一条趋势线。图4-46显示了基本的想法。

4.3 延续性数据 - 图14

图4-46 为数据节点拟合一条线

绘制一条线穿过尽可能多的数据节点,同时尽量减少各数据节点与拟合线之间的总距离。最直截了当的做法就是创建一条直线,这其中用到了你在中学时学过的基础斜截式方程:

4.3 延续性数据 - 图15

其中m代表斜率,b代表截距。但如果你的趋势不是线性的该怎么办?用直线是不可能拟合带有波峰波谷的数据的。在这里我们可以用到William Cleveland和Susan Devlin创建的一种统计学方法,它被称作LOESS,即局部加权散点平滑法(Locally Weighted Scatterplot Smoothing)。通过它你能用曲线来拟合数据。

LOESS从最开头的数据开始对数据进行“切片”。针对每一个切片中的数据,它都会估算出一个低阶多项式。LOESS会分析每一段数据,拟合一大堆微小的曲线,然后将它们合并形成一条曲线。你可以Google一下以了解更多细节,有关这一主题有不少论文。现在让我们来看看怎样用LOESS处理数据。

►为了解LOESS的完整细节,参阅William Cleveland在《美国统计协会杂志》上发表的文章“Robust Locally Weighted Regression and Smoothing Scatterplots”(强劲的局部加权回归及平滑散点图)。

拟合一条LOESS曲线

你现在看到的故事是美国过去几十年间的失业问题。失业率一直有升有降,而且呈现出季节性波动。但其中的整体趋势是怎样的?如图4-47所示,美国失业率在20世纪80年代达到了顶峰,90年代一直在下降,然后在2008年前后开始反弹。

4.3 延续性数据 - 图16

图4-47 用LOESS曲线拟合的美国失业率

图4-48显示了用R的plot( )函数生成的失业率点状图表。

  1. # 载入数据
  2. unemployment <-
  3. read.csv(
  4. "http://datasets.flowingdata.com/unemployment-rate-1948-2010.csv",
  5. sep=",")
  6. unemployment[1:10,]
  7.  
  8. # 生成散点图
  9. plot(1:length(unemployment$Value), unemployment$Value)

4.3 延续性数据 - 图17

图4-48 只有节点的失业率图表

图4-49显示了直线拟合的效果。

4.3 延续性数据 - 图18

图4-49 笔直的拟合线

这并没有什么用。它看起来好像忽略了失业率的所有起伏波动。要想用LOESS曲线来拟合,我们得用到scatter.smooth( )函数。

  1. scatter.smooth(x=length(unemployment$Value), y=unemployment$Value)

运行结果如图4-50所示。线条开始向上凸起,对应了20世纪80年代的失业高峰。现在有点感觉了。

4.3 延续性数据 - 图19

图4-50 LOESS曲线的拟合

你可以通过scatter.smooth( )函数中的degree和span参数来调整曲线的拟合度。前者控制拟合多项式的阶数,后者控制曲线的平滑度。span越接近于0,拟合的程度就越高。图4-51显示的是degree为2、span为0.5时的效果。现在我们再调整一下颜色和坐标轴的范围。

  1. scatter.smooth(x=1:length(unemployment$Value),
  2. y=unemployment$Value, ylim=c(0,11), degree=2, col="#CCCCCC", span=0.5)

4.3 延续性数据 - 图20

图4-51 平滑度较小、多项式阶数较高的拟合LOESS曲线

通过这些设置,曲线的上下起伏更加突出了。你可以多试试不同的span值,了解一下它是如何改变曲线平滑度的。

为了得到图4-47中的最终效果,将图形存储为PDF并在Illustrator中打开。使用同样的工具(比如选择工具、文字工具、钢笔工具)添加标题、背景色和水平轴的刻度线。拟合线比数据节点要突出得多,这样可以把读者的注意力引导到趋势上面。

提示 使用不同的颜色、笔触粗细来强调图表中的重要部分。