5.2 整体中的各个部分
这是形式最简单的比例呈现。你有一系列比例值,它们的总和为1,或者百分比的总和是100%。你既希望呈现各部分和其他部分的相对关系,同时又希望保持整体上的感觉。
5.2.1 饼图
饼图是最传统的图表之一。它们随处可见,比如商务演讲演示,甚至还有网站用它来开各种玩笑。已知最早的饼图是1801年由William Playfair发布的,他还发明了折线图和柱形图。真是有才。
你应该很清楚饼图的原理。如图5-1所示,我们从一个圆开始,用它来代表整体,然后把它们切成楔形,就和分蛋糕或披萨一样。每一个楔形都代表整体中的一部分。记住下面这句话,因为很多新手都会犯这个错误:所有楔形所占百分比的总和应该等于100%。如果不等,那就一定是哪里出了问题。
图5-1 饼图的基本框架
有些人对于饼图略持微词,因为它不像柱形图或者基于位置的图形那样精确,所以他们认为应该完全弃之不用。的确,衡量长度要比衡量面积或角度要容易得多,但这并不意味着我们就应该完全抛弃饼图。
只要了解了饼图的局限,使用起来并不存在问题。这一点很容易做到:良好组织数据,不要将一个饼图分成太多块。
创建饼图
几乎所有的图表工具都能绘制饼图,不过我们可以像上一章那样直接在Illustrator中创建。过程是一样的:首先添加数据,然后绘制基础图表,最后再加以修饰。
绘制基础图表(也就是饼图)的方法非常简单。创建一个新文件,从“工具”面板中选择Pie Graph Tool(饼图工具),如图5-2所示。按下左键并拖动鼠标创建一个矩形,其大小应该和你想要的图表尺寸相符。你还可以在后面调整尺寸。
图5-2 Illustrator中的“工具”面板
在松开鼠标左键之后,会弹出一个电子表格窗口,要求你输入数据。如果是单个饼图,从左到右输入各个数据点,然后数据就会以同样的顺序显示在图表中。
我们这次以FlowingData网站发起的一项投票为例。网站列出了一系列与数据相关的领域,并要求访问者从中选择他们最感兴趣的选项。最后收到了831票。
在Illustrator的电子表格中输入数据,如图5-3所示。你输入数字的顺序会直接影响到饼图中各个楔形的顺序,它们从顶部开始,然后以顺时针方向依次排列。
图5-3 Illustrator中的电子表格
请注意投票结果由大到小进行了排序,并且以“其他”类别作为结束。这种排序可以让你的饼图更加容易阅读。单击弹出窗口右上角的勾号,图表就创建成功了。
提示 Illustrator中的电子表格只是一个简要工具,你无法通过它对数据进行修改或者排序。解决办法是先用Microsoft Excel把所有的数据都处理好,然后再复制粘贴到Illustrator中去。
默认的饼图中出现了8个不同灰度的楔形,颜色似乎并无明确顺序,并且带有黑色边框,如图5-4所示。它看上去有点像一个灰色的棒棒糖,不过很容易就能改变这一点。最重要的是你已经得到饼图的雏形了。
图5-4 默认的饼图
现在让我们来增强饼图的可读性,比如改变颜色、添加文本,以向读者解释他们看到的是什么。现在的饼图颜色并没有什么含义,它们的作用只是分开楔形而已,但我们可以利用颜色来告诉读者哪些是重点、遵循了何种顺序。毕竟你好不容易才把数据按大小排好序。
如果你从12点钟方向开始然后顺时针旋转,应该会发现数值的大小呈逐步下降的趋势。然而现在的颜色是任意分配的,有一些较小的楔形反而颜色更深,得到了强调。颜色的深浅代表重点的强弱,因此我们应该让较大的楔形使用更深的颜色,而较小的楔形使用较浅的颜色。如果你希望强调那些获得票数较少的答案,那么就应该将颜色的深浅反过来。不过在这次投票中,你希望知道的是有哪些数据领域最受欢迎。
提示 颜色会极大地影响人们对图表的阅读。它不仅是美学元素——尽管有时候确实如此。颜色和长度、面积一样可以作为视觉线索,因此务必明智地进行选择。
在“工具”面板单击直接选择工具,然后选中某个楔形。通过“颜色”面板中的控件来改变填充色和边框色。图5-5显示了同样的饼图,但是边框变成了白色,而且各楔形按从深到浅排列。现在更容易识别出数值按从大到小排列了,不过最后一个楔形“Other”除外。
图5-5 颜色按从深到浅排列的饼图
当然,在颜色上不必如此节俭。你可以使用任何喜欢的颜色,就像图5-6中那样。一般来说,不要使用过于明亮的颜色,因为你不想刺激到读者的眼睛。不过如果你的主题适合用晃眼的颜色,不妨放纵一下。
图5-6 着色后的饼图(另见彩插图5-6)
由于这是FlowingData发起的投票,我借用了FlowingData网站logo的红色系,然后以逐步降低不透明度的方法来逐渐减弱色彩。你可以在“透明度”(Transparency)面板中找到这个选项。不透明度为0时,填充色就会完全看不见;不透明度为100%时,填充色就不会有任何透明感。
说明 当你调整不透明度时,颜色会与背景色相混合。本例中的背景是白色的,所以透明度越高时颜色就会体现出褪色的感觉。但如果背景是蓝色的,颜色就会越来越紫。
最后,通过文字工具添加标题、文字说明以及各个标签。你可以任意选择自己喜欢的字体,不过在考虑文本的位置时,Illustrator的对齐工具会非常有用。将标签文字进行合理地、均匀地分布,这样能让你的图表更加易读。你还可以使用钢笔工具为最后三个投票类别绘制箭头(见图5-7)。这些楔形的面积过小,不能把标签放到它们的内部,而且彼此间过于接近,标签放在邻近的位置可能会造成彼此混淆。
图5-7 带有标签和说明文字的最终饼图(另见彩插图5-7)
5.2.2 面包圈图
我们的好朋友饼图还有个小兄弟:面包圈图。它和饼图很相似,但在中间有一个洞,看起来更像面包圈,如图5-8所示。
图5-8 面包圈图的基本框架
由于圆形中间有一个洞,你不能再通过角度来衡量数值了,而要通过各弧形的长度。如果在一个图表中包含过多类别,对这种类型的图表也会造成同样的问题,但如果类别较少的话,面包圈图用起来也是很顺手的。
创建面包圈图
在Illustrator里面创建面包圈图非常简单。像之前那样创建一个饼图,然后在中心处放置一个实心圆,如图5-9所示。同样用颜色来引导读者的视线。
图5-9 从饼图到面包圈图
很多时候,面包圈图的中心都用于放置标签或者其他内容,就像图5-9一样。
提示 需要记住的是,饼图和面包圈图很容易就会变乱。它们本来就不适合应对较多数值。
现在让我们再创建一次这个图表,不过用的是另一款免费且开源的可视化工具Protovis。它是一个通过JavaScript实现的函数库,利用了现代浏览器的可缩放矢量图形(SVG,Scalable Vector Graphics)功能。图形可以动态创建,而且支持动画和交互行为,这让Protovis非常适合在线创建图表。
►访问http://vis.stanford.edu/protovis/下载Protovis,把它解压后放在你存储示例文件的文件夹里。
虽然我们要用到的是另一种编程语言,但步骤和之前用R与Illustrator的时候完全一样。首先载入数据,然后生成基础图表,最后是美感上的改进。
图5-10显示了我们希望达到的效果。它和图5-9很类似,但标签都被设置了角度,而且当鼠标悬停在各弧形上时,可以看到相应的投票数量。Protovis可以支持更高级的交互行为,不过我们还是从基础开始吧。
图5-10 利用Protovis创建的面包圈图
你要做的第一件事是创建一个HTML网页,将其命名为donut.html。
- <html>
- <head>
- <title>Donut Chart</title>
- <script type="text/javascript" src="protovis-r3.2.js"></script>
- <style type="text/css">
- #figure {
- width: 400px;
- height: 400px;
- }
- </style>
- </head>
- <body>
- <div id="figure">
- </div><!-- @结束figure -->
- </body>
- </html>
如果你曾经创建过网页,那么以上代码是很容易看懂的。如果你没有相关经验,这段代码其实在网上随处可见,你可以轻松找到。每一个网页都会以<html>标签开始,它的后面是<head>标签,里面包含有关于页面的信息,但不会显示在浏览器窗口中。只有<body>标签中封闭的所有内容才是可见的。将页面的标题(title)设置为Donut Chart,并通过<script>标签载入Protovis函数库,也就是JavaScript文件。之后再指定一些CSS,它们被用于定制HTML页面的样式。在这里简单一点就行了,将id为figure的<div>的宽度和高度都设定为400像素。你将会在它里面绘制图表。以上的HTML代码并不是图表的组成部分,但却是必需的,因为只有有了它,后面的JavaScript才会正确地载入到浏览器中。现在用浏览器打开donut.html文件,你看到的只是一个空白的页面。
在id为figure的<div>里,指定你要写的代码是JavaScript。后面的代码都位于这两个<script>标签之内。
- <script type="text/javascript+protovis">
- </script>
现在走好第一步:数据。我们关注的依然是FlowingData网站的投票结果,你需要将它们存储在数组中。一个数组用于存储投票数量,另一个用于存储相应的类别名称。
- var data = [172,136,135,101,80,68,50,29,19,41];
- var cats = ["统计学", "设计", "商务", "制图学",
- "信息科学", "网站分析", "编程",
- "工程学", "数学", "其他"];
然后指定面包圈图的宽度、高度、半径长度以及弧长范围。
- var w = 350,
- h = 350,
- r = w / 2,
- a = pv.Scale.linear(0, pv.sum(data)).range(0, 2 * Math.PI);
面包圈图的宽度和高度都是350像素,半径(图表中心到外围的距离)是宽度的一半,也就是175像素。第4行指定了弧形的标度。这样来理解它:真正的数据是一个线性比例,从0到所有投票的总和,也就是总票数。然后把这个比例换算成面包圈的比例,即0~2π的弧度,如果你习惯按角度来考虑,那么也就是0~360°。
之后是设定颜色的变化。某个类别获得的票数越多,它的红色就应该越暗。在Illustrator里面你必须手动去调色,但Protovis可以自动为你选择颜色。你只需定义想要的颜色范围即可。
- var depthColour = pv.Scale.linear(0, 172).range("white", "#821122");
现在你设定了颜色从白色到暗红色(也就是#821122)。这是一个线性范围,从0到172,后者是单个类别的最高票数。换句话说,票数为0的类别会显示为白色,票数为172的类别会显示为暗红色。票数在这个范围内的各类别会显示为白色和暗红色之间的某个颜色。
到目前为止,我们定义的都是一些变量,分别指定了尺寸和标度。要想得到实际的图表,首先需要创建一个350像素宽、350像素高的空白区域(panel)。
- var vis = new pv.Panel( )
- .width(w)
- .height(h);
然后往这个区域中添加内容,在本例中就是楔形。以下代码可能会让你有些困惑,我会逐行来解释。
- vis.add(pv.Wedge)
- .data(data)
- .bottom(w / 2)
- .left(w / 2)
- .innerRadius(r - 120)
- .outerRadius(r)
- .fillStyle(function(d) depthColors(d))
- .strokeStyle("#fff")
- .angle(a)
- .title(function(d) String(d) + "票")
- .anchor("center").add(pv.Label)
- .text(function(d) cats[this.index]);
第一行说的是你正在往空白区域中添加楔形,分别对应数组中的每一个数据。bottom( )和left( )参数指定了楔形的朝向,使它们的尖端放置在圆形正中。innerRadius( )指定了圆心那个洞的半径,而outerRadius( )则是整个圆形的半径。这两者确定了楔形的大小。这些代码指定了面包圈图的几何结构。
在填充颜色方面,并非给填充样式(fill style)指定一个静态色值,而是由各个数据的值以及存储了颜色范围的depthColors变量来决定。换句话说,填充色是由各个数据点的函数决定的。此外添加了白色(#fff)边框,由strokeStyle( )指定。之前定义的弧长标度可以确定每一个楔形的角度大小。
我们希望在读者将鼠标移动到某个区间上时显示该类别获得了多少票数,因此这里用到了title( )来显示提示文本。你也可以创建一个mouseover事件来指定当用户把鼠标移动到某个对象上时发生什么,但浏览器本来就自动支持显示title属性内的值,所以用title( )会更省事一些。让每一个数据点的title显示该数据点的值,然后再加上“票”以让表意更加清楚。最后为每一个区间添加标签。现在只剩下在图表中心的洞里加上“2009年5月”了。
- vis.anchor("center").add(pv.Label)
- .font("bold 14px Georgia")
- .text("2009年5月")
以上代码可以理解为:“在图表中心添加标签,字体是14像素的Georgia粗体,内容是‘2009年5月’。”
所有的元素都搭建完毕,现在你可以渲染图形了。
- vis.render( );
在浏览器里打开donut.html,你就会看到图5-10的效果。
►访问http://book.flowingdata.com/ch05/donut.html看一下图表的在线效果,并且查看完整的源代码。
如果你是编程新手,这一节的内容可能会让你感到有些气馁。但好消息是Protovis有很多实例教程可供学习。官方网站上有许多可运行的实例,其中既有传统的统计学图表,也有更高级的可交互式动画图表,而且你可以使用自己的数据。所以如果你感到有些沮丧,千万不要就此灰心丧气。你现在稍微付出一些努力,很快就能掌握其中的窍门,而且将会获得丰厚的回报。让我们在下一节再来看看Protovis。
5.2.3 比例中的堆叠
在上一章我们用堆叠柱形图呈现了随时间变化的数据,但它的能力并不只限于时间数据。如图5-11所示,你还可以用堆叠柱形图来表现类别数据。
图5-11 按类别划分的堆叠柱形图
比如说,让我们看一下2010年7月和8月间由盖洛普公司(1)和哥伦比亚广播公司举办的一次有关奥巴马总统支持率的民意调查。参与者被问到他们是否支持奥巴马有关13个主要问题的政治举措。
以下是以表格形式给出的各个数字。
我们可以为每一个问题创建一个饼图,如图5-12所示。要想用Illustrator实现,你只需输入多行数据即可。每一行数据都会生成一个饼图。
图5-12 系列饼图(另见彩插图5-12)
不过,堆叠柱形图会让你更容易地比较各个问题的支持率,因为与楔形的角度相比,人们对柱形高度更加敏感。所以让我们尝试一下。在Illustrator里面可以直接通过堆积柱形图工具(Stacked Graph tool)生成堆叠柱形图,这次我们再往里面添加一些简单的交互行为。
创建可交互堆叠柱形图
和面包圈图一样,我们也用Protovis来创建可交互堆叠柱形图。图5-13显示了最终的效果。我们需要实现两个基础的交互行为:第一个是当鼠标悬停在某个堆叠上时显示它的百分比值,第二个是根据鼠标的位置高亮显示该类别所对应的所有支持、反对或者不发表意见的柱形。
图5-13 利用Protovis创建的可交互堆叠柱形图(另见彩插图5-13)
一开始先创建HTML页面,并且载入必需的Protovis JavaScript文件。
- <html>
- <head>
- <title>Stacked Bar Chart</title>
- <script type="text/javascript" src="protovis-r3.2.js"></script>
- </head>
- <body>
- <div id="figure-wrapper">
- <div id="figure">
- </div><!-- @结束figure -->
- </div><!-- @结束figure-wrapper -->
- </body>
- </html>
这段代码应该很眼熟,和用Protovis创建的面包圈图时所做的一样。唯一的区别在于页面的标题变成了“Stacked Bar Chart”,而且增加了一个id为figure-wrapper的<div>。我们也没有添加任何CSS样式,这个可以留在后面去做。
现在开始写JavaScript。在id为figure的<div>中,以数组的形式载入数据(也就是奥巴马的支持率)。
- <script type="text/javascript+protovis">
- var data = {
- "Issue":["种族关系","教育","恐怖活动","能源政策","外交事务","环境","伊拉克
- 局势","税收","医疗保健政策","经济","阿富汗局势","联邦预算赤字","外来移民"],
- "支持":[52,49,48,47,44,43,41,41,40,38,36,31,29],
- "反对":[38,40,45,42,48,51,53,54,57,59,57,64,62],
- "不发表意见":[10,11,7,11,8,6,6,5,3,3,7,5,9]
- };
- </script>
从中可以看出,对应种族关系的支持率和反对率分别是52%和38%。与之类似,对应教育的支持率和反对率分别是49%和40%。
为了便于编写图表部分的代码,你可以把数据分开存储为两个变量。
- var car = data.Issue;
- var data = [data.Approve, data.Disapprove, data.None];
Issue(问题)数组被存储到cat变量中,而data变量则是一个包含数组的数组。
为宽度、高度、尺度比例和颜色设定必要的变量,代码如下:
- var w = 400,
- h = 250,
- x = pv.Scale.ordinal(cat).splitBanded(0, w, 4/5),
- y = pv.Scale.linear(0, 100).range(0, h),
- fill = ["#809EAD", "#B1C0C9", "#D7D6CB"];
图表会有400像素宽,250像素高。水平轴的标度是有顺序的,表示你设定的各个类别,它们之间并非延续性的关系。类别也就是调查中涉及的那些问题。图表宽度的4/5用于柱形,其他空间用于各柱形间的间隔。
垂直轴表现的是百分比,是一个0~100%的线性标尺。各柱形的高度可以从0像素一直到图表的顶端,也就是250像素。
最后,填充色通过一个16进制的数组来指定。深蓝色代表支持,浅蓝色代表反对,浅灰色代表不发表意见。你也可以按自己的喜好改用其他颜色。
►如果你不知道应该用什么颜色,http://colorbrewer2.org网站上的ColorBrewer可能会有所帮助。在该工具内指定需要的颜色数量和颜色类型,它就能提供适当的色标,方便你以多种格式进行复制。http://0to255.com上的0to255综合性更强,但我主要还是用前者。
下一步,用已指定的宽度和高度进行可视化的初始化。之后的代码为实际图表提供了周围的空白空间,以便添加坐标轴标签。比如说,bottom(90)将水平轴往上提升了90像素。你可以把这个操作看作是设置空白的画布。
- var vis = new pv.Panel( )
- .width(w)
- .height(h)
- .bottom(90)
- .left(32)
- .right(10)
- .top(15);
Protovis为堆叠图表提供了一种特殊的布局,其名称也很恰当,就叫做“堆叠”(Stack),方便在画布中添加堆叠柱形。虽然本例中添加的是堆叠柱形图,但该布局同样适用于堆叠面积图和流线图。将新的版式存储到bar变量中。
- var bar = vis.add(pv.Layout.Stack)
- .layers(data)
- .x(function( ) x(this.index))
- .y(function(d) y(d))
- .layer.add(pv.Bar)
- .fillStyle(function( ) fill[this.parent.index])
- .width(x.range( ).band)
- .title(function(d) d + "%")
- .event("mouseover", function( ) this.fillStyle("#555"))
- .event("mouseover", function( )
- this.fillStyle(fill[this.parent.index]));
另一条思路是把这个图表视作为三个层,分别代表支持、反对和不发表意见。还记得我们刚才是怎样把这三组数据构建为一个新数组的吗?用layers( )调用它,而x和y依然保持你之前设定的标尺。
对每一个层用pv.Bar来添加柱形,用fillStyle( )来指定填充色。请注意,我们使用了一个名为this.parent.index的函数。这样一来柱形就会根据它所属三个层中的其中一个进行着色。如果这里我们用的是this.index,你就必须为每一个柱形,也就是39(3×13)个柱形设置颜色。每个柱形的宽度都是相同的,具体数值可以从之前已指定的水平轴的顺序标尺中得到。
上面的最后三行代码给图表赋予了交互功能。在Protovis里用title( )就相当于给HTML元素(如图片)设置title属性。如果给网页中的图片设置了title,那么当鼠标悬停到图片上时就会出现文本提示。与之类似,当鼠标悬停到柱形上时也会出现文本提示。我们在这里只是简单地让文本提示显示该柱形所占的百分比值,其后跟随百分比符号(%)。
为了让鼠标移动到柱形上时高亮显示相应的层,我们用到了event( )。“mouseover”时填充的是深灰色(#555),而当鼠标移出时,“mouseout”事件将各柱形恢复初始颜色。
提示 Protovis支持的交互行为不是仅限于鼠标悬停效果,你也可以设置诸如单击、双击等行为。查阅Protovis说明以了解更多细节。
最后你需要渲染图形以便生成图表。在JavaScript代码最后输入以下代码:
- vis.render( );
这行代码的意思是:好,我们已经准备好了所有的部件,现在绘制出图形吧。在浏览器(Firefox或Safari等现代浏览器)中打开网页,你就会看到类似图5-14中的图表。
图5-14 没有添加标签的堆叠柱形图
鼠标移动到某个柱形上时,相应的层会被高亮显示,与此同时会出现文本提示。不过现在还缺少一些元素,也就是坐标轴和标签。把它们添加进来。
在图5-13中的柱形上有数字标签。不过标签只出现在较高的柱形上,灰色的柱形则没有。以下是实现方法。请注意这些代码位于vis.render( )的前面。永远都把渲染工作留在最后。
- bar.anchor("center").add(pv.Label)
- .visible(function(d) d > 11)
- .textStyle("white")
- .text(function(d) d.toFixed(0));
检查每一个柱形是否大于11%。如果大于,那么就在柱形的正中间绘制一个白色的标签,它显示了所占百分比四舍五入后的整数数值。
现在为x轴上的每一个问题添加标签。理想情况是所有标签都水平显示,但很明显位置不够。如果我们的图表是横向的柱形图,那么标签倒是能够水平放下,不过在本例中,我们将它们以45°斜向显示。当然你也可以把它们完全垂直放置,不过那样会有碍于阅读。
- bar.anchor("bottom").add(pv.Label)
- .visible(function( ) !this.parent.index)
- .textAlign("right")
- .top(260)
- .left(function( ) x(this.index)+20)
- .textAngle(-Math.PI / 4)
- .text(function( ) cat[this.index]);
这段代码的原理和往柱形中间添加数字标签相同。不过,这次只会向位于底部的柱形添加标签,也就是代表支持的柱形。然后利用textAlign( )和top( )将文本右对齐,并设置它们的绝对垂直位置。它们的x轴位置是根据相应标签的柱形位置决定的。每一个标签都被旋转了45°,标签文本显示了类别的名称。
这样我们就有了类别标签。在垂直轴上添加数值标签也是同样的方法,不过你还需要添加刻度线。
- vis.add(pv.Rule)
- .data(y.ticks( ))
- .bottom(y)
- .left(-15)
- .width(15)
- .strokeStyle(function(d) d > 0 ? "rgba(0,0,0,0.3)" : "#000")
- .anchor("top").add(pv.Label)
- .bottom(function(d) y(d)+2)
- .text(function(d) d == 100 ? "100%" : d.toFixed(0));
我们通过y.ticks( )为图表添加标尺(Rule),也就是刻度线。零度线的颜色是黑色,其他刻度线为灰色。代码的第二部分在各刻度线的上面添加标签。
现在还差水平轴,所以还需要加入另一个标尺,如图5-15所示。
- vis.add(pv.Rule)
- .bottom(y)
- .left(-15)
- .right(0)
- .strokeStyle("#000")
图5-15 添加水平轴
说明文字和其他标签是用HTML和CSS添加的。市面上有各种各样的Web设计书籍,所以这里就不再赘述了。Protovis是JavaScript代码,因此与HTML和CSS可以轻松地无缝结合使用,这一点是最棒的。
►访问http://book.flowingdata.com/ch05/stacked-bar.html浏览堆叠柱形图并与之交互,查看源代码了解HTML、CSS和JavaScript是如何紧密协作的。
5.2.4 层级和矩形
1990年,马里兰大学的Ben Shneiderman发现自己的硬盘总是空间不够,于是希望通过可视化的方式来弄清到底是什么如此占据空间。考虑到目录和文件是层级结构的,他一开始用的是树形图(tree diagram)。不过由于节点太多、分枝太多,很快图表就变得过于庞大,无法为他带来帮助。
►访问http://datafl.ws/11m了解板块层级图的来龙去脉,以及由创造者Ben Shneiderman亲身描述的其他案例。
最后他的解决方案是板块层级图(treemap)。如图5-16所示,这是一种基于面积的可视化方式,通过每一个板块(通常为矩形)的尺寸大小进行度量。外部矩形代表父类别,而内部矩形代表子类别。你也可以用板块层级图显示单纯的比例关系,不过在充分利用该技术的情况下,它更适合于显示层级结构,或者更确切的说,树状结构的数据。
图5-16 板块层级图的基本框架
创建板块层级图
Illustrator没有提供板块层级图工具,但R中有一个工具包可以实现这一功能。这个工具包是由Jeff Enos和David Kane开发的,名叫Portfolio。它的开发初衷是对股票市场投资组合(stock market portfolio)进行可视化(其名由此而得),但也完全适用于我们自己的数据。让我们看看FlowingData网站上最受欢迎的100篇文章的浏览次数和评论数量,然后将它们按照文章类别进行划分,例如Visualization(可视化)或者Data Design Tips(数据设计贴士)。
提示 R是一款针对统计学计算的开源软件环境,你可以从http://www.r-project.org/免费下载。R的可贵之处在于它有一个活跃的社区,上面经常会有人开发新的工具包来添加功能。如果你需要创建静态图表,而又不知道从何开始,R将会是一个很好的起点。
和之前一样,第一步是在R中载入数据。你可以直接从计算机里载入,或者指定URL。本例中采用的是后者,因为数据可以直接在网上找到。如果你希望采用自己的数据、直接从计算机载入的话,请确保你的数据文件放在了R的工作路径中。你可以通过R中的“文件”菜单来修改工作路径。
通过URL来载入CSV文件非常容易,它只需要一行代码,用到了R中的read.csv( )函数(参见图5-17)。
- posts <- read.csv("http://datasets.flowingdata.com/post-data.txt")
图5-17 在R中载入CSV文件
很简单,不是吗?我们已经利用read.csv( )载入了一个文本文件(CSV格式),并且将页面的浏览量和评论数都存储进了一个名为posts的变量。正如上一章所提到的,read.csv( )函数会假设你的数据文件是以逗号分隔的。假设你的数据是以制表符分隔,就需要用sep参数来指定该值为\t。要是你打算从本地目录中载入数据,之前的代码就应该变成这样:
- posts <- read.csv('post-data.txt')
以上代码适用于你已经设置了相应工作路径的情况。要想深入了解如何利用read.csv( )函数载入数据,在R的输入台中键入以下代码:
- ?read.csv
让我们继续。现在数据已经存储到了posts变量中,输入以下代码查看最开始的5行数据。
- posts[1:5,]
你应该会看到数据有4列,分别对应原始CSV文件的id、views(浏览量)、comments(评论数)和category(文章类别)。既然R已经载入了数据,现在使用Portfolio工具包。输入以下代码来载入它:
- library(portfolio)
返回了出错信息?你可能需要在使用之前先安装这个工具包:
- install.packages("portfolio")
现在你应该可以载入工具包了。不再返回出错信息了吧?很好,让我们进入下一步。
提示 你也可以通过R的用户界面来安装工具包。在菜单中选择“工具包”(Packages)→“安装工具包”(Install Packages)。从工具包列表中找到需要的工具包然后单击“确定”按钮安装。
Portfolio工具包通过一个名为map.market( )的函数来实现我们想要的效果。这个函数包含许多参数,不过我们只需要用到其中的5个。
- map.market(id= posts $id, area=posts$views, group=posts$category,
- color=posts$comments, main="FlowingData Map")
名为id的列给每一篇文章指定了唯一的特征点,而你告诉R根据文章的浏览量来决定图表中各矩形的大小,根据文章类别进行分组,同时根据每篇文章的评论数量来决定矩形的颜色。最后,以FlowingData Map作为图表的主标题。敲回车键获得板块层级图,如图5-18所示。
图5-18 R默认生成的板块层级图(另见彩插图5-18)
虽然图形看起来还很粗糙,但整个图表的基础和层级都已经搭建起来,这也是最困难的部分。和你指定的一样,每一个矩形都代表一篇文章,尺寸依页面浏览量而定,并按照文章类别进行了分组。明亮的绿色表明该文章获得的评论数比较多。浏览次数多的文章,获得的评论并不一定多。
在R中把图表存储为PDF文件,然后用Illustrator打开。利用各种常规选项来调整边框、填充色、字体,去掉无关的内容,并添加文字说明。
对于这个图表而言,我们需要修改一下标尺为-90~90的颜色说明。负值在这里并无意义,因为文章的评论数是不可能为负的。此外标签也需要调整,在较小的矩形中它们被遮盖住了。利用选择工具,根据矩形的尺寸(也就是该类别的浏览量)设置标签的字体大小。同时还可以加粗各个类别的外边框,让它们更加明显。最后的效果应该如图5-19所示。
图5-19 在R中创建、在Illustrator中编辑后的板块层级图
就是这样。现在的各个标签更加明显,而且颜色说明的含义也更加精确,整个图表变得更加易读。另外,我们还去掉了深灰色的背景以提升简洁度。当然了,标题和文字说明会对阐明图表的主旨提供帮助。
►在“How the Giants of Finance Shrank, Then Grew, Under the Financial Crisis”一文中,《纽约时报》使用了动态的板块层级图来显示金融危机时期股票市场的变化。地址是http://nyti.ms/9JUkWL。
Portfolio工具包在这一过程中承担了绝大部分工作。所以如果你打算采用自己的数据,唯一需要注意的地方就是确保正确的格式。你至少需要做到三件事:每一行数据需要一个独立的id、矩形尺寸的衡量依据、以及数据所属的父类别。你也可以用第四个度量标准来给矩形着色。第2章介绍了如何为数据定义必要的格式。