LO-07: Visualizing Information

A Visualisation Project by Stamen Design: Metagenomics with The Banfield Lab

Usually, information Visualisation examples I have seen either visualise quantified data to tell a story in compelling forms, most data visualizations on the internet are complicated, without covering the complexity of scale or information, the Metagenomics project by Stamen Design, on the other hand, takes into consideration a vast libraries of life and categorisation of species into a large map that uses a simple, excel like cell structure but encodes a vast amount of information in the way it is ordered and color-coded. This project is called “New images of complex microbiome environments”.

Erik Rodenbeck details the process of collaboration and creating this project.

https://stamen.com/wp-content/uploads/2020/06/banfield_metag.gif



Stamen Design is a data and information design studio. They partner with educational institutions and world organisations to use data and design to weave useful narratives that bring our attention to important information about our world.

As per the document published by Stamen Design, “Understanding the genomic content of an ecosystem yields incredible insight into who the dominant organisms are, the minor constituents, and all levels in between… including viruses”. Given that our lives are currently affected by a virus that seems like an abstract entity, but is a living organism with a cell-structure, this application of information visualisation to see something of a big, intangible scale is an important application of visual design in making the abstract concrete. Not only does the project encode tonnes of information, but it acts as a living document, that scientists can use as a library to understand this information.

Having been a fan of Stamen Design’s work for years, what I like about their work, is that they master the ability to encode complex information in simple geometric shapes.

From the perspective of a p5.js learner, this teaches me that I can use the simple functions of p5.js to create compelling visual information.

For example, in the image, above, I could imagine that using a mouseX, mouseY to highlight some parts of the map, and creating set of bars the heights of which can change based on the mouse position, p5.js can be used to create visualisations and paired with the backend engine of a dataset to tell stories through data.

Project 7: Curves

curves cb
//global variables
var nPoints = 1000;
var angle = 0;

function setup() {
    createCanvas(480, 480);
}

function draw() {
    background(mouseY, 100, mouseX); //change background color
    //draw 2 sets of 36 hypotrochoids 
    for (var x = 80; x <= 400; x += 64) {
        for (var y = 80; y <= 400; y += 64) {
            push();
            translate(x, y);
            drawHypotrochoid1();
            drawHypotrochoid2();
            pop();
        }
    }
}

function drawHypotrochoid1() {
    var a = map(mouseX, 0, 480, 0, 80); //radius of outside circle
    var b = map(mouseX, 0, 480, 0, 20); //radius of inside circle
    var h = map(mouseY, 0, 480, 0, 40); //point distance from center of inner circle

    strokeWeight(.5);
    stroke(mouseX, mouseY, 100); //change stroke color
    noFill();
    beginShape(); //create hypotrochoid
    for (var i=0; i<nPoints; i++) {
        var angle = map(i, 0, 100, 0, TWO_PI);
        x = (a-b) * cos(angle) + h * cos(((a-b)/b) * angle);
        y = (a-b) * sin(angle) - h * sin(((a-b)/b) * angle);
        vertex(x, y);
    }
    endShape();
}

function drawHypotrochoid2() {
    var a = map(mouseX, 0, 480, 2, 80); //radius of outside circle
    var b = map(mouseX, 0, 480, 2, 20); //radius of inside circle
    var h = map(mouseY, 0, 480, 2, 40); //point distance from center of inner circle

    strokeWeight(.35);
    stroke(mouseX, mouseX, mouseY); //change stroke color
    noFill();
    beginShape(); //create hypotrochoid
    for (var i=0; i<nPoints; i++) {
        var angle = map(i, 0, 100, 0, TWO_PI);
        x = (a-b) * cos(angle) + h * cos(((a-b)/b) * angle);
        y = (a-b) * sin(angle) - h * sin(((a-b)/b) * angle);
        vertex(x, y);
    }
    endShape();
}

After exploring the WolframMathWorld site, I found hypotrochoids and thought that they were very dynamic and interesting. I decided to create my project with two sets of overlapping hypotrochoids to create a field of growing flower-like shapes. To make the composition interactive, I coded the mouse position to control the variables and colors of the hypotrochoids as well as the background color.

top left, top right, bottom left, bottom right
other screenshots

Looking Outwards 07 – Information Visualization

https://guns.periscopic.com/

On their website, Periscopic brands themselves as a “socially conscious data visualization firm”. They are a team of designers who bring light to societal issues through striking visualizations, such this one, the annual number of gun homicides in the US. 

