Week 5 Data Visualization – Leo Shirky

Inspiration:

I find that Google Trends is great for telling time when you search for seasonal or repetitive events. For example, searches for Mariah Carey’s “All I Want for Christmas” always increases around the start of the holiday season in the United States. I eventually chose to use Ramadan, as it occurs once per calendar year, but changes when in the calendar year it occurs.

Process:

I started by downloading the Google Trends spreadsheet and adding it to Processing. I first made a simple version of what I wanted the final graph to look like, simply by telling Processing to pull the dates and searches from the .csv file. This made a simple bar chart, at which point I started to mess with the scale I wanted. I had to map the values from the .csv chart into x and y coordinates. I did this simply by messing around with different values until I found a scale I liked.

Next I added a title and a date/searches counter to display the values from the .csv file. I thought that labelling each date and having a scale on the y-axis would be too difficult for the user to read. This calculator allowed the user to easily tell exactly when and how much “Ramadan” was being searched.

The final aspect that I wanted in my graph was to highlight the bar that was being selected. I wanted the color and thickness of the bar to change to make it very clear which was being selected. Rather than have the user click each bar, I wanted it to happen automatically based on where the users mouse was.

Final Work:

Below is a video displaying how the graph works.

 

Challenges:

I had a lot of trouble figuring out the highlighting. I made an integer mx for the x position of the mouse. I initially tried “if (mx == x)” with x being the x value of the bar, but that would only highlight a few bars when the mouse hovered over them, rather than each bar. In the end I used if(abs(mx>3)), which worked much better.

Code:

Table table;
PFont titleFont;
int mx = 30; // mouseX position
void setup() {
  size(1280, 400);
 titleFont =  createFont("Courier New", 15);
 table = loadTable("RamadanTimeline.csv", "header");
 smooth(0);
 
}
void draw() {
  background(235,236,237);
  textFont(titleFont);
  stroke(0);
  fill(227,70,126);
  textAlign(CENTER);
  text("Interest in Ramadan by Week over past 5 years", width/2, 50);
  fill(253,93,96);
  text("Data via Google Trends", width/2, 70);
  
//take data from the .csv file
  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, width);
    float y = map(searches, 0, 100, 375, 60);
    
//draw the lines on the graph, and change the color of the selected line
    line(x, y, x, 375);
    if(abs(mx - x)<3){
      strokeWeight(6);
      stroke(252,192,109);
    }else{
      strokeWeight(2);
      stroke(60,73,129);
    }

//display the date and data for each selected line
    if(abs(mx - x) < 3) {
      fill(66,190,171);
      text(dates, width-50, 50);
      text(nfp(searches, 1, 3), width-50, 80);
      }
    }
  }
 
void mouseMoved() {
  mx = mouseX;
}

 

Week 3: Generative Object-Oriented Art Leo Shirky

Intro:

My sister used to love butterflies, so I decided I would try to animate a Monarch butterfly migration flight in Processing.

Process:

I started by creating a class called Butterflies, and made a simple butterfly shape, with a body and wings. I then added some code that would make the Butterflies fly along the screen at varying speeds and at random points on the X axis to give a sense of magnitude to the migration.

Finally, in order to make the animation more dynamic, I added some code that told the Butterflies to move towards the X coordinate of the mouse, so that the user had some control over the animation.

Challenges:

I really wanted the butterflies to flap their wings as they flew, but I couldn’t figure out how to make that happen. I tried to add a variable butterflyWing with two possible states, butterflyExtend and butterflyContract. I wanted the butterflies to alternate between the two randomly on every frame count. I drew the two states, but no matter what I tried, I couldn’t get the result I wanted. I also wasn’t sure how to even search for what I wanted. I ended up watching a number of Coding Train videos in hopes of finding some help, but in the end I was unsuccessful.

Final:

Code:

The Butterfly Class code:

class Butterfly{
  float posX, posY;
  float butterflyWidth, butterflyHeight;
  color butterflyColor;
  float speed;
  
