Created
November 16, 2012 11:57
-
-
Save geotheory/4086735 to your computer and use it in GitHub Desktop.
Twitter data visualisation in Processing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Data for this is available at https://dl.dropbox.com/u/46043231/data/twit.csv | |
String[][] allData; | |
int[][] grid; | |
int[][][] agGrid; | |
float[] count; | |
int[][] boxHeight; | |
int res = 35; // range from 20-50 | |
float latmin = 51.2; | |
float latmax = 51.8; | |
float lonmin = -0.6; | |
float lonmax = 0.4; | |
//import processing.video.*; | |
//MovieMaker mm; | |
//---------------------------------------- | |
void setup() { | |
size(500, 500, P3D); | |
background(0); | |
readData(); | |
aggregateData(); | |
frameRate(30); | |
boxHeight = new int[res][res]; | |
//String fileName = "movies/" + year() + "." + month() + "." + day() + " " + hour() + "." + minute() + ".mov"; | |
//mm = new MovieMaker(this, width, height, fileName, 30, MovieMaker.ANIMATION, MovieMaker.HIGH); | |
} | |
//---------------------------------------- | |
void readData() { | |
String [] dataIn = loadStrings("twit.csv"); | |
allData = new String[dataIn.length][10]; // table dimensions | |
count = new float[dataIn.length]; | |
grid = new int[dataIn.length][2]; // grid classification matrix | |
for (int i=0; i<dataIn.length; i++) { // iterate down the 'dataIn' array | |
String[] thisLine = split(dataIn[i], ","); // split strings by commas | |
for (int j=0; j<thisLine.length; j++) { // iterate across line values | |
allData[i][j] = thisLine[j]; // save each to data matrix | |
} | |
float lat = float(allData[i][3]); // convert to numeric | |
float lon = float(allData[i][4]); | |
float x = map(lon, lonmin, lonmax, 0, width); // map function | |
float y = map(lat, latmin, latmax, height, 0); | |
//generate a longer time index of 10:80 day-hour units | |
count[i] = round(10.0*(float(allData[i][5])+(float(allData[i][6])/23.0))); | |
//grid points | |
grid[i][0] = abs(int(round(map(lon, lonmin, lonmax, 1, res)))); | |
grid[i][1] = abs(int(round(map(lat, latmin, latmax, 1, res)))); | |
} | |
println("data read in"); | |
} | |
//---------------------------------------- | |
void aggregateData(){ | |
println(grid.length + " rows"); | |
agGrid = new int[69][res][res]; // new grid for aggregate data: [t][x][y] | |
// 'n' is for remembering 'j' outside of the 'j' loop | |
// as the twit dataset is sorted on time-series - so it makes sense not | |
// to reloop over grid lines already aggregated. | |
int n = 1; | |
for (int i=1; i<69; i++) { // iterate through time-index | |
// println(""); | |
// println("TIME INDEX: " + i); | |
if (n==grid.length) { | |
i=70; | |
} | |
for (int j=n; j<grid.length-1; j++) { // iterate through 'grid' | |
agGrid[i][ grid[j][0] ][ grid[j][1] ] += 1; // aggregate data: count grid lines (tweets) into appropriate agGrid box (+1/row) | |
//print("j" + j + ": " + agGrid[i][grid[j][0]][grid[j][1]] + " | "); | |
if (count[j]!=count[j+1]) { // i.e. the last row of time-segment | |
n=j+1; // remember 'j' position | |
j=grid.length; // terminate this time-segment's grid iteration | |
} | |
} | |
} | |
println("data aggregated"); | |
} | |
//---------------------------------------- | |
void draw() { | |
background(0); | |
ambientLight(150,150,150); | |
directionalLight(200,100,100,1,-1,0); | |
directionalLight(100,200,100,-1,1,0); | |
pushMatrix(); | |
translate(sin(frameCount/60.0)*300, cos(frameCount/60.0)*500, sin(frameCount/60.0)*150 + 200); | |
fill(0,0,0,50); | |
popMatrix(); | |
// camera(sin(frameCount/40.0)*375, cos(frameCount/40.0)*500, sin(frameCount/40.0)*150 + 180, mouseX, mouseY, 0, 0, 0, -1); | |
camera(50,400,200,0,0,0,0,0,-1); | |
int h = (frameCount*2)%69; // GENERATES NUMBER BETWEEN 1 AND 70 | |
float dim = 0.99; // box height reduction coefficient | |
// boxHeight = new int[res][res]; | |
noStroke();//70, 90, 250,100); | |
pushMatrix(); | |
translate(-250,-250,0); | |
for (int i=1; i<res; i++) { // iterate through x values | |
for (int j=1; j<res; j++) { // iterate through y values | |
boxHeight[i][j] = boxHeight[i][j]-round(boxHeight[i][j]*0.15); | |
if ( agGrid[h][i][j] > boxHeight[i][j] ) { | |
boxHeight[i][j] = agGrid[h][i][j]; | |
} | |
pushMatrix(); | |
translate(i*500/res, j*500/res, boxHeight[i][j]/2); // extrude | |
fill(constrain(90+boxHeight[i][j],90,255), constrain(130+boxHeight[i][j],130,150), constrain(255-boxHeight[i][j]/5,100,255), 255); | |
// stroke(50,50,50); | |
box(round(0.75*width/res),round(0.75*height/res), boxHeight[i][j]); | |
popMatrix(); | |
} | |
} | |
popMatrix(); | |
//mm.addFrame(); | |
println(h); | |
} | |
/*void keyPressed(){ | |
// if(key==' ') saveFrame("/images/" + frameCount + ".jpg"); | |
mm.finish(); | |
} | |
*/ | |
void keyPressed(){ | |
if(key==' ') saveFrame(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment