Introduction to Processing

Objectives

The goal of this lab is to provide a gentle introduction to Processing, the environment we will use for this class. It will also help you get used to drawing to the screen, loading data from a file, and thinking about how to represent data.

What is Processing?

Processing is actually several things:

  • A website.
  • A programming environment focused on learning computation design.
  • A sketchbook for rapid prototyping.
  • A 2D or 3D graphics API & rendering engine for Java.
  • An open project created by Casey Reas and Ben Fry.

It is especially useful in this course because it is straight-forward to learn and is well-suited to graphics applications. It is also compatible with Java, so if you already know that language, the learning curve should be fairly shallow.

It is great for generating and modifying images, and includes support for:

  • vector & raster drawing,
  • image processing,
  • color models,
  • mouse and keyboard events,
  • network communication,
  • object-oriented programming,
  • and lots more.

In short, it has what we need to be able to create complex applications, while letting us focus on the representation and interaction in our visualizations.

Examples

Similar Diversity Similar Diversity
by Philipp Steinweber & Andreas Koller

Travel Time Tube Map Travel Time Tube Map
by Tom Carden

Visualizing Haplotype Visualizing Haplotype
by Ben Fry (Cover of Nature)

Getting started

Processing includes its own development environment, shown below:

Processing Development Environment

The Processing development environment refers to projects as sketches (which is related to its origins as a “sketchbook” for rapid prototyping). A Sketch can be made up of several files, which can be .pde (processing development environment) or .java files.

Assignment 1

In our first assignment, we are going to learn how to use Processing to draw the following image:

La France

In order to do so, you will need to:

  1. Load and parse the data.
  2. Choose an internal data structure to represent these data.
  3. Draw them to the screen.

The data we will use comes from www.galichon.com/codesgeo. The original data was in the form:

- (name, postal code, insee code, longitude, latitude)
- (name, insee code, population, density)

To simplify things, we will instead use a pre-processed version of these data courtesy of Petra Isenberg, Jean-Daniel Fekete, Pierre Dragicevic and Frédéric Vernier. It merges these into:

- (postal code, x, y, insee code, place, population, density)

Download these data here

Getting started

First, open up Processing. In the lab, you can use the command-line by opening a Terminal window and typing:

/opt/processing-2.1/processing

If you are using your own computer, you can download Processing.

Then write the following code:

:::java
void setup() {
    size(800, 800);
}

void draw() {
    background(255);
}

The setup() and draw() methods are built-in methods in processing that are called automatically when your program starts and each time the window repaints, respectively.

Try pressing the Run button. You should see an 800 by 800-pixel wide window with a white background.

Loading data

Now lets take a look at the data we’re going to use. Open them in your preferred text editor. Notice that this a file containing a data table in a tab-separated format. Let’s go ahead and read that file:

:::java
void readData() {
    String[] lines = loadStrings("http://www.telecom-paristech.fr/~eagan/class/as2013/inf229/data/population.tsv");
    println(lines); // for debugging
}

Now call readData() from setup(). When you run the program, you should see this data file displayed on the console.

Parsing the data

Now let’s parse the data so we can actually make use of it.

:::java
float minX, maxX; // store the bounding box of all points
float minY, maxY;
int numPoints; // total number of places seen

void parseInfo(String line) { // Parse one line
    String infoString = line.substring(2); // remove the #
    String[] pieces = split(infoString, ',');
    numPoints = int(pieces[0]);
    minX = float(pieces[1]);
    maxX = flaot(pieces[2]);
    minY = float(pieces[3]);
    maxY = float(pieces[4]);
}

Now call parseInfo(lines[0]) from your readData() method. This will load the header information stored in the first line of the data file, and store them in the global variables min/max X/Y that we created. Next let’s load the data. First create two more global variables: float x[] and float y[]. Then add to the end of readData() :

:::java
x = new float[numPoints]; // create an array of numPoints floats
y = new float[numPoints];
for (int i = 2; i < numPoints+2; ++i) { // Why the +2?
    String pieces[] = split(lines[i], '\t');
    x[i-2] = float(pieces[1]);
    y[i-2] = float(pieces[2]);
}

Try running the program. You won’t see anything new, but it should at least compile and run. It’s usually a good idea to frequently run your program while you’re developing it to make sure you haven’t introduced any new bugs, even if you won’t necessarily see anything new.

Drawing

Now let’s get to the fun part. We’ve extracted the points from the data file and stored them in our x/y arrays. Let’s see what this looks like. Update the draw() method to add:

:::java
background(255);
color black = color(0);
for (int i = 0; i < numPoints; ++i) {
    set((int)x[i], (int)y[i], black); // Why won't this work?
}

Run the program, and marvel in the wonder of your beautiful drawing. Or fix any bugs and then marvel. /* FIXME: map() */

Places

That’s great for getting started, but what we’ve created so far is really only little more than an info vis “Hello world” (or, more properly, “hello France!”).

To better understand our toolbox, let’s open the menu Help > Reference. These are the builtin methods and functions of Processing. Take particular note of:

  • size()
  • point(), line(), triangle(), quad(), rect(), ellipse(), and bezier()
  • background(), fill(), stroke(), noFill(), noStroke(), strokeWeight(), strokeCap(), strokeJoin(), smooth(), noSmooth(), ellipseMode(), and rectMode().

Let’s create a class Place. Create a new tab (using the right-arrow icon on the right side of the window), and write the following code:

:::java
class Place {
    int postalCode;
    String name;
    float x;
    float y;
    float population;
    float density;
    
    // Put a drawing function here and call it from the main drawing loop
}

Let’s now get rid of those ugly x[] and y[] global variables and replace them with an array of Places.

On your own…

You should now have the tools you need to update your visualization to:

  • Show population and density

You’re also going to make your visualisation interactive. When the user clicks on a place, draw its name and postal code. You will need the following tools to do so:

Text rendering

Processing uses bitmap fonts to draw text. These are different than the system fonts installed. To create one, go to the Tools > Create Font... menu. This panel will let you generate a bitmap font you can use in your program. Copy the filename that is created at the bottom of the screen. Then double-check that the font file is in the data folder of your project using the Sketch > Show Sketch Folder menu.

To use the font, first create a global variable PFont labelFont to store the font. Then modify your setup() method to load and configure the font:

:::java
void setup() {
    // ...
    labelFont = loadFont("/* font filename from above */");
    textFont(labelFont, 32); // From now on, all drawing will use the labelFont at 32 point.
}

Then modify your drawing method to draw some text using text("Hello, France!", x, y) where x and y are the coordinates at which to draw the text.

User events

When the user performs certain actions, such as moving the mouse, pressing or releasing the mouse button, etc, Processing will call certain methods:

  • void mousePressed()
  • void mouseDragged()
  • void mouseReleased()

You can also use test which button is pressed with:

:::java
if (mousePressed == true) { ... }
if (mouseButton == left) { ... }

Creative Commons License Assignment courtesy of Petra Isenberg, Jean-Daniel Fekete, Pierre Dragicevic and Frédéric Vernier under a Creative Commons Attribution-ShareAlike 3.0 License.