tutorial 1.4:

Importing CSV data in Processing

In this example we'll use data imported from a CSV (comma-separated values) file to generate 2D geometry.

Any data that can be stored in an excel spreadsheet can be translated into CSV format. CSV is text-based data format that's commonly used to exchange data between applications. It's also used quite extensively in computer programming because it offers a very simple way to store and work with tabular data (in other words data that can be stored in a table, which is to say data that's organized into a grid of columns and rows). Every programming language offers tools that allow you to quickly generate CSV data from values stored in an array, or to feed data from a CSV file into an array. The advantage of importing CSV data into an array is that once it's in this format you can access many built-in Processing array functions for analysing and working with the data. For a list of array functions see the Processing.org reference page. There is also a useful tutorial on 2-dimensional arrays at Processing.org.

The tool offered by Processing for working with Tabular data is the Table object, which greatly simplifies the code needed for storing and reading tabular data. Each instance can store one table, and as a data structure is equivalent to a 2-dimensional array. Unlike arrays in Processing it is not necessary to declare the type of data to be stored or the size of the data set.

1) Start by copying and pasting the following code into a new empty sketch:


Make sure that you give it a new title / subtitle in the correct comment syntax


/*
    Tutorial 1.4 importing csv data. Mark Meagher and Adam Park Nov 2014
*/

Table myCSV; //declare a table object that will contain the CSV
String myDataFile = "UK_climate.csv";


void setup() {
  size(800, 400); // set the size of the display window
  background(200);
  myCSV = loadTable(myDataFile, "header"); //this loads the data from the CSV into the Table object. So long as your data isn't changing, this only needs to happen once
}

void draw() {
    initForm(); //This function can be called in the setup or the draw loop. Can you explain the difference?
}

Note how the Table instance is declared at the start of the script, before the setup as a global variable. The data from the CSV is loaded intot the Table instance in the setup() using the loadTable function which accepts two parameters: the name of the datafile (which must be located in the 'data' folder located within the sketch folder) and an options parameter. In the options parameter it is possible to indicate whether there is a header row and also the format of the data file (csv, tsv). The format of the data file must be indicated in the options parameter if the file does not have a file extension corresponding to the correct data format (see documentation for loadTable at Processing.org.



2) Write a function that creates some geometry based on the data.

Start by copying and pasting the following code into a new tab called 'functions':

void initForm() {

  int myRadius = 5;
  int myX = 10;
  int myCount = 0;
  int myColor = 200;
  for (TableRow row : myCSV.rows()) {

    int year = row.getInt("Year");
    float january = row.getFloat("JAN");
    float february = row.getFloat("FEB");

    int myY = 10 + (10*myCount);
    makeCircle(myRadius, myColor, myX, myY);
    myCount++;
    println("year = " +  year + " January value = " + january); //print values to the output window as a check that we're getting the correct data
  }
}

Note how we can use the TableRow object to extract each row from the Table object in turn, using the for() loop to iterate through the rows. This is a different for() syntax than we saw in the previous example and shows how this type of loop can also be used to iterate through all the rows returned by the method Table.rows(). The columns can then be accessed by name (if there is a header row) or by numeric ID (0,1,2, etc).

You should also paste our 'makeCircle' function from the previous tutorials:

void makeCircle(int myRadius, int myColor, int myX, int myY) {
  stroke (myColor);
  ellipse(myX, myY, myRadius, myRadius);
}


Note that in this example we loop through the rows of our Table instance and create a circle for each row. We're not yet doing anything with the data from the spreadsheet. You can download the data I'm working with here - this is data showing average (or mean - not quite sure) temperatures for each month over the last few years in the UK.