This visualization represents the lives of those lost to a bullet through an arc of time. A victim’s arc starts as a bright orange line and fades to ash gray at the point they were killed, and the arc extends to the point of their expected natural life expectancy. Each arc can be clicked on providing more information about the homicide and expected lifespan. Periscopic mentions that the gun data was in ASCII format originally, making it difficult to extract the data for artists who had little coding experience. They have converted the data into CSV format and shared it freely.

This visualization struck me by how simple yet powerful its message is. Knowing the context of gun killings that this graphic conveys, the way the arcs turn from a passionate orange to lifeless gray is chilling, especially when seeing the vast number of lines form into a faded mass of death. And even if the 2018 death count of 11,356 doesn’t seem like much, the 472,332 lost years of human life makes it clear that gun homicides are a problem we must address.

Project 07 – Composition with Curves

I wasn’t really inspired by anything this time but I had an idea in mind of a rotating curve that had a trailing effect. I ended up with a variable epicycloid curve, formed by a point traced by a circle’s radius as it rotates around a larger circle. Clicking on the screen adds “petals” to the shape of the curve. At first, I wanted to experiment with a reuleaux triangle and make an animation similar to a rotary engine, but couldn’t figure out the math behind making the triangle follow an eccentric path.

sketch

/*
 * Eric Zhao
 * ezhao2@andrew.cmu.edu
 *
 * Interactive composition with epicycloid curves
 * that changes color with a gradient effect. Click
 * to increase the number of "petals" on the curves.
 *
 */
var numPoints = 75;
var thetaCanvas = 0;
var rotateSpeed = 2;
var multiplier = 2;
var totalScale;
var epicycloid = [];
var baseFill;

function setup() {
    createCanvas(480, 480);
    background(220);
    strokeWeight(2);
    fill(0);
    angleMode(DEGREES);
    colorMode(HSB);
}

function draw() {
        for (let i = 0; i < 10; i++){
        //creates series of nested epicycloid curve objects
        epicycloid[i] = new Object();
        epicycloid[i].shapeScale = 1 - i/10;
        epicycloid[i].a = epicycloid[i].shapeScale * 100;
        epicycloid[i].b = epicycloid[i].a / multiplier;
        epicycloid[i].theta = 0;
    }

    totalScale = map(sin(thetaCanvas), -1, 1, 0.33, 1);
    //makes composition zoom in and out smoothly
    background(0);

    push();
    translate(width/2, height/2);
    rotate(thetaCanvas);
    scale(totalScale);
    for (let i = 0; i < epicycloid.length; i++){
        //slightly offsets hue and rotation of each successive curve
        push();
        rotate(i*10);
        baseFill = ((thetaCanvas + i*10)*2) % 360;
        stroke(baseFill, 100, 100);
        epicycloidCurve(epicycloid[i]);
        pop();
    }
    pop();
    thetaCanvas += rotateSpeed;
}
function epicycloidCurve(e){
    //Epicycloid curve equation
    beginShape();
    for(let i = 0; i <= numPoints; i++){
        e.theta = map(i, 0, numPoints, 0, 360);
        e.x = ((e.a + e.b) * cos(e.theta) - e.b * cos(((e.a + e.b)/e.b) *
        e.theta));
        e.y = ((e.a + e.b) * sin(e.theta) - e.b * sin(((e.a + e.b)/e.b) *
        e.theta));
        curveVertex(e.x, e.y);
    }
    endShape(CLOSE);
}

function mousePressed(){
    //changes number of "petals" in the epicycloid
    multiplier++;
    if(multiplier > 5){
        multiplier = 2;
    }
}


Project-07-Curves

This is based on a hypotrochoid, which is a point rotating around a circle that is rotating around a larger circle. The point is supposed to create a looping pattern around the larger circle. I changed this by having the position of the mouse affect how fast the point would rotate, breaking the looping pattern created by a hypotrochoid. In addition, I also had the mouse affect the speed at which the inner circle was rotating around the outer circle and the distance the point is from the inner circle. It is a little activity where you can try to fill in the backgroudn with the blue but it is challenging because the point in always rotating and affected by the mouse position.

sketch

var r = 0 // rotation angle of outer circle
var r1 = 0 // rotation angle for inner circle
function setup() {
    createCanvas(480, 480);
    background(0);
    strokeWeight(0);
}

