4.2 时间中的离散点
时间数据可以分为离散时间和延续时间两种。理解自己的数据属于何种类型,你才能选择正确的可视化方法。在离散型时间数据中,数据来自于某个具体的时间点或者时段,可能的数值也是有限的。比如说,人们每年的考试通过率就是离散型数据。人们去考试,然后事件就结束了。考试有具体的日期,而且人们的分数也不会再发生变化。而类似温度这样的数据则是延续型的,在一天当中的任何时刻都可以去测量它,而且它一直都在变化。
在本节中你将会看到适用于可视化离散型时间数据的图表类型,并且通过实例学习如何在R和Illustrator中创建这些图表。在每种类型的一开始我都会作简要介绍,其中涉及的设计模式将贯穿本章,因此这些部分非常重要。虽然实例针对的都是具体图表,但其设计原则是通用的,所有类型的可视化都可以借鉴。不要忘了,要建立大局意识。
4.2.1 柱形
柱形图是最常见的图表类型,你可能见过不少,甚至还绘制过一些。柱形图适用于多种类型的数据,我们先看看在时间数据中如何使用它。
图4-3显示了基本的框架。时间轴(水平轴,也就是x轴)显示了按先后顺序排列的各时间点。本图中显示的时间点是月份,从2011年1月到6月,你也可以显示年份、日期或其他时间单位。柱形的宽度和彼此之间的间隔一般不代表数值。
图4-3 柱形图的基本框架
数值轴(垂直轴,也就是y轴)标识出图表的尺度。图4-3显示的是线性标尺(linear scale),各单位在整条轴线上均匀分布。柱形高度与数值轴相对应。比如说第一个柱形达到了1个单位,而最高的柱形达到了4个单位。
这很重要。体现数值的视觉线索就是柱形的高度。数值越小,柱形就越矮;数值越大,柱形就越高。所以我们可以看到4个单位的柱形(4月)的高度是2个单位的柱形(2月)的两倍。
许多程序默认将数值轴上的最小值设为数据集中的最小值,如图4-4所示。本例中的最小值是1。然而,如果数值轴从1开始,那么2月柱形的高度就不再是4月柱形高度的一半了。看上去2月是4月的1/3。而且1月的柱形也消失了。所以请永远保持数值轴尺度从0开始标注。否则你的柱形图就可能会显示出错误的关系。
图4-4 数值轴不从0开始的柱形图
提示 处理的数据都是正数时,请永远让柱形图的数值轴从0开始,否则会让人们难以从视觉上比较各柱形的高度。
1.创建柱形图
是时候制作你的第一张图表了。我们使用的数据是真实的,来自人类历史上最重要的赛事近30年的比赛成绩。这一赛事绝对值得被每一个人铭记——它就是享誉国际的“内森杯”热狗大胃王比赛!
图4-5是最终生成的图表。我们会分两步完成。首先在R中创建基本柱形图,然后在Illustrator中进行完善。
图4-5 显示“内森杯”热狗大胃王比赛成绩的柱形图
如果你还不知道这项巡回赛事,不妨稍微了解一下:“内森杯”热狗大胃王比赛每年举办一次,日期是在7月4日,也就是美国独立日。它实在太受欢迎了,连ESPN电视台都会进行直播。
在20世纪末期,获胜者能在约15分钟内吃下10~20个热狗面包(hot dogs and buns, HDB)。然而在2001年,来自日本的专业级食客小林尊(Takeru Kobayashi)以50个HDB的成绩傲视群雄,比他之前的世界冠军超出了整整一倍还要多。直到这时故事才开始进入高潮。
维基百科提供了这项赛事从1916年至今的所有成绩,但大胃王比赛从1980年开始才成为一项常规赛事,所以我们可以从这里开始。数据是以HTML表格形式呈现的,包括了赛事年度、选手姓名、吃掉的HDB数量和获胜者的国籍。我已经把数据编辑成了CSV文件,大家可以到http://datasets.flowingdata.com/hot-dog-contest-winners.csv下载。数据的开头五行是这样的:
- "Year", "Winner", "Dogs eaten", "Country", "New record"
- 1980, "Paul Siederman & Joe Baldini", 9.1, "United States", 0
- 1981, "Thomas DeBerry ",11, "United States", 0
- 1982, "Steven Abrams ",11, "United States", 0
- 1983, "Luis Llamas ",19.5, "Mexico", 1
- 1984, "Birgit Felden ",9.5, "Germany", 0
使用read.csv( )命令在R中载入数据。你可以从自己电脑上本地载入CSV文件,也可以通过URL加载。要想实现后者,可以在R中输入下面这行代码:
- hotdogs <-
- read. csv("http://datasets.flowingdata.com/hot-dog-contest-winners.csv",
- sep=",", header-TURE)
如果你打算从自己电脑上本地载入数据文件,请通过主菜单把R的工作路径设为你的数据文件所在的文件夹:点击File(文件)菜单下的Change dir…(修改目录)选项。当然你也可以使用setwd( )函数来设置。
如果你是不熟悉编程,可能会难以理解以上代码,我们把它拆开来讲解。这是一行R代码,目的是通过read.csv( )命令载入数据,其中有3个参数。第一个是数据的来源位置,本例中是一个URL地址。
第二个参数sep指定了数据文件中分隔各列的字符是什么。这是一个逗号分隔文件,所以将它指定为逗号。如果是一个制表符分隔的文件,就需要用\t来代替逗号,表明分隔符是制表符。
最后一个参数header告诉R数据文件是有标头的,它包含有每一列的名称。第一列是赛事年度,第二列是获胜者姓名,第三列是吃掉的HDB数量,第四列是该获胜者的国籍。你可能注意到我还添加了一个新的字段new record。如果该年度的世界纪录被打破,那么值就取1;否则就是0。我们很快就会用到它。
现在数据已经导入到R,可以通过hotdogs变量来读取。技术上来说,数据其实是被存储为一个数据块(data frame),这一点并不重要,但从概念来说是如此。如果键入hotdogs就会看到类似如下的数据块(开头部分)。
- Year Winner Dogs.eaten Country New.record
- 1 1980 Paul Siederman & Joe Baldini 9.10 United States 0
- 2 1981 Thomas DeBerry 11.00 United States 0
- 3 1982 Steven Abrams 11.00 United States 0
- 4 1983 Luis Llamas 19.50 Mexico 1
- 5 1984 Birgit Felden 9.50 Germany 0
列名称中的空格已经被替换为句点。Dogs eaten现在变成了Dogs.eaten, New record也是如此。要访问具体某一列数据,你需要在数据块名称后面加上美元符号($),然后再加上该列的名称。比如要访问Dogs.eaten列,你需要输入:
- hotdogs$dogs.eaten
现在R中已经有了数据,可以直接通过barplot( )命令来绘图了。
- barplot(hotdogs$Dogs.eaten)
这行代码告诉R绘制出Dogs.eaten列,应该会得到图4-6。
图4-6 通过R的barplot( )命令默认生成的热狗数量图表
不赖,但你还能做得更好。通过在barplot( )里设置names.arg参数来指定每一个柱形的名称。在本例中也就是每次赛事的举办年份。
- barplot(hotdogs$Dogs.eaten, names.arg=hotdogs$Year)
这样就能得到图4-7。图表的底部出现了标记。
图4-7 带有年份标记的柱形图
还有很多其他参数可以设置。你可以添加坐标轴标签、修改边框和颜色,如图4-8所示。
- barplot(hotdogs$Dogs.eaten, names.arg=hotdogs$Year, col="red",
- border=NA, xlab="Year", ylab="Hot dogs and buns (HDB) eaten")
图4-8 设置颜色及坐标轴标记后的柱形图
其中的col参数可以让你选择颜色(在R的说明文档中有标明),或者采用16进制的色彩编码,例如#821122。同时你用NA指定了去除边框,这是一个逻辑常数,代表没有数值。此外你还分别以“年份”和“吃掉HDB数量”标记了x轴和y轴。
并不是只能用一种颜色。通过为barplot( )提供多种颜色,你可以给想要的柱形着色。比如说你想突出显示美国人获胜的年份,那么就把该年度的柱形显示为暗红色(#821122),而让其他柱形显示为浅灰色,如图4-9所示。
图4-9 柱形呈现多种色彩的柱形图
要实现这一目的,你需要创建一个列表(也就是R里面的向量)用于着色。访问每一年的数据然后决定相应的柱形应该采用哪种颜色。如果是美国人获胜,指定为暗红色;否则指定为灰色。以下是相关代码:
- fill_colors <-c( )
- for (i in 1:length(hotdogs$Country) ) {
- if (hotdogs$Country[i] == "United States") {
- fill_colors <- c(fill_colors, "#821122")
- } else {
- fill_colors <- c(fill_colors, "#cccccc")
- }
- }
第一行启用了一个名为fill_colors的空向量(vector)。我们用c( )来在R里创建向量。
第二行开始了一个for循环。代码告诉R在名为i的索引中进行循环,其中i从1开始,最高值是hotdogs数据块的所有行数。具体来讲,你从hotdogs数据块中取得一个列,本例中是Country列,然后找到它的长度。如果只是对hotdogs用length( ),就只能得到它的列数,也就是5。但我们要的是它的行数,应该是31。1980—2010年的每一年都占一行,所以循环会在括号中执行31遍代码,其中每循环一次,索引i都会加1。
所以在第一次循环中,也就是i等于1时,R会检查第一行(也就是1980年)的获胜国是否为美国。如果是,就在fill_colors中添加颜色#821122(一种暗红色,以16进制形式显示)。如果不是,则添加颜色#cccccc,也就是浅灰色。
说明 大多数编程语言的数组或向量都以0开始,也就是索引的第一项从0开始引用。不过R中的向量是从1开始的。
1980年的获胜者来自美国,所以我们执行前者。之后循环会检查余下的30个年份。在R的控制台中键入fill_colors可以看到程序运行的结果。这是一组按我们需要建立的色彩值向量。
以下代码可以把fill_colors这组向量传递到barplot( )的col参数中去,以便显示更新后的柱形图。
- barplot(hotdogs$Dogs.eaten, names.arg=hotdogs$Year, col=fill_colors,
- border=NA, xlab="Year", ylab="Hot dogs and buns (HDB) eaten")
这段代码和之前的基本一样,只不过在col参数中用fill_colors代替了之前的"red"。
不过,图4-5中的最终图表突出显示的是纪录被刷新的年份,而不是美国获胜的年份。没关系,整个过程和逻辑思路是一样的。你只需修改一些条件即可。在数据块中的New.record列代表的是纪录是否被刷新,所以如果它是1,就使用暗红色,否则使用灰色。以下是R中实现的代码。
- fill_colors <- c( )
- for (i in 1:length(hotdogs$New.record) ) {
- if (hotdogs$New.record[i] == 1) {
- fill_colors <- c(fill_colors, "#821122")
- } else {
- fill_colors <- c(fill_colors, "#cccccc")
- }
- }
- barplot(hotdogs$Dogs.eaten, names.arg=hotdogs$Year, col=fill+colors,
- border=NA, xlab="Year", ylab="Hot dogs and buns (HDB) eaten")
代码与美国获胜的例子基本一样,但在if语句中略有变化。结果应该如图4-10所示。
图4-10 柱形呈现多种色彩的柱形图,不过运用的条件和图4-9不同
现在你可以试一下barplot( )里的其他选项,例如柱形间隔或者添加标题。
- barplot(hotdogs$Dogs.eaten, names.arg=hotdogs$Year, col=fill_colors,
- border=NA, space=0.3, xlab="Year", ylab="Hot dogs and buns (HDB)
- eaten")
这样你就能得到图4-11。注意柱形间隔较之前更宽,而且顶部也出现了标题。
图4-11 带有自定义间隔和主标题的柱形图
提示 在选择柱形间隔时需要小心。如果间隔的宽度和柱形宽度相近,视觉上就会产生振动效应(vibration effect),给人感觉柱形和间隔的角色发生了互换。
嘿!你的第一次R尝试已经成功完成了!
先选中图表的显示窗口,然后在File(文件)菜单中选择保存图表。将图表保存为PDF文件,你马上就会用到它。
提示 要想查阅R中函数的说明文档,只需要输入一个英文问号再加上函数名称即可。比如要在R中查阅barplot( ),只需输入?barplot,R就会提供该函数的描述以及所有可用参数的解释说明。通常还会有可运行的实例,非常有帮助。
2.在Illustrator中完善图表
现在你有了一张基础的柱形图,看起来还不赖。如果你只用它来方便自己分析,那么就没必要再进行加工了。但如果你希望把它制成可单独发布的图表,就得再花点工夫让它更具可读性。
让我们从讲故事的角度来看。假设你是一位读者,无意中看到了图4-11这张尚未完善的图表,你从中能获得哪些信息?你能看出它显示的是每年被吃掉的热狗面包。它是否记录的是某个人的饮食习惯?很明显对普通人来说这些热狗也太多了点。或者是给动物吃的?吃剩的会拿去喂鸟吗?或者是每个人每年平均食用的热狗数量?为什么有些柱形的颜色还不一样呢?
作为绘制图表的人,你了解数字背后的上下文背景,但是你的读者不了解。所以你必须对正在发生什么作出解释。好的数据设计可以帮助读者更清楚地理解整个故事。Illustrator可以帮助你做到这一点。通过它你能直接修改图中的每一个元素,比如调整字体、添加说明、修改坐标轴、编辑颜色,完成你能想象到的任何效果。
提示 站在读者的角度来设计数据图表。有哪些部分需要加以解释?
提示 如果你没有Illustrator,可以尝试InkScape,它是免费且开源的替代工具。虽然它在功能或界面上和Illustrator不太一样,但仍然可以从中找到许多共同点。
本书只是用Illustrator对图表稍作修改。但在学习了更多实例,并且开始自己设计图形时,你就会发现这些小小的改动能极大地改进图表,让它们更加简洁明了。
让我们先走好第一步。在Illustrator里打开刚才柱形图的PDF文件。你应该会在一个窗口中看到自己制作的图表,此外还有其他一些小面板提供了各种工具,包括颜色和字体面板。最值得注意的是Tools(工具)面板,如图4-12所示。你会经常用到它。如果你在界面中找不到Tools面板,可以在Window(窗口)菜单中单击Tools选项来打开它。
图4-12 Illustrator的Tools面板
面板上的黑色箭头图标被称为“选取工具”(Selection tool)。选中它,你的鼠标指针就会变成一个黑色箭头。单击并拖动鼠标,选择图表的整个边框。此时边框会高亮显示,如图4-13所示。它在Illustrator中被称为“剪切蒙版”(clipping mask)(1)。在许多情况下这个东西都很有用,但现在你不用在意它。单击Delete键把它删除。如果这个操作删除了整个图表,撤销本次操作,然后使用直接选取工具(Direct Selection tool),也就是白色箭头图标,它能直接选中剪切蒙版。
图4-13 删除PDF的剪切蒙版
现在尝试改变字体,这个操作很简单。再次使用选择工具,单击你想编辑的文本来选中它。在“字体”(Font)面板中通过下拉菜单选择你喜欢的字体,如图4-14所示。你也可以通过“文字”(Type)菜单来改变字体。图4-15中的字体已经被改成了Georgia Regular。
图4-14 Illustrator中的“字体”面板
图4-15 字体改为Georgia Regular后的图表
下一步,数值轴上的那些数字标签也需要调整。现在的数字都是侧立的,应该将其正过来以提高可读性。单击那些数字,你会注意到其他元素也会被选中。这是因为数字和其他元素默认属于一个群组(2)。你需要先打散群组才能旋转各个数字,可以在Object(对象)菜单中找到Ungroup(取消编组)选项并点击。取消已选定的数字标签,然后再选择它们,此时不再是选中整个组了,只有数字会被选中。有的时候你可能需要打散好几次群组才能只选中想要的对象。或者你也可以通过直接选择工具来选取想要的元素。
选中各个数字后,回到“Object”菜单,选择Transform(变换)→Transform Each(分别变换)。在图4-16所示的面板中,将旋转角度设置为-90°。然后单击“确定”(OK)按钮。现在数字标签就都正过来了。
图4-16 Transform Each面板
保持现在的选中状态不变,将数字标签往上、右方移动(不包括刻度线),让它们从刻度线的左侧移动到刻度线的上方。你可以用键盘上的方向键来移动对象,或者直接用鼠标拖动它们。此外还可以修改y轴左侧的文本,并将其移动到y轴的顶部右侧。这样也能提高可读性,因为读者的视线一般会从左到右移动。
为了让图表更加简洁,你还可以去掉数值轴上的垂直线。它对于数据传递并没有多大帮助。请留意在图4-5的最终图表中只有刻度线。如果你用选择工具点击垂直线,有可能那些标签也会被选中,这是因为它们默认在一个群组内。可以用直接选择工具选中这根线,然后敲Delete键,它就会消失。现在你的图表应该和图4-17类似。
图4-17 简化数值轴后的柱形图
提示 数据图的目的是显示数据本身。尝试去掉所有多余的元素。
现在你的图表已经和图4-5更加接近了。不过它依然缺少一些东西。在水平轴上没有任何刻度线、图表也缺少注释,而且如果图表中包含了绿色会更好,因为绿色是“内森杯”热狗大赛的标志色之一。
创建刻度线有很多种方法,比如说通过钢笔(Pen)工具,你可以轻而易举地画出一条直线。在“工具”面板中选择该图标,然后在“描边”(Stroke)面板中指定线条的样式。将笔触粗细设置为0.3pt,并确定“虚线”(Dashed Line)复选框没有被选中。
要画一根线,先在你希望的地方(比如第一个柱形的正下方)单击鼠标确定线段的一端,然后在稍下方再次单击鼠标确定另一端。如果在第二次单击时按住Shift键,线段就会自动呈现垂直或水平状态。现在你应该画出了第一根刻度线。你还需要30条这样的线段,因为每一年都需要一个刻度。
你可以一根一根把它们都画出来,但还有更好的办法。如果你用的是Mac,按住Option键;如果你用的是PC,则按住Alt键。用选择工具单击之前画出的刻度线然后拖动到你希望下一根刻度线所在的位置(比如第二个柱形的正下方,稍有偏移也没关系)。在这个过程中要保持按住Option或Alt键,然后松开鼠标。这个操作会创建一个副本,所以你现在应该有两根刻度线了。现在松开Option或Alt键,再按一下Command+D(Mac)或Ctrl+D组合键(PC)。这个操作会复制一根新的刻度线,而且它与第二根线的距离与前两根线的间距相等。持续按Command/Ctrl+D组合键,直到获得足够多的刻度线为止。
最后,还要适当排列一下所有的刻度线。将最后一根刻度线移动到最后一个柱形的正下方。第一根刻度线应该已经位于第一个柱形的正下方了。现在选中所有的刻度线,然后在“对齐”(Align)面板(见图4-18)中单击“水平居中分布”(Horizontal Distribute Center)图标。
图4-18 Illustrator中的“对齐”面板
这个操作会重新分配每根刻度线的间距,使它们均匀分布在首末两根刻度线之间。你还可以用选择工具选中偶数位的刻度线,然后缩短它们的垂直长度。这样能更明显地表现出稍长的刻度线对应了已有的年度标签。
要想把填充色从红色改为绿色,可以用直接选择工具选中每一个红色矩形。由于这些矩形数量不多,选起来还比较快。但如果有很多矩形需要选中怎么办?你可以先选中一个红色柱形,然后在菜单中单击“选择”(Select)→“相同”(Same)→“填充颜色”(Fill Color)。这个操作能满足你的要求,选中所有以红色填充的元素。现在只需在“颜色”(Color)面板中设置你想要的颜色即可。你可以在这里改变边框色和填充色,不过目前只需改动填充色就行了,效果如图4-19所示。
图4-19 改变图表元素的颜色
在“工具”面板中找到文字(Type)工具,可以在图表中添加文本。这是一个给图表加注释、阐明所有疑点的好机会。选择你想要的字体、字号和样式,以便和图表中其他标记文字(例如坐标轴标签)区分开来。
在这个重要非凡的热狗图表中,有3个年度可以着重强调,包括1980年后的第一次纪录刷新、小林尊的统治伊始和Joey Chestnut代表美国夺魁。同时还需要添加图表标题和说明,以便点明整幅图表的要旨。
最后也是相当重要的一点:别忘了添加数据来源。除此之外没办法证明你的图表的准确性。
提示 确保在你的图表中提供了数据来源。它不仅提升了可信度,而且还提供了上下文背景。
所有因素加在一起,你就得到了最终的图表,和图4-5中的一样。
你可能需要一段时间来消化这些内容,但当你和图表打的交道越多时,这一切就会变得越简单。如果你理解了刚才的所有操作,就能发现用R或其他任何语言编写代码所遵循的模式。而且虽然Illustrator博大精深,你也已经掌握了其中一些常用的功能。
后续的例子会涉及有关时间数据的其他图表类型,而且会继续用到R和Illustrator。鉴于你已经了解了这两款软件的基础知识,后面的进度将略有加快。
4.2.2 柱形的堆叠
如图4-20所示,堆叠柱形图的几何形状与常规柱形图很相似,区别自然在于矩形都彼此堆叠。如果数据存在子分类,且各子分类之和有意义,我们就可以用到堆叠柱形图。
图4-20 堆叠柱形图的基本框架
和柱形图一样,堆叠柱形图可以用于多种数据类型,并不只针对时间数据。不过在图4-19的例子中,x轴是按月显示的。
创建堆叠柱形图
堆叠柱形图也是很常见的图表类型,有多种制作方法。我们的例子是用R来实现的。制作过程和创建常规柱形图很相似。
(1)载入数据。
(2)确保数据有适当的格式。
(3)通过某个R函数来创建图形。
每次用R制作数据图表你都会经过这三个步骤。有时你可能会在某个步骤中花费更多的时间。也许是要琢磨数据的格式,也许是必须自己写函数才能实现某种效果。但不管怎样,你总会经过以上三个步骤,而且在其他语言中也是如此,后面几章中你就会见到。
回到堆叠柱形图,让我们再看看“内森杯”热狗大胃王比赛。我们后面不会再看到有关热狗的数据,所以请尽情享受这一刻。图4-21是我们希望实现的效果。
图4-21 显示2000—2010年各年度大胃王前三甲的堆叠柱形图
这一次,我们不再只是观察赛事冠军吃掉的热狗数量,而是扩大到每年的前三甲选手。每一个堆叠都代表一个年份,包含三个柱形,每一个柱形代表一位前三甲选手。维基百科从2000年才有相关的数据记录,所以我们也由此开始。
让我们先走好第一步,在R中载入数据。你可以直接从以下URL获得数据。
- hot_dog_places <-
- read.csv('http://datasets.flowingdata.com/hot-dog-places.csv',
- sep=",", header=TURE)
输入hot_dog_places查看数据。每一列显示了该年度的比赛结果,每一行分别表示冠、亚、季军。
- X2000 X2001 X2002 X2003 X2004 X2005 X2006 X2007 X2008 X2009 X2010
- 1 25 50.0 50.5 44.5 53.5 49 54 66 59 68.0 54
- 2 24 31.0 26.0 30.5 38.0 37 52 63 59 64.5 43
- 3 22 23.5 25.5 29.5 32.0 32 37 49 42 55.0 37
所有的列名称都以“X”开头,这是R在载入数据时自动添加的,因为R不喜欢标头的名称是数字,所以它强加了一个字母让它们更像一个单词(用更专业的词汇来说就是字符串)。最终图表里的坐标轴标签会显示这些列名称,所以你需要把它们改回来。
- names(hot_dog_places) <- c("2000", "2001", "2002", "2003", "2004",
- "2005", "2006", "2007", "2008", "2009", "2010")
把每个年份用双引号括起来,用于指明它是一个字符串。再次输入hot_dog_places,标头现在只剩下年份了。
- 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
- 1 25 50.0 50.5 44.5 53.5 49 54 66 59 68.0 54
- 2 24 31.0 26.0 30.5 38.0 37 52 63 59 64.5 43
- 3 22 23.5 25.5 29.5 32.0 32 37 49 42 55.0 37
和之前一样,我们将用到barplot( )函数,但会是另一种格式。要想把上面的所有数值都传递给barplot( ),你需要把hot_dog_places转换成一个矩阵(matrix)。现在它还只是一个数据块。这两者在R中的结构是不同的,不过其中的区别就目前来说并不重要。你只需要知道如何将数据块转换成矩阵就行了。
- hot_dog_matrix <- as.matrix(hot_dog_places)
你已经把我们新创建的矩阵存储为hot_dog_matrix。现在可以把它传递给barplot( )。
- barplot(hot_dog_matrix, border=NA, space=0.25, ylim=c(0, 200),
- xlab="Year", ylab="Hot dogs and buns (HDBs) eaten",
- main="Hot Dog Eating Contest Results, 2000-2010")
你指定了柱形没有边框、间距是柱形宽度的0.25倍、数值轴的范围是0~200,并加上了图表的标题和坐标轴标签。结果如图4-22所示。
图4-22 利用R创建的堆叠柱形图
几行代码就能得到这个效果,很不赖。不过你还可以继续完善它。将图形存储为PDF格式,并用Illustrator打开。通过之前用过的那些工具,你可以添加文本、修改字体、简化垂直轴、利用“选择相同填充色的对象”功能来统一编辑颜色,当然别忘了还要标明数据来源(见图4-23)。
图4-23 在Illustrator中编辑
最后添加一段文字说明,再修改一下图表的总标题,图4-21显示了最终的结果。
我们在下一章会认识堆叠柱形图的表兄弟:堆叠面积图。它们在几何上非常相似,但堆叠面积图可以理解为把所有的堆叠都连通变成一段持续的曲线。
4.2.3 圆点
有时候,如果用圆点代替柱形,表达的意思可能会更加明确。它们占据的空间小,而且不是矩形,所以能更好地体现出“流”的感觉。图4-24显示了用点状图表来表现时间数据时的几何特征。
图4-24 点状图表的基本框架
这种类型的图表通常被称为散点图(scatterplot),你也可以用它来表现非时间数据。它通常用于表现两个变量之间的关系,我们会在第6章中谈到相关内容。而对于时间数据,我们通过水平轴来表示时间,数值或量度则在垂直轴上表现。
柱形图用高度作为视觉线索,而散点图则用位置。你可以根据每个点的x轴和y轴坐标来观察,并且根据其他点的位置来进行相互比较。出于这一原因,散点图的数值轴不必总从0开始(不过从0开始通常是不错的)。
创建散点图
利用R中的plot( )函数可以很容易地创建散点图,不过也可以根据不同的数据类型稍加变化。图4-25显示了最终的图表。
图4-25 在R中创建、在Illustrator中设计得到的散点图
这次的故事是关于FlowingData网站于2010年1月计算的订阅者数量,数据报告来源于Feedburner,该服务能够追踪每天有多少人阅读FlowingData上的文章。在2010年1月1日,订阅人数是25047,而到月底的人数是27611。不过其中最有意思的地方可能是该月中旬的明显下滑。我是否说了什么话冒犯了17000名读者,让他们愤然退订?应该不是这么回事。
提示 数据并不都是真实的。可能是笔误、报告错误或其他原因导致数据偏离了现实。
还记得在R中创建图表时要做的第一件事是什么吗?载入数据。用read.csv( )直接从URL中获得数据。
- subscribers <-
- read.csv("http://datasets.flowingdata.com/flowingdata_subscribers.csv",
- sep=",", header=TRUE)
输入以下代码可以查看数据的前五行:
- subscribers[1:5,]
看上去应该是这样:
- Date Subscribers Reach Item.Views Hits
- 1 01-01-2010 25047 4627 9682 27225
- 2 01-02-2010 25204 1676 5434 28042
- 3 01-03-2010 25491 1485 6318 29824
- 4 01-04-2010 26503 6290 17238 48911
- 5 01-04-2010 26654 6544 16224 45221
可以看到有5列数据,分别对应日期、订阅人数、访问网站人数、浏览文章数和网站点击数。我们只关心其中的订阅人数。
你也可以让R把日期也绘制出来,但由于每天的人数本来就是按时间顺序排列的,所以第一列的内容其实并无太大必要。输入下面这行代码就能看到点状图,效果如图4-26所示。
- plot(subscribers$Subscribers)
图4-26 R中的默认图表
很简单,对吧?plot( )函数可以让你创建多种不同类型的图表,不过点状图是它的默认类型。你只用到了数据中的订阅人数。当你只给plot( )函数提供一个数组时,它会假设该数组中含有数值,并且自动为x轴坐标建立索引。
现在明确指定你希望的是点状类型,并且设置垂直轴的范围是0~30000。
- plot(subscribers$Subscribers, type="p", ylim=c(0, 30000))
图4-27和图4-26是一回事,但垂直轴的范围更宽,因为你用ylim参数进行了指定。请注意你用type参数告诉了R使用点状类型(p)。如果你把类型改为h,R就会改为创建高密度的垂直线。
图4-27 R中指定了y轴范围的点状图
你也可以合并这两种类型,如图4-28所示。不过你还需要用到points( )函数。这是因为只要一用到plot( )函数,你就会创建一个新的图表,而不是在已有图表上添加新元素。如果你打算合并垂直线和点状图这两种效果,以下是需要的代码。
- plot(subscribers$Subscribers, type="h", ylim=c(0, 30000),
- xlab="Day", ylab="Subscribers")
- points(subscribers$Subscribers, pch=19, col="black")
图4-28 带有高密度垂直线的点状图
垂直线类型的图表会首先绘制出来,这一次加上了坐标轴标签。之后点状图会添加到已有的图表中。pch参数是有关圆点大小的,而col参数我们曾在柱形图中用到过,它指定填充颜色。
现在让我们回到图4-27。将其保存为PDF文件,然后在Illustrator中打开,以便进行一些设计工作。
用选择工具选中标签,改成你喜欢的字体。然后打散标签群组,以便能单个编辑垂直轴的标签。通过“Transform→Transform Each”将标签正过来,然后用直接选择工具删除y轴上的垂直线。你不一定非要这么做,只不过它有点占地方。
最后选中那些圆点,它们目前是白色的圆圈。调整“颜色”面板中的选项,设置你想要的填充色和边框色。可能你还需要打开“颜色”面板的选项菜单(见图4-29),把颜色模式从灰度(Grayscale)改成CMYK(也就是青、品红、黄和黑四色搭配模式),这样才能有更多的用色选择。
图4-29 “颜色”面板中的选项菜单
这样你就会得到图4-30。它已经很像最终的图表了。
图4-30 调整坐标轴和颜色之后的点状图
现在试着添加网格,这样一来读者就能更容易观察右边较远圆点所代表的值,以及和之前各圆点之间的关系。用选择工具选中数值轴上的刻度线,然后拖动鼠标将它们拉长到贯穿整个图表。现在看来它们有点生硬,所以需要改变线条的样式。和之前一样,你可以在“描边”面板中做到这一点。如果你想用较细的虚线,可以按图4-31那样设置。
图4-31 “描边”面板中虚线样式的各种选项
图4-32是修改后的效果,同时添加了数值的单位。
图4-32 添加网格并且在数值轴上标明数值和单位
在图4-32的基础上,使用同样的工具和技巧以实现最终的图表。用钢笔工具在水平轴上绘制刻度线,用文字工具编辑和添加标签。不要忘了在图表底部加上数据来源,让故事更加完整。