前言

大家对Processing的热情让我们备受鼓舞,但也深感鸭梨。之前翻译的两篇,我们自己也觉的不胜满意。经过一些讨论和思考,我们打算自己动手写教程。计划是这样的:

  1. 想要围绕一个具体的主题来讲解Processing。这样,到最后起码学会了用Processing完成一些具体的可视化,而不是一些不相关的图案。我们选的题目是数据可视化,因为这是我们的兴趣所在,也是我们的专长。
  2. 因为我们设定了上面的目标,所以不打算特别的来讲解Processing的语法和程序结构。如果想要专门花时间学习这些的。我们严重推荐ww同学的Processing学习笔记。我仔细读过了,真是写的相当好阿。你也可以买中文版的Processing互动编程艺术。不过我没看过,不发表意见。
  3. 因为很多关注我们的同学都是初学者,所以我们打算从最简单的例子开始,一步一步,尽量讲的比较细致。数据可视化最基本的就是各种图表了。就从这里开始把。
  4. 我们也想探讨论一些深一点的Processing可视化。这方面打算以介绍别人的例子,分析代码为主。希望大家给我们推荐案例。
  5. 最后,希望大家给我们留言,建议。你们的关注才能让我们坚持下去,谢谢!

那就开始吧!

让我们从最常用的柱状图(Bar Chart)开始。打算分三天来讲,从最基本的开始,一点点完善。

柱状图是由一系列长方形组成的,所以先来看看怎么画一个长方形。首先,我们要定义Sketch的大小,这就好比是你画布的大小。我们设的大小是200×200,这里是指200个像素(pixel)。计算机屏幕的分辨率就是像素,现在通常看到的是1400×900。 所以这个Sketch的宽是屏幕宽度的1/7。 我们要定义Sketch的背景的颜色,用的是函数background(r, g, b)。三个参数r, g, b分别是想要的背景色的红,绿,蓝三个通道的数值。这些数值在0到255之间。我们在这里用黑色,就是(0, 0, 0)。

画长方形的函数是rect(x, y, w, h)。这里x和y是长方形起点的坐标,w是长方形的宽度,而h是长方形的高度。Processing里长方形是怎么画的呢?这就要先了解 Processing里Sketch的坐标系。下面图里是200×200的Sketch。左上角是坐标原点(0, 0)。 然后右下角是(200, 200)。Sketch的中心点坐标是(100,100)。

画长方形的时候,从起点(x,y)出发,向x轴正方向延伸w,就是宽;向y轴正方向延伸h,就是高。所以长方形的其他三个顶点就是(x+w, y), (x, y+h), (x+w, y+h)。下面这段程序画了一个起点在(100, 100), 宽50,高80的长方形。我们用了fill()函数选择了用白色(255,255,255)来填充长方形。

size(200, 200);
background(0, 0, 0);
fill(255, 255, 255);
rect(100, 100, 50, 80);

把上面的程序贴到你的Processing窗口,运行一下。你会看到下面这样的Sketch。

和你想象的效果一样吗?是不是有点奇怪?长方形怎么往下长了呢?别忘了,Processing的坐标系是左上角为原点,从左到右和从上向下增长。从左到右没任何问题,但是从上到下就不太对了。我们一般画柱状图的习惯是把每个长方形的底边对齐,从下往上画阿。怎么办呢?很简单,我们只要把高度80变成负数 -80。这个长方形就往上长了。

rect (100,100,50,-80)

相信有些同学可能还是不太习惯。定式思维是,规定长方形的中心和长宽,而不是起点。我们可以通过Processing的rectMode(CENTER)函数设置按中心绘制的模式。

rectMode(CENTER);
rect(75, 60, 50, 80);

现在我们可以来开始画柱状图了。柱状图就是把一组数可视化成一排长方形。通常长方形的宽度相同,而高度由相对应的数决定。数字越大就越高。这些长方形的底边对齐,也就是说他们的起点的y轴坐标应该是一样的。我们随便选择一些数,把他们这些数放在Processing的数组中:

int[] numbers = { 2, 5, 3, 1, 6, 5, 9, 4, 7, 3, 2, 5, 1, 4, 2, 5 };

首先,我们想要所有的长方形底边对齐,所以他们的起点的y坐标应该是一样的,那就选200好了。所有的长方形宽度一样,那就选5好了。在柱状图中,长方形一个挨着一 个,所以第一个的x坐标从0开始到5,第二个就应该从5开始,以此类推。如果用公式表达的话,第i个长方形,起点的x坐标就是i*5。而长方形的高度可以直接用对应的数字。这段程序和之前的不太一样,我们要放在一个叫setup()的函数里面。Processing规定这个函数在运行的时候会被执行一次。

void setup()
{
     size(200,200);
     background(0);
     int[] numbers = { 2, 5, 3, 1, 6, 5, 9, 4, 7, 3, 2, 5, 1, 4, 2, 5 };
     fill(255,255,255);
     for(int i=0;i<numbers.length;i++){
         rect(i*5, 200, 5, -numbers[i]);
     }
}

显然长方形都太小了,不但看不清,而且没有很好的利用空间。我们现在想要柱状图填满整个Sketch。要做的是根据Sketch的大小来设置长方形的宽和高。柱状图通常很少有正方形的。让我们首先改变Sketch的大小,变成400×150。因为一共有numbers.length个长方形,每个的宽度就应该是400/numbers.length。对于高度,我们想要最高的长方形能从顶天立地,所以我们需要知道数组里的最大值:max(numbers)。然后单位高度就是150/max(numbers)。新的程序:

void setup()
{
    size(400,150);
    background(0);
    int[] numbers = { 2, 5, 3, 1, 6, 5, 9, 4, 7, 3, 2, 5, 1, 4, 2, 5 };
    int w = 400/numbers.length;
    int max_number = max(numbers);
    int h = 150/max_number;
    fill(255,255,255);
    for(int i=0;i<numbers.length;i++){
       rect(i*w, 150, w, -h*numbers[i]);
    }
}

得到的结果是这样的:

我们注意到,尽管我们算长方形位置的时候是一个挨着一个的,但是他们之间还是有黑色的分隔。这是因为每个Processing画的图形缺省都有黑色的边框。这对于我们的柱状图来说刚好,所以就不用改了。今天到这里,明天继续。

© 2011, 视物 | 致知. All rights reserved.

Related Posts:

  1. 这是我们纯原创的,请不要转载。如果想推荐给朋友,可以给他们发这篇的链接:http://www.vizinsight.com/2011/09/学用processing做数据可视化之柱状图-(1)/ 谢谢!

    • 噢。好的。
      V大,像这样的http://visualization.geblogs.com/visualization/aging/用java做出来的可视化案例用Processing可以实现木?

    • 这个可以的,等我写一个。哈哈
      不过,要澄清一点,processing其实就是java。所以,processing的程序其实可以在eclipse里面运行和调试。

    • 我仔细看了一下,你贴的这个作者是Ben Fry,也就是Processing的作者。所以这个东西99%的可能就是用processing写的,哈哈。