function draw() {
    fill(255);
    textSize(20);
    text('Fill in the background!',0,20);
    translate(width/2,height/2);
    scale(.8);
    speedr = map(mouseX,0,480,0,3,true);
    rotate(radians(r));
    r += speedr
    outercircle();
    innercircle();

    function innercircle(){
      push();
      fill(0,255,0);
      translate(0,170);
      speedr1 = map(mouseY,0,480,1,5,true);
      rotate(radians(r1));
      r1 += speedr1
      circle(0,0,60);
      point();
      pop();

      function point(){
        fill(0,0,255);
        cdistance = map(mouseX,0,480,20,150);
        circle(0,cdistance,30);
      }
    }
    function outercircle(){
      fill(255,0,0);
      circle(0,0,400);
    }
}

Looking Outwards-07

Nathan Yau is using data from the running app RunKeeper to create visualizations of the most taken courses or paths runners take in different cities. Nathan is a statistician from FlowingData who focuses on information design, as seen in the informational maps he has created below. He finds that visualization is a key way to make data more accessible and attractive. 

He created these data visualizations for 18 major US cities, including Chicago, LA, and New York City. He simply concluded that most runners love to run near nature, which are near water and parks.

To create these visualizations he may have used photoshop to collage all the paths of every runner or maybe if he used p5js he created arrays that marked each location as a point and when each location is marked the density increases, which increases the deepness of the purple as well.

Philadelphia running paths
New York City running paths

LookingOutwards-07

Martin Wattenberg is a co-leader of the People + AI Research initiative at Google. My career has encompassed machine learning, visualization, journalism, and art. Asking a question to himself, “what does music look like?” made him create this art piece. According to him, The Shape of Song is an attempt to answer his paradoxical question. I admire how he related music with this “visualization method called an arc diagram that highlighted repeated sections of music–or of any sequence–with translucent arcs.” It is very interesting to see how arc diagrams shape different thicknesses, sizes, saturation, etc to express diverse kinds of music. Just like every music has its own sequence, all of these art pieces create their own unique components.

LO 07 Data Visualization

TableTop Whale is an online blogger currently working in at the New York Times graphics department. Her work is specialized towards information design with a focus o science communication. Her PHD work was done in Biology and Data science. On her blog the tableTop whale, she posts a variety of data visualization graphics. I think what intrigues me the most is her explorations on the geology of various planets of the solar system. Mapping terrain and topography has been an interest of explorers for centuries even before the age of exploration. In the past cartographers used various analog techniques to map out the world as we know today. Now, with the avdvent of GIS data, we have the capability creating maps almost on demand with digital tools such as ARC GIS and a variety of other Geospatial data visualizer. What’s interesting about TableTop Whale’s work is that she uses USGS’s data sets for the planets, but renders them in a style that evokes maps of the age of sail. This is interesting because, the style evokes a sense of unknown and allows for out imagination to run wild about the possibilities of new uncharted territory. That’s also what’s so special about having large datasets to manipulate and visualize, it can allow for new information to emerge from things we already know about. Allowing us to dive even deeper into what we already know possibly defining the unknown.

https://tabletopwhale.com/index.html

Project 07: Composition with Curves

I decided to go with a butterfly curve because I thought it looked cool. Because of the name, I decided to make my project a butterfly flying in the sky. For the background, I just reused my clouds that I made for last week’s deliverables. Instead of having them move depending on what minute it was, I just set a constant to add to the x values of the ellipses the clouds were made of.

butterflyDownload
var translateX;
var translateY;
var nPoints=1000;
var butterfly=true;
var cloudScale=[0.5, 0.75, 1, 1.25, 1.5];
var x=0;
var dx=0.1;

function setup() {
    createCanvas(480, 480);
    translateX=width/2;
    translateY=height/2;
}

function draw() {
    background(222, 245, 253);
    drawClouds();
    push();
    translate(translateX, translateY);
    drawButterfly();
    pop();
}

function drawButterfly(){
    //Butterfly curve https://mathworld.wolfram.com/ButterflyCurve.html
    //this draws a butterfly curve to make the butterfly
    beginShape();
    scale(50);
    strokeWeight(0.02);
    stroke(255, 200);
    var x;
    var y;
    var angle=radians(map(mouseY, 0, height, 0, 360)); //rotation depends on mouseY
    rotate(angle);
    var m=map(mouseX, 0, width, 0, 25); //the size/extent of the curve of the butterfly depends on mouseX
    for (var i=0; i<nPoints; i++){
        var t=map(i, 0, nPoints, 0, m*TWO_PI); //var m is multiplied times the upper limit of the map function
        x=sin(t)*(exp(cos(t))-2*cos(4*t)+pow(sin((1/12)*t), 5));
        y=cos(t)*(exp(cos(t))-2*cos(4*t)+pow(sin((1/12)*t), 5));
        vertex(x, y);
        fill(228, 198, 245, 150);
    }
    endShape();
}

