DataViz : NYUAD 10th anniversary

Inspiration

This data visualization was done in celebration of NYU Abu Dhabi’s 10th anniversary. What has been the interest in NYU Abu Dhabi overtime for the past ten years based on google searches?

Process

Using Google Trends, I got the data of searches for NYUAD from 2004 to the present grouped by months.

After loading the data, I went through each column mapping the rows to a wider range of values. For the second column, I mapped from 150 to 0 as opposed to the other way round to avoid drawing the lines upside-down.

After cleaning my data through the map function, I drew lines with a little circle on top. The little circle on top was drawn using ellipses with small diameters. I used smooth() to draw lines with anti-aliased edges.

To make things more interesting, I added a new line with red color that shows the date and increment in searches when the mouse pointer is moved. I achieved this using the nfp () function which formats a number to a string and shows ” + ” when positive and ” – ” when negative.

Final Work

DataViz

Video

Challenges

Cleaning the data was the biggest challenge. Did a lot of trial and error to find the right scale for mapping. I had trouble making the lines a bit bigger. I wanted to deepen the line representing the start of each year but it looked horrible. I wanted to add labels below the line graph but it appeared to be clustered.

Code
// Line plot of NYUAD search per month

color [] Pride = {  #ffffff, #560BAD , #480CA8,#3A0CA3, #FF0000};
color [] palette = Pride;

Table table;

PFont titleFont;

int mx = 30; // mouseX position


void setup() {
 size(640, 200);
 
 // set fonts
 titleFont =  createFont("Georgia", 12);
 
 
 // load Data
 table = loadTable("NYUADTimeline.csv", "header");
 
 // draw with smooth anti-aliased edges
 smooth(2); 
 
}


void draw() {
  background(palette[0]);
  textFont(titleFont);
  stroke(palette[4]);
  fill(palette[3]);
  textAlign(CENTER);
  text("Interest in NYUAD per month over 10 years", width/2, 20);
  

  for (int row = 0; row < table.getRowCount(); row++) {
    
    String dates = table.getString(row, 0);
    float searches = table.getFloat(row, 1);
    float x = map(row, 0, 216, 0, 600);
    float y = map(searches, 0, 100, 150, 0);

    
   
  
    
    // SLIDER
    if((mx > 30) && (mx < 640)) {
      line(mx, 30, mx, 150);
      if(abs(mx - x) < 2) {
        fill(palette[4]);
       
       // show the dates and search count
        text(dates, mx + 6, 40);
        
        // format numbers into strings with 1 decimal to left and 3 to right
        text(nfp(searches, 1, 3), mx + 6, 55);
      }
    }  
    
   
    // DRAW Lines and dots on top
     
    // thickness of each line
    strokeWeight(1); 
    
    stroke(palette[1]);
    line(x, y, x, 150);
    noStroke();
    fill(palette[1]);
    int d = 3;
    ellipse(x, y, d, d);
   
  }
  
  
}



void mouseMoved() {
  mx = mouseX;
}
   
  

 

 

genArt : Ripple !

Description

Create a generative artwork using Object-Oriented Programming paying attention to the structure, clarity, and organization of your program.

Process

Saying goodbye to hardcoding was hard. How do I create a pleasing and satisfying to-watch art with little code?  After hours of thinking, it finally clicked. Why not recreate the natural phenomena of the ripple effect. Throw a little stone into water and it creates a mighty ripple. Yeah that’s the inspiration

I started off by exploring how I can play with ellipses to form the shapes of the ripple effect. As I was working on this piece deep in the night, I kept on repeating the ” final countdown ” tune so I decided to create my whole art in a form of a play or an exhibition.

The Intro!

The introduction of my exhibition starts with a count down. The countdown is actually a count up 🙂  which is centered in the middle of the screen. I then added the ripple effect. I added some colors to appeal to the eye

The Interlude!

Now we can kill some time by watching balls bouncing off walls and changing colors. Used some opacity to achieve a lightsaber effect.

 

The Playback!

In the playback, I created two spheres that clash with each other and disappear off the screen. Then, I removed the stroke and played with random colors. The outcome was unexpected 🙂 Yeah, it was fun.

The Exhibition!

I combined the intro to the interlude and the playback with a few tweaks. Yeah, and a little suspense, :).