  Butterfly(float _posX_, float _posY_, float _speed){
    posX = _posX_;
    posY = _posY_;
    butterflyWidth = random(10, 20);
    butterflyHeight = random(50, 100);
    butterflyColor = color(252,127,3);
    speed = _speed;
}

void migration(){
 butterflyBody();
 butterflyWing();
 butterFly();
 update();
}

void constructButterfly(float _posX_,float _posY_){
  
}

void butterFly(){
  posY += speed;
  
  if (posY > height+butterflyHeight/2) {
    posY = +butterflyHeight/2;
  }
    

}

void update(){ 
  if (posX > mouseX){
    posX --;
  }
  if (posX < mouseX){
    posX ++;
  }
}

void butterflyBody(){
  fill(0);
  stroke(0);
  strokeWeight(1);
  strokeJoin(ROUND);
  ellipse(posX, posY, butterflyWidth, butterflyHeight);
}

void butterflyWing(){
  fill(butterflyColor);
  triangle(posX, posY, posX-butterflyHeight, posY+butterflyHeight/20, posX-butterflyHeight, posY+butterflyHeight);
  triangle(posX, posY, posX+butterflyHeight, posY+butterflyHeight/20, posX+butterflyHeight, posY+butterflyHeight);
  triangle(posX, posY, posX-butterflyHeight, posY-butterflyHeight/20, posX-butterflyHeight, posY-butterflyHeight);
  triangle(posX, posY, posX+butterflyHeight, posY-butterflyHeight/20, posX+butterflyHeight, posY-butterflyHeight);

}
}

The operational code:

Butterfly[] myButterflies;

void setup(){
 size(1280, 1280); 
 rectMode(CENTER);
 
 myButterflies = new Butterfly[50];
 for (int i=0; i<myButterflies.length; i++){
   myButterflies[i] = new Butterfly(random(width), height + 100, random(5, 10));
 }
}

void draw() {
  background(255);
  
  for (int i=0; i<myButterflies.length; i++){
    myButterflies[i].migration();
  }
}

 

Week 2 – Simple Work of Art

I was unsure how to approach this assignment. I am new to coding, and I am also not an artist in any way, shape, or form. Coming up with ideas was difficult, as I am not used to looking for inspiration and executing the vision. Most of my initial ideas were to try and replicate or recreate existing pieces of art, but I felt that was too uncreative. When I began to formulate my own ideas, I quickly became frustrated, as I would often bite off more than I could chew, and very quickly realize that I could not execute my own vision. In the end, I settled on trying to recreate a picture I took recently of a sunset over the beach.

My beach photo

I thought that this would provide some new challenges, while also not being too busy, and hopefully looking good in the end. I was looking forward to figuring out the gradient, and getting some movement in the grass and the sun. I basically wanted to create a GIF. The toughest thing for me to work out was the grass, which I wanted to move. I tried creating random ellipses, at first, but I didn’t like the way it looked. In the end, I used arcs, which I think worked out well. I also got the sun to set behind the sand and reappear at the top of the screen, which I thought was a cool effect.

float x = 0;
float y = 0;
float circleY;
float ySpeed=2;

void setup(){
  size(680,780);
  // Define colors
  b1 = color(255,218,185);
  b2 = color(188,143,143);
  c1 = color(255);
  c2 = color(0);
  circleY=height/3;

  //noLoop();
}

int Y_AXIS = 1;
int X_AXIS = 2;
color b1, b2, c1, c2;

void draw() {
//sky
  setGradient(0, 0, width, height/2, b2, b1, X_AXIS);
//sun
  stroke(255,215,0);
  fill(255);
  ellipse(0+width/5,circleY,100,100);
  circleY = circleY + ySpeed;
  if(circleY>height/1.5){
    circleY=-100;
  }
//sand
  fill(255,222,173);
  noStroke();
  quad(0,height/2,width,height/2,width,height,0,height/1.3);
//road
  fill(105);
  noStroke();
  quad(0,height/1.3,width,height/1.1,width,height,0,height);
  grass();
}

  void setGradient(int x, int y, float w, float h, color c1, color c2, int axis ) {
  noFill();
  if (axis == X_AXIS) {
    for (int i = x; i <= x+h; i++) {
      float inter = map(i, x, x+h, 0, 1);
      color b = lerpColor(b1, b2, inter);
      stroke(b);
      line(x, i, x+w, i);
      }
    }
  }

void grass() {
  for (int i =0; i<width; i+=1) {
    stroke(85,107,47);
    noFill();
    arc(i+random(8), height/1.5-random(height/6), i, 100, radians(0), radians(45));
  }
}

 

Leo Shirky Self Portrait

Background

I spent a few minutes thinking about what the major features of my face were, and would therefore be important to preserve in the self-portrait. I ended up deciding to have my nose, my ears, my earrings, and my excuse for facial hair. I wanted to have my hair as well, although that ended up being difficult for me to figure out.

Process