function mousePressed(){
    //changes position depending on where you click
    translateX=mouseX;
    translateY=mouseY;
}

function drawClouds(){
    //smallest cloud--cloud 1
    push();
    fill(250, 250);
    noStroke();
    scale(cloudScale[0]);
    translate(500,100);
    cloud();
    pop();

    //cloud 2
    push();
    fill(250, 250);
    noStroke();
    scale(cloudScale[1]);
    translate(100, 250);
    cloud();
    pop();

    //cloud 3
    push();
    fill(250, 250);
    noStroke();
    scale(cloudScale[2]);
    translate(400, 350);
    cloud();
    pop();

    //cloud 4
    push();
    fill(250, 250);
    noStroke();
    scale(cloudScale[3]);
    translate(0, 50);
    cloud();
    pop();

    //cloud 5
    push();
    fill(250, 250);
    noStroke();
    scale(cloudScale[4]);
    translate(-50, 250);
    cloud();
    pop();
}

function cloud(){
    ellipse(x+30, 10, 60, 40);
    ellipse(x+40, 40, 90, 50);
    ellipse(x, 40, 100, 50);
    ellipse(x, 15, 55, 35);
    x=x+dx;
    //once the clouds go off the screen, they reappear on the other side
    if(x>width){
        x=0;
    }
}

It rotates depending on where mouseY is and also draws the curve as mouseX goes from left to right.

You can also click to change the origin of the image and move the butterfly around.

Project 7 Curves Composition

There are two hypotrochoids that are being drawn simultaneously in this program, as Mouse Y changes you can alter the pedals of the hypotrochoids., the lines redraw themselves every 3 loops around the circle so as you move Mouse Y around you begin to get an overlay of various patterns.

sketch
//tjchen 
// section a 
// 07 project composisiton with curves
var t = 0
var numPoints = 100;// global set up of num of points on circle
var lineX = [];
var lineY = [];
var lineX2 = [];
var lineY2= [];
function setup() {
    createCanvas(480, 480);
    background(0);
    strokeWeight(1);
    stroke(255);
    noFill();
}


function draw() {
    background(0);
    translate(width/2,height/2)
    stroke(255,0,0);
    draw_hypotrochoid_1(t);
    stroke(0,255,0);
    draw_hypotrochoid_2(t);
    t+=1; 
}


function draw_hypotrochoid_1(t){
    var a = 150; // radius of large circle 
    var b = 8; // radius of spinning circle 
    var h = mouseY/10; // location of fixed point 
    var xH= (a-b) * cos (radians(t)) + h * cos(((a-b)/b)*(radians(t)));
    var yH = (a-b) * sin (radians(t)) - h * sin(((a-b)/b)*(radians(t))); 
    circle(xH,yH,10);;
    lineX.push(xH);
    lineY.push(yH);
    if (radians(t)>4*PI){ // 4 trips around the circle before redrawing circle 
        lineX.shift();
        lineY.shift();
    }
    strokeWeight(1);
    for (i=0; i < lineX.length-1; i++){
        line(lineX[i], lineY[i], lineX[i+1], lineY[i+1]);
    }


} 

function draw_hypotrochoid_2(t){
    var a2 = 200; // radius of large circle 
    var b2 = 8; // radius of spinning circle 
    var h2 = mouseX/10; // location of fixed point 
    var xH2= (a2-b2) * cos (radians(t)) + h2 * cos(((a2-b2)/b2)*(radians(t)));
    var yH2 = (a2-b2) * sin (radians(t)) - h2 * sin(((a2-b2)/b2)*(radians(t))); 
    circle(xH2,yH2,10);;
    lineX2.push(xH2);
    lineY2.push(yH2);
    if (radians(t)>4*PI){ // 4 trips around the circle before redrawing circle 
        lineX2.shift();
        lineY2.shift();
    }
    strokeWeight(1);
    for (i=0; i < lineX2.length-1; i++){
        line(lineX2[i], lineY2[i], lineX2[i+1], lineY2[i+1]);
    }


} 
the Circle transitioning
curves in one composition

curves in another composition