Final Work

Challenges

The first challenge I faced was bouncing the ball off the walls.  For some reason, my method was not working after putting my function into a class. I tried multiple times to let a function inside a class run continuously but couldn’t get it to work. I spent hours learning how to make functions within classes run more than one time. Oh no! All this while, I’ve been thinking too hard, I just needed to add an if statement to my method.

Also, I was having trouble tweaking the randomness. Striking a balance between control over the elements and randomness was hard.  I did a lot of trial and error in the beginning to find the optimal, the just-right level of randomness

Finally, Ripple! one big thing I learned from this assignment is to let go, I stopped controlling the background colors, and boom! there goes this mesmerizing art.

Code

–  Main

Ripple genArt;

void setup() {
  size(640, 640);
  genArt = new Ripple( width/2, height/2);
}

void draw() {
  genArt.exhibit();
}


– Ripple Class

class Ripple {
  // data
  int x, x2, x3, y, y1, y2;
  int Width = width;
  int centerX, centerY;
  float circleWidth;
  int countUp;
  int counter;
  int speed;



  // constructor
  Ripple(int _x, int _y) {
    centerX = _x;
    centerY = _y;
    circleWidth = 500;
    countUp = 0;

    // bouncing balls coordinates and speed
    x = _x;
    y = _y;
    y1 = 80;
    y2 = 400;
    speed = 3;


    // clashing balls coordinates
    x2 = 640;
    x3 = 0;

    // exhibition counter
    counter = 0;
  }


  void intro() {

    // countdown

    fill(random(255), random(255), random(255), 10);
    textAlign(CENTER, CENTER);
    textSize(32);
    text( countUp +=1, centerX, centerY-5);


    // ellipses as rainbow ripple effect
    noFill();
    stroke(random(255), random(255), random(255), 90);
    ellipse(x, y, circleWidth, circleWidth);
    circleWidth += 20;

    // repeat ellipses with random colours
    if (circleWidth > 1000) {
      // clear background and start over
      background(255);
      circleWidth = frameCount*1.5;
    }
  }

  void interlude() {
    // background(60);

    ellipse(x, y, circleWidth, circleWidth);
    ellipse(x, y1, circleWidth, circleWidth);
    ellipse(x, y2, circleWidth, circleWidth);

    x += speed;
    y1 += speed;
    y2 += speed;

    // ball bounces off wall
    if (x + circleWidth/2> Width || x - circleWidth/2<0) {
      speed *= -1;
      //fill(random(255), 50);
      stroke(random(230), random(230), random( 250));
    }
  }

  void playback() {
    noStroke();
    //background(0);
    ellipse(x2, y, circleWidth, circleWidth);
    ellipse(x3, y, circleWidth, circleWidth);

    // expand the clashing balls as they approach each other
    if (x2<=640) {
      x2 = x2 -10;
      x3 = x3 + 10;
      circleWidth += 5;
    }


    // reset the cordinates of the clashing balls
    if (circleWidth > 1000) {
      circleWidth = 10;
      x2 = 640;
      x3 = 0;
      fill(random(250), random(250), random( 250), 50);
    }
  }





  // control exhibition
  void exhibit() {
    counter +=1;

    // play intro
    if ( counter < 1000) {
      intro();

      // go blank when timer is out
      if (counter > 650) {
        background(0);
      }
    }

    // play interlude and playback together
    else if ( counter < 2000) {

      interlude();
      playback();
    } else {
      background(255);
      counter = 600;
    }
  }


  void reset() {
    circleWidth = 100;
    y = centerY;
  }
}

 