I started with the face, going for a narrow-ish ellipse, as my face is quite narrow. I added the eyes next, with two more ellipses and circles. I made a float for eyeSpacing = 50, and used this as my standard unit that every other distance was based on.

The nose went next, and as I have quite a prominent nose, I tried to capture that in the self-portrait. Once I had the eyes and nose in a place I was happy with, I moved onto the rest of the face. The mouth, ears, and earrings were all ellipses, and not too difficult to add in.

I had no idea how to do hair, so I took the easy route and made me wear a hat instead. Below is the code for the hat, along with the NYU logo (violet pride!). I used an arc for the U in the NYU logo, and once I figured out how to use the arc in Processing, I moved onto the beard and mustache, both of which were arcs as well.

Challenges

As mentioned above, the hair was difficult and so I stuck with using a hat. Other than that, I felt that the creation and placement of each of the shapes was relatively easy once I had the process down.

Final

float circleSize = 300;
float eyeSize = 50;

int x, y;
x = width/2;
y = height/2;
float eyeSpacing = 50;
size(480, 480);

//ears
stroke(0);
fill(187, 109, 74);
ellipse(x - eyeSpacing * 2.5, y + eyeSize/4, eyeSize, eyeSize * 2);
ellipse(x + eyeSpacing * 2.5, y + eyeSize/4, eyeSize, eyeSize * 2);

//earrings
stroke(0);
fill(128, 128, 128);
circle(x - eyeSpacing *2.5, y + eyeSize, eyeSize/4);
circle(x + eyeSpacing *2.5, y + eyeSize, eyeSize/4);

//face
stroke(0);
fill(204, 132, 67);
ellipse(x, y, circleSize/1.3, circleSize);

//eyeballs
stroke(0);
fill(255);
ellipse(x - eyeSpacing, y - eyeSpacing/2, eyeSize, eyeSize/2);
ellipse(x + eyeSpacing, y - eyeSpacing/2, eyeSize, eyeSize/2);

//irises
stroke(0);
fill(50, 25, 10);
ellipse(x - eyeSpacing, y - eyeSpacing/2, eyeSize/3, eyeSize/3);
ellipse(x + eyeSpacing, y - eyeSpacing/2, eyeSize/3, eyeSize/3);

//nose
stroke(0);
fill(190, 114, 60);
triangle(x - eyeSpacing/10, y - 25, x - eyeSpacing/10, y + eyeSpacing, x + eyeSpacing/2, y + eyeSpacing);

//mouth
stroke(0);
fill(199, 122, 88);
arc(x, y + eyeSpacing * 1.6, 80, 15, 0, PI, CHORD);
arc(x, y + eyeSpacing * 1.6, 80, 15, PI, TWO_PI);

//beard
stroke(0, 0, 0, 185);
noFill();
strokeWeight(8);
arc(x, y + eyeSpacing/1.2, eyeSpacing * 4.25, eyeSpacing * 4.25, 0, PI, OPEN);

//moustache
stroke(0, 0, 0, 185);
noFill();
strokeWeight(6);
arc(x, y + eyeSpacing * 2.25, eyeSpacing * 3, eyeSpacing * 2, PI, TWO_PI);

//goatee
stroke(0, 0, 0, 185);
line(x, y + eyeSpacing * 1.9, x, y + eyeSpacing * 2.3);

//hat
stroke(0);
strokeWeight(1);
fill(87, 6, 140);
arc(x, y - eyeSpacing, 225, 200, PI, TWO_PI);

//hat logo
stroke(255);
strokeWeight(8);

//N
line(x - eyeSpacing, y - eyeSpacing * 1.2, x - eyeSpacing, y - eyeSpacing * 2);
line(x - eyeSpacing, y - eyeSpacing * 2, x - eyeSpacing/2, y - eyeSpacing * 1.2);
line(x - eyeSpacing/2, y - eyeSpacing * 1.2, x - eyeSpacing/2, y - eyeSpacing * 2);

//Y
line(x, y - eyeSpacing * 1.2, x, y - eyeSpacing * 1.5);
line(x - eyeSpacing/3, y - eyeSpacing * 2, x, y - eyeSpacing * 1.5);
line(x + eyeSpacing/3, y - eyeSpacing * 2, x, y - eyeSpacing * 1.5);

//U
noFill();
arc(x + eyeSpacing * 0.9, y - eyeSpacing * 2, eyeSpacing * 0.8, eyeSpacing * 1.5, 0, PI, OPEN);