References
  1.  https://commons.wikimedia.org/wiki/File:Ripple_effect_on_water.jpg

Simple Work of Art : CheckMate!

Description

Using loops (for() or while()) in some way, along with everything that you’ve learned so far, make a simple work of art. You may want to look at these old computer art magazines for inspiration.

Process

Finding inspiration from the Old Computer Graphics took a while. My search stopped when I saw art that combines two of the games I love – Yess crossword and checkers! Working on an art I love while meeting the requirements was really fun.

 

Not wasting much time, I jump into sketching. Yeah, it’s me again, the clearer the sketch, the easier the coding becomes 🙂 ;

 

I take back my words earlier, sketching doesn’t make it easier. I started off by exploring how I can play with rectangles to form the shapes I wanted.

The CheckerBoard!

Yeah, so now we are on to the fun part. I realized after countless hours of trying that I can use a nested for loop to draw the checkbox instead of rectangles and horizontal lines.

Using the old and even concept, coloring was not much a huddle.

 

 

 

 

 

The CrossWord!

Now on to the most technical part. In drawing the horizontal rectangles ( across), I randomize the x coordinates and the height of each rectangle given it a different start point and length

 

 

 

 

 

For the vertical rectangles ( criss). It was indeed a crisis. I used two rectangle functions and threw in as much randomization for the x and y coordinates as I can while maintaining the height and width of each rectangle.

Final Work

 

I also played around with random colors

Then I played around with noLoop() and noStoke()

 

Challenges

The first challenge I faced was making the crossword pattern. I tried a lot of rectangle shapes. I decided to use frameCount and it didn’t make it any simpler. Had to try one rectangle after another adjusting the multiplier till I got the trend. I converted all the single lines of rectangle code into a for-loop. This little trick of dividing the challenge into sub-challenges saved a lot of time. I finally ended up using random which did the trick.

Also, I was having trouble randomizing my crosses. I tried different options including noise and randomization, Noise seemed to work initially but failed so had to go back to random.

I did a lot of trial and error in the beginning, it wasn’t helpful so I switch to using mousePressed to determine coordinates and this also saved a lot of time.

Coloring the checkerboard was a big challenge but the concept of odd and even saved the day.

The last challenge was filling the crossword with dots as in the original image. Couldn’t figure that one out. Do you know how?

 

Checkmate! one big thing I learned from this assignment is to experiment, try things out and who knows, something cool might result in an accident. 🤗

Code
int centerX;
int cellSize = 40;
int cols, rows;


void setup() {
  size(640, 480);
  background(255);

  // number of columns and rows
  cols = 20;
  rows = 20;

  noLoop();
}

void draw() {



  fill(51);

  // CROSS WORD
  
  // drawing the across ( horizontal rectangles)
  for ( int h = 0; h < height; h+=10) {
    rect(random(height), h, random(width/2), 10);
  }


  // drawing the criss ( vertical rectangles)

  //fill(random(255));

  for (int m = 10; m < 100; m+=10) {
    rect(random(width), m, 10, 100);
    rect(random(width), random(height), 10, 100*m);
  }


  // CHECKBOARD

  for (int i = 8; i < cols; i++) {
    for (int j = 0; j < rows; j++) {

      // increasing the size of the x and y coordinate for each rectangle
      int x = i*cellSize;
      int y = j*cellSize;

      // Coloring checkboard
      if ((i+j) % 2 == 0) {
        fill(255); // even is white

        //fill(random(255),random(255), random(255));
      } else {
        fill(51);  // Odd is brown

        //fill(random(255));
      }

      rect(x, y, cellSize, cellSize);
    }
  }
}

 

 

Week1 : Self Portrait

Description

Make a self-portrait from basic shapes using simple drawing functions learned in class. The basic shapes includes but not limited to line, ellipse, rectangle, arc, and circle.

Process

The first step I took in drawing the self-portrait was to sketch the portrait. Having a visual of what I wanted to draw improve my pace overall.

In this project, I realized how useful rectangles can be. In drawing my face, I could have used an ellipse omitting my prominent jaws but I used a rectangle curving the bottom left and bottom right to properly show my jaws. Setting the rectangle mode to center, in the beginning, reduced significantly the time I would have spent experimenting with the right coordinates to use.

The top-to-down execution of Processing code helped a lot in coloring the portrait and in hiding unwanted parts of the shapes used. The execution made drawing and coloring my head, hands, and neck possible.

Using variables played an important role in centering the pupil for the eyes and the nose, eyes, mouth, and eyebrows for the face.

Challenges

The first challenge I faced was drawing my hair. The initial plan was to use an arc on top of my face and fill it with small black circles to depict afro hair. After hours of failing to fill the arc with small circles, I decided to used curly lines which also failed. Finally, I settled on using an ellipse and filling it with black color.

Another challenge I faced was centering my nose. Working with triangle function was hard, I had to read the reference and try out a lot of options before I finally got the nose in the center of the face

Last but not least, coloring my hands was a challenge because filling the torso which was a single arc with the shirt color filled the hand with the same color. I duplicated the arc for the torso and reduced its starting and stopping angles so that filling the color of the shirt won’t affect that of the hands.

Final Work

Code

int centerX;
int centerY;
float faceCenterX;
float faceCenterY;
float earWidth = 20;
float earHeight = 40;

void setup() {
  size(640, 480);
  background(180, 235, 52)
  centerX = width / 2;
  centerY = height / 2;
  faceCenterX = centerX;
  faceCenterY = centerY -100;
};

void draw() {
    stroke(0,0,0);
  rectMode(CENTER);
     fill(197, 140, 133); // skintone
   //neck
   rect(centerX,centerY, 55, 55);
   
   // ears
   ellipse(centerX-80 , centerY-100, earWidth, earHeight);
   ellipse(centerX +80, centerY-100, earWidth, earHeight);

  
   // hair 
    fill(0,0,0);
    ellipse(centerX,centerY-150,180,150);
   
  
   // face
   fill(197, 140, 133); // skintone
   rect(centerX,centerY-100, 150, 150, 3, 6, 50, 50);

   // eyebrows
   arc(faceCenterX-50,faceCenterY - 30, 50, 15, radians(193), radians(347));
   
   arc(faceCenterX+50,faceCenterY -30, 50, 15, radians(193), radians(347));
   
   // mouth
   
   fill(184, 105, 106);
   ellipse(faceCenterX,faceCenterY + 40, 60, 30);
   line(faceCenterX-30, faceCenterY + 40 , faceCenterX +30 , faceCenterY+40);
   
   
   // eyes
   fill(255,255,255); // eye color
   ellipse(faceCenterX -50, faceCenterY -20, 30, 10 );
            // pupil
           fill(0,0,0); // pupilcolor
           ellipse(faceCenterX - 50 , faceCenterY -20, 10, 10 );
           
   fill(255,255,255); //eye color 
   ellipse(faceCenterX + 50, faceCenterY -20, 30, 10 );
           // pupil
           fill(0,0,0); //pupil color
           ellipse(faceCenterX + 50 , faceCenterY -20, 10, 10 );
   
   
   fill(197, 140, 133); // skintone
   
   // nose
   triangle(faceCenterX-20,faceCenterY +20, faceCenterX, faceCenterY-20, 20+faceCenterX, faceCenterY+20);
   
   // torso

   //hands
   fill(197, 140, 133); // skintone
   arc(centerX,centerY+250,350,400,radians(160),radians(400));
   
   //shirt
   fill(43,58,222); //shirt color
   arc(centerX,centerY+200,350,400,radians(180),radians(360));
   line(centerX -170,centerY+150, centerX+170, centerY+150);
   stroke(43,58,222);
   rect(centerX,centerY+160, 250, 200);
 
   
}