PROJ 1: VISUALIZING the CULTURE ANALYSIS in 2D (PROCESSING)

glegrady
Posts: 203
Joined: Wed Sep 22, 2010 12:26 pm

PROJ 1: VISUALIZING the CULTURE ANALYSIS in 2D (PROCESSING)

Post by glegrady » Sat Dec 26, 2015 6:47 pm

PROJ 1: VISUALIZING the CULTURE ANALYSIS in 2D (PROCESSING)

The assignment is to create a 2D Matrix visualization in Processing that is to include the following:

A 2D grid of cells based on 3 numeric columns of data from a MySQL query you have stored in a csv file as per the first assignment.

Each cell's vertical (Y) and horizontal (X) position and color value to be determined by the 3 csv columns.

--------------------------------------------
VISUALIZATION DETAILS:
MATRIX BASED: The visualization should not be a linear (time/change) frequency graph (we will do this in the 3D version) but use the cells to each represent a data value This means using at least 3 metadata for each item mapped (horizontal, vertical, and color value). There is flexibility in the design of the 2D matrix but it needs to make sense, everything should be there for a reason, and it should NOT be a graph.

SIZE/DATA: Length and Height of the matrix each represent a data value. The 3rd value is to be represented by coloring cells either using, color in RGB, or saturation, or brightness in HSB, or any other way where each cell has a x,y, location, and it is differentiated from the other cells through color, or scale or any other means.

COLOR CODING: 99% of science visualizations use the green – yellow- red color system. Experiment with/invent a different color scheme. Try http://tristen.ca/hcl-picker/#/hlc/6/1/21313E/EFEE69

LABELS and TEXTS: Use standard sans-serif fonts from the Swiss Graphic Design tradition for your texts and labels. Limit font sizes to a few. These include any of the following: Arial, Helvetica, Futura, Univers and related fonts.

CENTER VISUALIZATION: Your visualization should be at the center of your screen.

DUE DATE: 1st Draft due on January 24.

--------------------------------------------
Your REPLY POST should include the following:

Concept description
--
Sketch if useful
Screen Shots of your project with descriptions
--
MySQL query
Processing time
--
Analysis
--
csv file and code that created the image
George Legrady
legrady@mat.ucsb.edu

qiu0717
Posts: 9
Joined: Wed Jan 06, 2016 1:44 pm

Re: PROJ 1b: VISUALIZING the CULTURE ANALYSIS in 2D (PROCESS

Post by qiu0717 » Sun Jan 24, 2016 10:23 pm

----Edited----

I clean up my redundant fonts.
Code keeps the same.
updated_project1b_weihao.zip
Clean up the redundant fonts
(66.68 KiB) Downloaded 232 times

----Edited----


To make the curve illustrate more clearly, I added a label at the left area of the curve.
Additionally, I fixed the bug of the "following" interaction mode.
5.png
New Overview

The new Version of processing code is below:

Code: Select all

int[][] dataMatrix;
int[] dataMax;
int[] dataMin;
int[] dataSum;
Table[] CheckoutTimes;
Table jobApproval;
float cellHeight, cellWidth;
PFont[] Fonts;
boolean shouldShowCurve, mouseClick, shouldFollow;
color[] colors;
float[] verticalLines;
float[] horizonalLines;

int detailsI, detailsJ;
void setup() {
  fullScreen();
  //size(1000, 700);
  dataMatrix = new int[12*7][4];
  dataMax = new int[4];
  dataMin = new int[4];
  dataSum = new int[4];

  CheckoutTimes = new Table[3];
  CheckoutTimes[0] = loadTable("Couts of all books by month.csv");
  CheckoutTimes[1] = loadTable("Couts of all dvds by month.csv");
  CheckoutTimes[2] = loadTable("Couts of all cds by month.csv");

  jobApproval = loadTable("job_approval.csv");

  Fonts = new PFont[5];
  //Fonts[0] = loadFont("AppleGothic-12.vlw");
  Fonts[1] = loadFont("EurostileRegular-12.vlw");
  Fonts[2] = loadFont("EurostileRegular-48.vlw");

  colors = new color[3];
  colors[0] = #565B77;
  colors[1] = #6FDEFD;
  colors[2] = #43AD8A;

  horizonalLines = new float[4];
  horizonalLines[0] = 1.f/8*height;
  horizonalLines[1] = 3.f/8*height;
  horizonalLines[2] = 1.f/2*height;
  horizonalLines[3] = 7.f/8*height;

  verticalLines = new float[4];
  verticalLines[0] =  1.f/8*width;
  verticalLines[1] =  2.f/8*width;
  verticalLines[2] =  5.f/8*width;
  verticalLines[3] =  7.f/8*width;

  cellWidth = (verticalLines[3] - verticalLines[1])/(7*12);
  cellHeight = (horizonalLines[3]-horizonalLines[2])/3;

  shouldShowCurve = false;
  mouseClick = false;
  shouldFollow = true;

  for (int i = 0; i <7; i++ ) {
    for (int j = 0; j<12; j++) {
      String month= str(2000+i+8)+"-"+nf(j+1, 2, 0);
      //print(month);
      TableRow[] row = new TableRow[3];
      for (int k = 0; k<3; k++) {
        row[k] = CheckoutTimes[k].findRow(month, 0);
        if (row[k]!=null) {
          dataMatrix[i*12+j][k] = row[k].getInt(1);
        } else {
          dataMatrix[i*12+j][k] = 0;
        }
      }
      dataMatrix[i*12+j][3] = jobApproval.getInt(i*12+j, 0);
    }
  }

  for (int i = 0; i<4; i++) {
    dataMax[i] = 0;
    dataMin[i] = 1000;
    dataSum[i] = 0;
    for (int j = 0; j<12*7; j++) {
      if (dataMatrix[j][i]>dataMax[i]) dataMax[i] = dataMatrix[j][i];
      if (dataMatrix[j][i]<dataMin[i]) dataMin[i] = dataMatrix[j][i];
      dataSum[i] = dataSum[i] + dataMatrix[j][i];
    }
  }

  smooth();
  noStroke();
}

void draw() {
  background(255*7/8, 100);

  fill(255);
  rectMode(CORNERS);
  rect(width*0.04, height*0.04, width*0.96, height*0.96);

  noFill();

  //for (int i = 0; i< 4; i++) {
  //  line(verticalLines[i], 0, verticalLines[i], height);
  //  line(0, horizonalLines[i], width, horizonalLines[i]);
  //}
  if (shouldShowCurve) drawJobApprovalCurve();

  noStroke();
  boolean isMouseIn = false;
  for (int j = 0; j < 3; j++) {
    for (int i = 0; i < 7*12; i++) {
      if (drawCell(i, j)) {
        isMouseIn = true;
        doMouseInteraction(i, j);
        if (shouldFollow) {
          detailsI = i;
          detailsJ = j;
        } else if (mouseClick) {
          detailsI = i;
          detailsJ = j;
          mouseClick = false;
        }
      }
    }
  }
  if (!isMouseIn) {
    if (shouldFollow) {
      detailsI = -1;
      detailsJ = -1;
    } else {
      if (mouseClick) {
        detailsI = -1;
        detailsJ = -1;
        mouseClick = false;
      }
    }
  }

  doMouseInteractionForDetails(detailsI, detailsJ);

  drawLabel();
}

boolean drawCell(int verticalIndex, int horizonalIndex) {

  float percent = float(dataMatrix[verticalIndex][horizonalIndex])/dataMax[horizonalIndex];
  fill(lerpColor(colors[0], colors[1], percent), 150);

  float startY = horizonalLines[2]+horizonalIndex*cellHeight;
  float startX = verticalLines[1]+verticalIndex*cellWidth;
  rectMode(CORNER);
  rect(startX, startY, cellWidth, cellHeight*0.5, 0);

  boolean isMouseInX = (mouseX>startX) && (mouseX < startX+cellWidth);
  boolean isMouseInY = (mouseY>(startY))&& (mouseY < (startY+cellHeight*0.5));
  boolean isMouseIn = isMouseInX && isMouseInY;
  return isMouseIn;
}

void doMouseInteraction(int verticalIndex, int horizonalIndex) {
  float percent = float(dataMatrix[verticalIndex][horizonalIndex])/dataMax[horizonalIndex];
  float startY = horizonalLines[2]+horizonalIndex*cellHeight;
  float startX = verticalLines[1]+verticalIndex*cellWidth;

  fill(lerpColor(colors[0], colors[1], percent), 255);
  rect(startX, startY, cellWidth, cellHeight*0.5);

  if (verticalIndex>=12 && shouldShowCurve) {
    float jobApprovalPercent = map(dataMatrix[verticalIndex-12][3], dataMin[3], dataMax[3], 0, 1);
    color jobApprovaColor = lerpColor(colors[0], colors[1], jobApprovalPercent);
    fill(jobApprovaColor, 240);
    Parallelogram(verticalLines[1]+ (verticalIndex+0.5)*cellWidth-6, 
      map(dataMatrix[verticalIndex-12][3], dataMin[3], dataMax[3], horizonalLines[3], horizonalLines[1])-6, 12, 12, 0.2);
  }
}

void doMouseInteractionForDetails(int verticalIndex, int horizonalIndex) {

  if (verticalIndex>=0&&horizonalIndex>=0) {

    // Details Part
    //
    float percent = float(dataMatrix[verticalIndex][horizonalIndex])/dataMax[horizonalIndex];
    float detailTextX = 0.5*(verticalLines[2]+verticalLines[3])-3;
    float detailTextY1 = 0.5*(horizonalLines[0]+horizonalLines[1]);
    float detailTextY2 = 0.5*(horizonalLines[0]+horizonalLines[1]) + 20;
    float detailTextY3 = 0.5*(horizonalLines[0]+horizonalLines[1]) + 40;
    color detailBlockColor =  lerpColor(colors[0], colors[1], percent);
    String typeName = "";
    switch(horizonalIndex) {
    case 0 : 
      typeName = "Book";
      break;
    case 1 : 
      typeName = "DVD";
      break;
    case 2 : 
      typeName = "CD";
      break;
    }

    // Main Block
    //
    fill(detailBlockColor);
    Parallelogram( 0.5*(verticalLines[2]+verticalLines[3]), 0.5*(horizonalLines[0]+horizonalLines[1]), 
      0.5*(verticalLines[3]-verticalLines[2]), 0.5*(horizonalLines[1]-horizonalLines[0]), 0.2);

    // Text
    fill(0);
    textFont(Fonts[1], 12);
    textAlign(RIGHT, TOP);
    text(str(2008+verticalIndex/12)+"/"+nf(verticalIndex%12+1, 2), detailTextX, detailTextY1);
    text(typeName+" Checkouts: " + str(dataMatrix[verticalIndex][horizonalIndex]), detailTextX, detailTextY2);

    // Job Approval part
    //
    if (verticalIndex>=12 && shouldShowCurve) {
      text("Job Approval: " + str(dataMatrix[verticalIndex-12][3])+"%", detailTextX, detailTextY3);
      float jobApprovalPercent = map(dataMatrix[verticalIndex-12][3], dataMin[3], dataMax[3], 0, 1);
      color jobApprovaColor = lerpColor(colors[0], colors[1], jobApprovalPercent);
      fill(jobApprovaColor, 240);
      Parallelogram( 0.5*(verticalLines[2]+verticalLines[3]), 0.3*horizonalLines[0]+0.7*horizonalLines[1], 
        0.5*(verticalLines[3]-verticalLines[2]), 0.3*(horizonalLines[1]-horizonalLines[0]), 0.2/0.6);
    }
  }
}

void Parallelogram(float startX, float startY, float Width, float Height, float ratio) {
  beginShape();
  vertex(startX, startY);
  vertex(startX+Width, startY+Height*ratio);
  vertex(startX+Width, startY+Height);
  vertex(startX, startY+Height*(1-ratio));
  endShape();
}

void drawJobApprovalCurve() {
  strokeWeight(2);
  stroke(colors[0]);
  beginShape();
  curveVertex(verticalLines[1]+ (0+12+0.5)*cellWidth, map(dataMatrix[0][3], dataMin[3], dataMax[3], horizonalLines[3], horizonalLines[1]));
  for (int i = 0; i < 6*12; i++) {
    curveVertex(verticalLines[1]+ (i+12+0.5)*cellWidth, map(dataMatrix[i][3], dataMin[3], dataMax[3], horizonalLines[3], horizonalLines[1]));
  }
  curveVertex(verticalLines[1]+ (71+12+0.5)*cellWidth, map(dataMatrix[71][3], dataMin[3], dataMax[3], horizonalLines[3], horizonalLines[1]));
  endShape();
  line(verticalLines[0], horizonalLines[2]- 0.5*cellHeight, 0.5*(verticalLines[0]+verticalLines[1]), horizonalLines[2]- 0.5*cellHeight);
}

void drawLabel() {

  fill(0);

  // Horizonal lables
  //
  textAlign(LEFT, BOTTOM);
  textFont(Fonts[1], 12);
  text(str(2008)+"/"+nf(1, 2), verticalLines[1], horizonalLines[2]);
  textAlign(RIGHT, BOTTOM);
  text(str(2014)+"/"+str(12), verticalLines[3], horizonalLines[2]);


  // Vertical labels
  //
  textAlign(LEFT, TOP);
  textFont(Fonts[1], 12);
  text("Book", verticalLines[0], horizonalLines[2]+ 0*cellHeight);
  text("DVD", verticalLines[0], horizonalLines[2] + 1*cellHeight);
  text("CD", verticalLines[0], horizonalLines[2] + 2*cellHeight);
  if (shouldShowCurve) {
    text("Job Approval", verticalLines[0], horizonalLines[2]- cellHeight);
  }

  // Max an Min
  //
  int gradingNum = 7;
  float gradingLength = (verticalLines[1]-verticalLines[0])/2;
  float gradingSize = gradingLength/gradingNum;
  for (int i = 0; i < gradingNum; i++) {
    fill(lerpColor(colors[0], colors[1], i/6.f), 150);
    noStroke();
    rectMode(CORNER);
    rect(verticalLines[0]+gradingSize*i, horizonalLines[2]+0.5*cellHeight-gradingSize, gradingSize, gradingSize);
    rect(verticalLines[0]+gradingSize*i, horizonalLines[2]+1.5*cellHeight-gradingSize, gradingSize, gradingSize);
    rect(verticalLines[0]+gradingSize*i, horizonalLines[2]+2.5*cellHeight-gradingSize, gradingSize, gradingSize);
  }

  textFont(Fonts[1], 10);
  fill(128);
  for (int i = 0; i < 3; i++) {
    textAlign(LEFT, BOTTOM);
    text(str(dataMin[i]), verticalLines[0], horizonalLines[2]+ (i+0.5)*cellHeight - gradingSize);
    textAlign(RIGHT, BOTTOM);
    text(str(dataMax[i]), verticalLines[0]+gradingLength, horizonalLines[2]+ (i+0.5)*cellHeight - gradingSize);
  }
  if (shouldShowCurve) {
    textAlign(LEFT, BOTTOM);
    text(str(dataMin[3])+"%", verticalLines[0], horizonalLines[2] - 0.5*cellHeight -2);
    textAlign(RIGHT, BOTTOM);
    text(str(dataMax[3])+"%", verticalLines[0]+gradingLength, horizonalLines[2] - 0.5*cellHeight - 2);
  }

  //Title text
  //
  pushMatrix();
  //translate(0, -0.1*(horizonalLines[1]-horizonalLines[0]));
  //fill(255*7/8, 100);
  //Parallelogram(0.04*width,horizonalLines[0],verticalLines[0]-0.04*width, horizonalLines[1]/2-0.04*height,0.2);
  //translate(0, 0.1*(horizonalLines[1]-horizonalLines[0]));

  fill(128, 200);
  textFont(Fonts[2], 20);
  textAlign(LEFT, TOP);
  text(" Job Approval and \n Checkout Times of Related Items of", verticalLines[0], horizonalLines[0]);
  translate(0, 55);
  fill(0);
  textFont(Fonts[2], 42);
  textAlign(LEFT, TOP);
  text("BARACK OBAMA", verticalLines[0], horizonalLines[0]);
  popMatrix();
}

void keyPressed() {
  if (key == 'C' || key == 'c') {
    shouldShowCurve = !shouldShowCurve;
    print(shouldShowCurve);
  }
  if (key == 'F' || key == 'f') {
    shouldFollow = !shouldFollow;
    print(shouldFollow);
  }
}
void mouseClicked() {
  mouseClick = true;
}
Can be downloaded here:
updated_project1b_weihao.zip
Edited version
(657.66 KiB) Downloaded 228 times

----Old Version----
Checkout times for CDs, DVDs and Books related to Barack Obama


This visualization aims to illustrate the times of checkout for the CDs, DVDs and Books that are related to Barack Obama. I followed the last query to collect the data, but in a more detailed way, to collect the checkout times of each specific type separately, rather than to collect the sum of all types.

In the project, I utilized the data from 2008.01 to 2014.12. I designed a 2D matrix which have 3 rows, representing Books, CDs and DVDs respectively, and 84 (12*7=84) collumns, representing all months in 7 years. Each element is a thin rectangle, with the color of the rectangle representing how many times this item is lent during a specific month. The colors range from #565B77 to #6FDEFD.


To make the visualization more uniform, I applied different mapping for different types of items. However, they are actually scale-different. When the rectangles representing different types, like books and CDs, looks similar, they still differs greatly in actual value. To eliminate this confusion, I marked the scale at the bottom of their type name as a reference for evaluate the actual values of each rectangle.
1.png
Overview
To make the illustration more clear, I added several methods of interaction.
1. When Mouse is hovered on a specific rectangle, it color will become darker, which is implemented by the alpha value change.
2.png
Mouse interaction by mouse movement
2. The curve of job approval can be switched on or off. When it is on, there will be a small parallelogram appearing on the curve to mark the job approval of a specific time, which is the same time of the rectangle hovered by Mouse.
3.png
With the appearance of job approval curve
3. For the detailed information, which is shown on the right top area of the screen, there are several modes of display. The "following" and "not following" modes differ in the update time of details. "Following" mode enables the detailed information to be updates at the same time of mouse movement. However, the "Not following" mode requires a mouse click on some rectangle for detail information updating.
3.png
With the appearance of job approval curve
4.png
Mouse interaction by mouse click
On the other hand, when the job approval curve is off, there will only show the detailed information of checkout times. However, when it is on, the job approval percentage will be included in the detailed information, too. Additionally, the color block will be cut into two parts, representing the checkout times and job approval respectively, to give a more intuitive contrast.

The interaction key:
"c" or "C" - opening or close the display of job approval curve;
"f" or "F" - to change the "following" or "not following" mode.


As to the design, the colors of blue, red and beige are specially selected to represent the U.S national flag, which echoes Barack Obama, the U.S. president. Besides, the font of title looks classic, rather than as modern as Helvetica or Avenir , but not as obsolete and serious as fonts like Times New Romans, which I think is very suitable for this formal and contemporary subject.


The sql code for all bibNumbers query is here:

Code: Select all

SELECT DISTINCT
    subject.bibNumber, title.title
FROM
    spl3.subject,
    spl3.title
WHERE
    subject.bibNumber = title.bibNumber
        AND (spl3.subject.subject LIKE '%Obama%'
        OR spl3.title.title LIKE '%Obama%')

The sql code for Book is here:

Code: Select all

SELECT 
    DATE_FORMAT(checkOut, '%Y-%m') AS checkOutMonth,
    COUNT(checkout) AS CheckoutCount,
    SUBSTRING(itemType, 3, 4) AS type
FROM
    spl3._rawXmlDataCheckIns
WHERE
    (bibNumber = 1594342
        OR bibNumber = 2254490
        OR bibNumber = 2334542
        OR bibNumber = 2351236
        OR bibNumber = 2368614
        OR bibNumber = 2385227
        OR bibNumber = 2400404
        OR bibNumber = 2400405
        OR bibNumber = 2431852
        OR bibNumber = 2436195
        OR bibNumber = 2440936
        OR bibNumber = 2452138
        OR bibNumber = 2459581
        OR bibNumber = 2462269
        OR bibNumber = 2472743
        OR bibNumber = 2483975
        OR bibNumber = 2496250
        OR bibNumber = 2499179
        OR bibNumber = 2503241
        OR bibNumber = 2505901
        OR bibNumber = 2510243
        OR bibNumber = 2510261
        OR bibNumber = 2511098
        OR bibNumber = 2511099
        OR bibNumber = 2512209
        OR bibNumber = 2513892
        OR bibNumber = 2514170
        OR bibNumber = 2517677
        OR bibNumber = 2519406
        OR bibNumber = 2521075
        OR bibNumber = 2521277
        OR bibNumber = 2521290
        OR bibNumber = 2523199
        OR bibNumber = 2524606
        OR bibNumber = 2524607
        OR bibNumber = 2524608
        OR bibNumber = 2528650
        OR bibNumber = 2529452
        OR bibNumber = 2530439
        OR bibNumber = 2530479
        OR bibNumber = 2531825
        OR bibNumber = 2531902
        OR bibNumber = 2533448
        OR bibNumber = 2535393
        OR bibNumber = 2535396
        OR bibNumber = 2535948
        OR bibNumber = 2539304
        OR bibNumber = 2539884
        OR bibNumber = 2540464
        OR bibNumber = 2540505
        OR bibNumber = 2543400
        OR bibNumber = 2549302
        OR bibNumber = 2549309
        OR bibNumber = 2549322
        OR bibNumber = 2549743
        OR bibNumber = 2550060
        OR bibNumber = 2553984
        OR bibNumber = 2556519
        OR bibNumber = 2556551
        OR bibNumber = 2556571
        OR bibNumber = 2556572
        OR bibNumber = 2556908
        OR bibNumber = 2556910
        OR bibNumber = 2558574
        OR bibNumber = 2558575
        OR bibNumber = 2558576
        OR bibNumber = 2559385
        OR bibNumber = 2559663
        OR bibNumber = 2560954
        OR bibNumber = 2561294
        OR bibNumber = 2561384
        OR bibNumber = 2561733
        OR bibNumber = 2562316
        OR bibNumber = 2562671
        OR bibNumber = 2562911
        OR bibNumber = 2562988
        OR bibNumber = 2565436
        OR bibNumber = 2566510
        OR bibNumber = 2566553
        OR bibNumber = 2566612
        OR bibNumber = 2566634
        OR bibNumber = 2566701
        OR bibNumber = 2566943
        OR bibNumber = 2569054
        OR bibNumber = 2571459
        OR bibNumber = 2573009
        OR bibNumber = 2574230
        OR bibNumber = 2574289
        OR bibNumber = 2575184
        OR bibNumber = 2575208
        OR bibNumber = 2575286
        OR bibNumber = 2577340
        OR bibNumber = 2577347
        OR bibNumber = 2579568
        OR bibNumber = 2580718
        OR bibNumber = 2583384
        OR bibNumber = 2585069
        OR bibNumber = 2586395
        OR bibNumber = 2588624
        OR bibNumber = 2590574
        OR bibNumber = 2595651
        OR bibNumber = 2599379
        OR bibNumber = 2599426
        OR bibNumber = 2599480
        OR bibNumber = 2600512
        OR bibNumber = 2601890
        OR bibNumber = 2603028
        OR bibNumber = 2603044
        OR bibNumber = 2603791
        OR bibNumber = 2603800
        OR bibNumber = 2607795
        OR bibNumber = 2608218
        OR bibNumber = 2612337
        OR bibNumber = 2613822
        OR bibNumber = 2614667
        OR bibNumber = 2614669
        OR bibNumber = 2614673
        OR bibNumber = 2615440
        OR bibNumber = 2615471
        OR bibNumber = 2616710
        OR bibNumber = 2616773
        OR bibNumber = 2618806
        OR bibNumber = 2618808
        OR bibNumber = 2618983
        OR bibNumber = 2618990
        OR bibNumber = 2618994
        OR bibNumber = 2620858
        OR bibNumber = 2622464
        OR bibNumber = 2622465
        OR bibNumber = 2622508
        OR bibNumber = 2622665
        OR bibNumber = 2623097
        OR bibNumber = 2624647
        OR bibNumber = 2625627
        OR bibNumber = 2626046
        OR bibNumber = 2626477
        OR bibNumber = 2626652
        OR bibNumber = 2626915
        OR bibNumber = 2627322
        OR bibNumber = 2629289
        OR bibNumber = 2631266
        OR bibNumber = 2631321
        OR bibNumber = 2632635
        OR bibNumber = 2632658
        OR bibNumber = 2633956
        OR bibNumber = 2634499
        OR bibNumber = 2634932
        OR bibNumber = 2635980
        OR bibNumber = 2636226
        OR bibNumber = 2636259
        OR bibNumber = 2636283
        OR bibNumber = 2638105
        OR bibNumber = 2638899
        OR bibNumber = 2639354
        OR bibNumber = 2640297
        OR bibNumber = 2642611
        OR bibNumber = 2644392
        OR bibNumber = 2645566
        OR bibNumber = 2645602
        OR bibNumber = 2645798
        OR bibNumber = 2645814
        OR bibNumber = 2648428
        OR bibNumber = 2648433
        OR bibNumber = 2648452
        OR bibNumber = 2649553
        OR bibNumber = 2649718
        OR bibNumber = 2650784
        OR bibNumber = 2652718
        OR bibNumber = 2652985
        OR bibNumber = 2653622
        OR bibNumber = 2653798
        OR bibNumber = 2654311
        OR bibNumber = 2654355
        OR bibNumber = 2655297
        OR bibNumber = 2656425
        OR bibNumber = 2656883
        OR bibNumber = 2657409
        OR bibNumber = 2658156
        OR bibNumber = 2658161
        OR bibNumber = 2658181
        OR bibNumber = 2659280
        OR bibNumber = 2663542
        OR bibNumber = 2663557
        OR bibNumber = 2663749
        OR bibNumber = 2663962
        OR bibNumber = 2664535
        OR bibNumber = 2665135
        OR bibNumber = 2666698
        OR bibNumber = 2666714
        OR bibNumber = 2667985
        OR bibNumber = 2668090
        OR bibNumber = 2668113
        OR bibNumber = 2668123
        OR bibNumber = 2668139
        OR bibNumber = 2668755
        OR bibNumber = 2669615
        OR bibNumber = 2669978
        OR bibNumber = 2670266
        OR bibNumber = 2671106
        OR bibNumber = 2672846
        OR bibNumber = 2673740
        OR bibNumber = 2675311
        OR bibNumber = 2675327
        OR bibNumber = 2678898
        OR bibNumber = 2679103
        OR bibNumber = 2680974
        OR bibNumber = 2681390
        OR bibNumber = 2681927
        OR bibNumber = 2681979
        OR bibNumber = 2682586
        OR bibNumber = 2682596
        OR bibNumber = 2682791
        OR bibNumber = 2683103
        OR bibNumber = 2683622
        OR bibNumber = 2685693
        OR bibNumber = 2686042
        OR bibNumber = 2686232
        OR bibNumber = 2686233
        OR bibNumber = 2686561
        OR bibNumber = 2686574
        OR bibNumber = 2686595
        OR bibNumber = 2687223
        OR bibNumber = 2689521
        OR bibNumber = 2689813
        OR bibNumber = 2697227
        OR bibNumber = 2699308
        OR bibNumber = 2699472
        OR bibNumber = 2699910
        OR bibNumber = 2701213
        OR bibNumber = 2701831
        OR bibNumber = 2701903
        OR bibNumber = 2702729
        OR bibNumber = 2705420
        OR bibNumber = 2707824
        OR bibNumber = 2708539
        OR bibNumber = 2708581
        OR bibNumber = 2713105
        OR bibNumber = 2714923
        OR bibNumber = 2714956
        OR bibNumber = 2715124
        OR bibNumber = 2715262
        OR bibNumber = 2716334
        OR bibNumber = 2716337
        OR bibNumber = 2716794
        OR bibNumber = 2718088
        OR bibNumber = 2719385
        OR bibNumber = 2728693
        OR bibNumber = 2729581
        OR bibNumber = 2730380
        OR bibNumber = 2730895
        OR bibNumber = 2731084
        OR bibNumber = 2732372
        OR bibNumber = 2733588
        OR bibNumber = 2734461
        OR bibNumber = 2737921
        OR bibNumber = 2738980
        OR bibNumber = 2739984
        OR bibNumber = 2740021
        OR bibNumber = 2743502
        OR bibNumber = 2743589
        OR bibNumber = 2744458
        OR bibNumber = 2744629
        OR bibNumber = 2744630
        OR bibNumber = 2746833
        OR bibNumber = 2747267
        OR bibNumber = 2748155
        OR bibNumber = 2748527
        OR bibNumber = 2750672
        OR bibNumber = 2751807
        OR bibNumber = 2755536
        OR bibNumber = 2756282
        OR bibNumber = 2756308
        OR bibNumber = 2762382
        OR bibNumber = 2766258
        OR bibNumber = 2767297
        OR bibNumber = 2771604
        OR bibNumber = 2792709
        OR bibNumber = 2792824
        OR bibNumber = 2794603
        OR bibNumber = 2794626
        OR bibNumber = 2794637
        OR bibNumber = 2795061
        OR bibNumber = 2795232
        OR bibNumber = 2795559
        OR bibNumber = 2796319
        OR bibNumber = 2800237
        OR bibNumber = 2800806
        OR bibNumber = 2800873
        OR bibNumber = 2801237
        OR bibNumber = 2801616
        OR bibNumber = 2801859
        OR bibNumber = 2802329
        OR bibNumber = 2802453
        OR bibNumber = 2802635
        OR bibNumber = 2806269
        OR bibNumber = 2806664
        OR bibNumber = 2807917
        OR bibNumber = 2808983
        OR bibNumber = 2809172
        OR bibNumber = 2811405
        OR bibNumber = 2811585
        OR bibNumber = 2815178
        OR bibNumber = 2815215
        OR bibNumber = 2815218
        OR bibNumber = 2815249
        OR bibNumber = 2816343
        OR bibNumber = 2816368
        OR bibNumber = 2817343
        OR bibNumber = 2830487
        OR bibNumber = 2832924
        OR bibNumber = 2834040
        OR bibNumber = 2834331
        OR bibNumber = 2834486
        OR bibNumber = 2838392
        OR bibNumber = 2838891
        OR bibNumber = 2839344
        OR bibNumber = 2840485
        OR bibNumber = 2840491
        OR bibNumber = 2841718
        OR bibNumber = 2841786
        OR bibNumber = 2844523
        OR bibNumber = 2846192
        OR bibNumber = 2846233
        OR bibNumber = 2854425
        OR bibNumber = 2856416
        OR bibNumber = 2858802
        OR bibNumber = 2858813
        OR bibNumber = 2860050
        OR bibNumber = 2860711
        OR bibNumber = 2862264
        OR bibNumber = 2867019
        OR bibNumber = 2867026
        OR bibNumber = 2871038
        OR bibNumber = 2874300
        OR bibNumber = 2874394
        OR bibNumber = 2874680
        OR bibNumber = 2875283
        OR bibNumber = 2877275
        OR bibNumber = 2882295
        OR bibNumber = 2882296
        OR bibNumber = 2882298
        OR bibNumber = 2882299
        OR bibNumber = 2883971
        OR bibNumber = 2899950
        OR bibNumber = 2903400
        OR bibNumber = 2909094
        OR bibNumber = 2915942
        OR bibNumber = 2923188
        OR bibNumber = 2927237
        OR bibNumber = 2927578
        OR bibNumber = 2930684
        OR bibNumber = 2932038
        OR bibNumber = 2932064
        OR bibNumber = 2935488
        OR bibNumber = 2939991
        OR bibNumber = 2940997
        OR bibNumber = 2941339
        OR bibNumber = 2945367
        OR bibNumber = 2945450
        OR bibNumber = 2946917
        OR bibNumber = 2957387
        OR bibNumber = 2960639
        OR bibNumber = 2960730
        OR bibNumber = 2969676
        OR bibNumber = 2969737
        OR bibNumber = 2991354
        OR bibNumber = 3004523
        OR bibNumber = 3011053
        OR bibNumber = 3011223
        OR bibNumber = 3013461
        OR bibNumber = 3014930
        OR bibNumber = 3018325
        OR bibNumber = 3023533
        OR bibNumber = 3032340
        OR bibNumber = 3035306
        OR bibNumber = 3036128
        OR bibNumber = 3044155
        OR bibNumber = 3046065
        OR bibNumber = 3051159
        OR bibNumber = 3052227)
        AND (SUBSTRING(itemType, 3, 4) = 'bk')
GROUP BY checkOutMonth
The sql code for DVD is here:

Code: Select all

SELECT 
    DATE_FORMAT(checkOut, '%Y-%m') AS checkOutMonth,
    COUNT(checkout) AS CheckoutCount,
    SUBSTRING(itemType, 3, 4) AS type
FROM
    spl3._rawXmlDataCheckIns
WHERE
    (bibNumber = 1594342
        OR bibNumber = 2254490
        OR bibNumber = 2334542
        OR bibNumber = 2351236
        OR bibNumber = 2368614
        OR bibNumber = 2385227
        OR bibNumber = 2400404
        OR bibNumber = 2400405
        OR bibNumber = 2431852
        OR bibNumber = 2436195
        OR bibNumber = 2440936
        OR bibNumber = 2452138
        OR bibNumber = 2459581
        OR bibNumber = 2462269
        OR bibNumber = 2472743
        OR bibNumber = 2483975
        OR bibNumber = 2496250
        OR bibNumber = 2499179
        OR bibNumber = 2503241
        OR bibNumber = 2505901
        OR bibNumber = 2510243
        OR bibNumber = 2510261
        OR bibNumber = 2511098
        OR bibNumber = 2511099
        OR bibNumber = 2512209
        OR bibNumber = 2513892
        OR bibNumber = 2514170
        OR bibNumber = 2517677
        OR bibNumber = 2519406
        OR bibNumber = 2521075
        OR bibNumber = 2521277
        OR bibNumber = 2521290
        OR bibNumber = 2523199
        OR bibNumber = 2524606
        OR bibNumber = 2524607
        OR bibNumber = 2524608
        OR bibNumber = 2528650
        OR bibNumber = 2529452
        OR bibNumber = 2530439
        OR bibNumber = 2530479
        OR bibNumber = 2531825
        OR bibNumber = 2531902
        OR bibNumber = 2533448
        OR bibNumber = 2535393
        OR bibNumber = 2535396
        OR bibNumber = 2535948
        OR bibNumber = 2539304
        OR bibNumber = 2539884
        OR bibNumber = 2540464
        OR bibNumber = 2540505
        OR bibNumber = 2543400
        OR bibNumber = 2549302
        OR bibNumber = 2549309
        OR bibNumber = 2549322
        OR bibNumber = 2549743
        OR bibNumber = 2550060
        OR bibNumber = 2553984
        OR bibNumber = 2556519
        OR bibNumber = 2556551
        OR bibNumber = 2556571
        OR bibNumber = 2556572
        OR bibNumber = 2556908
        OR bibNumber = 2556910
        OR bibNumber = 2558574
        OR bibNumber = 2558575
        OR bibNumber = 2558576
        OR bibNumber = 2559385
        OR bibNumber = 2559663
        OR bibNumber = 2560954
        OR bibNumber = 2561294
        OR bibNumber = 2561384
        OR bibNumber = 2561733
        OR bibNumber = 2562316
        OR bibNumber = 2562671
        OR bibNumber = 2562911
        OR bibNumber = 2562988
        OR bibNumber = 2565436
        OR bibNumber = 2566510
        OR bibNumber = 2566553
        OR bibNumber = 2566612
        OR bibNumber = 2566634
        OR bibNumber = 2566701
        OR bibNumber = 2566943
        OR bibNumber = 2569054
        OR bibNumber = 2571459
        OR bibNumber = 2573009
        OR bibNumber = 2574230
        OR bibNumber = 2574289
        OR bibNumber = 2575184
        OR bibNumber = 2575208
        OR bibNumber = 2575286
        OR bibNumber = 2577340
        OR bibNumber = 2577347
        OR bibNumber = 2579568
        OR bibNumber = 2580718
        OR bibNumber = 2583384
        OR bibNumber = 2585069
        OR bibNumber = 2586395
        OR bibNumber = 2588624
        OR bibNumber = 2590574
        OR bibNumber = 2595651
        OR bibNumber = 2599379
        OR bibNumber = 2599426
        OR bibNumber = 2599480
        OR bibNumber = 2600512
        OR bibNumber = 2601890
        OR bibNumber = 2603028
        OR bibNumber = 2603044
        OR bibNumber = 2603791
        OR bibNumber = 2603800
        OR bibNumber = 2607795
        OR bibNumber = 2608218
        OR bibNumber = 2612337
        OR bibNumber = 2613822
        OR bibNumber = 2614667
        OR bibNumber = 2614669
        OR bibNumber = 2614673
        OR bibNumber = 2615440
        OR bibNumber = 2615471
        OR bibNumber = 2616710
        OR bibNumber = 2616773
        OR bibNumber = 2618806
        OR bibNumber = 2618808
        OR bibNumber = 2618983
        OR bibNumber = 2618990
        OR bibNumber = 2618994
        OR bibNumber = 2620858
        OR bibNumber = 2622464
        OR bibNumber = 2622465
        OR bibNumber = 2622508
        OR bibNumber = 2622665
        OR bibNumber = 2623097
        OR bibNumber = 2624647
        OR bibNumber = 2625627
        OR bibNumber = 2626046
        OR bibNumber = 2626477
        OR bibNumber = 2626652
        OR bibNumber = 2626915
        OR bibNumber = 2627322
        OR bibNumber = 2629289
        OR bibNumber = 2631266
        OR bibNumber = 2631321
        OR bibNumber = 2632635
        OR bibNumber = 2632658
        OR bibNumber = 2633956
        OR bibNumber = 2634499
        OR bibNumber = 2634932
        OR bibNumber = 2635980
        OR bibNumber = 2636226
        OR bibNumber = 2636259
        OR bibNumber = 2636283
        OR bibNumber = 2638105
        OR bibNumber = 2638899
        OR bibNumber = 2639354
        OR bibNumber = 2640297
        OR bibNumber = 2642611
        OR bibNumber = 2644392
        OR bibNumber = 2645566
        OR bibNumber = 2645602
        OR bibNumber = 2645798
        OR bibNumber = 2645814
        OR bibNumber = 2648428
        OR bibNumber = 2648433
        OR bibNumber = 2648452
        OR bibNumber = 2649553
        OR bibNumber = 2649718
        OR bibNumber = 2650784
        OR bibNumber = 2652718
        OR bibNumber = 2652985
        OR bibNumber = 2653622
        OR bibNumber = 2653798
        OR bibNumber = 2654311
        OR bibNumber = 2654355
        OR bibNumber = 2655297
        OR bibNumber = 2656425
        OR bibNumber = 2656883
        OR bibNumber = 2657409
        OR bibNumber = 2658156
        OR bibNumber = 2658161
        OR bibNumber = 2658181
        OR bibNumber = 2659280
        OR bibNumber = 2663542
        OR bibNumber = 2663557
        OR bibNumber = 2663749
        OR bibNumber = 2663962
        OR bibNumber = 2664535
        OR bibNumber = 2665135
        OR bibNumber = 2666698
        OR bibNumber = 2666714
        OR bibNumber = 2667985
        OR bibNumber = 2668090
        OR bibNumber = 2668113
        OR bibNumber = 2668123
        OR bibNumber = 2668139
        OR bibNumber = 2668755
        OR bibNumber = 2669615
        OR bibNumber = 2669978
        OR bibNumber = 2670266
        OR bibNumber = 2671106
        OR bibNumber = 2672846
        OR bibNumber = 2673740
        OR bibNumber = 2675311
        OR bibNumber = 2675327
        OR bibNumber = 2678898
        OR bibNumber = 2679103
        OR bibNumber = 2680974
        OR bibNumber = 2681390
        OR bibNumber = 2681927
        OR bibNumber = 2681979
        OR bibNumber = 2682586
        OR bibNumber = 2682596
        OR bibNumber = 2682791
        OR bibNumber = 2683103
        OR bibNumber = 2683622
        OR bibNumber = 2685693
        OR bibNumber = 2686042
        OR bibNumber = 2686232
        OR bibNumber = 2686233
        OR bibNumber = 2686561
        OR bibNumber = 2686574
        OR bibNumber = 2686595
        OR bibNumber = 2687223
        OR bibNumber = 2689521
        OR bibNumber = 2689813
        OR bibNumber = 2697227
        OR bibNumber = 2699308
        OR bibNumber = 2699472
        OR bibNumber = 2699910
        OR bibNumber = 2701213
        OR bibNumber = 2701831
        OR bibNumber = 2701903
        OR bibNumber = 2702729
        OR bibNumber = 2705420
        OR bibNumber = 2707824
        OR bibNumber = 2708539
        OR bibNumber = 2708581
        OR bibNumber = 2713105
        OR bibNumber = 2714923
        OR bibNumber = 2714956
        OR bibNumber = 2715124
        OR bibNumber = 2715262
        OR bibNumber = 2716334
        OR bibNumber = 2716337
        OR bibNumber = 2716794
        OR bibNumber = 2718088
        OR bibNumber = 2719385
        OR bibNumber = 2728693
        OR bibNumber = 2729581
        OR bibNumber = 2730380
        OR bibNumber = 2730895
        OR bibNumber = 2731084
        OR bibNumber = 2732372
        OR bibNumber = 2733588
        OR bibNumber = 2734461
        OR bibNumber = 2737921
        OR bibNumber = 2738980
        OR bibNumber = 2739984
        OR bibNumber = 2740021
        OR bibNumber = 2743502
        OR bibNumber = 2743589
        OR bibNumber = 2744458
        OR bibNumber = 2744629
        OR bibNumber = 2744630
        OR bibNumber = 2746833
        OR bibNumber = 2747267
        OR bibNumber = 2748155
        OR bibNumber = 2748527
        OR bibNumber = 2750672
        OR bibNumber = 2751807
        OR bibNumber = 2755536
        OR bibNumber = 2756282
        OR bibNumber = 2756308
        OR bibNumber = 2762382
        OR bibNumber = 2766258
        OR bibNumber = 2767297
        OR bibNumber = 2771604
        OR bibNumber = 2792709
        OR bibNumber = 2792824
        OR bibNumber = 2794603
        OR bibNumber = 2794626
        OR bibNumber = 2794637
        OR bibNumber = 2795061
        OR bibNumber = 2795232
        OR bibNumber = 2795559
        OR bibNumber = 2796319
        OR bibNumber = 2800237
        OR bibNumber = 2800806
        OR bibNumber = 2800873
        OR bibNumber = 2801237
        OR bibNumber = 2801616
        OR bibNumber = 2801859
        OR bibNumber = 2802329
        OR bibNumber = 2802453
        OR bibNumber = 2802635
        OR bibNumber = 2806269
        OR bibNumber = 2806664
        OR bibNumber = 2807917
        OR bibNumber = 2808983
        OR bibNumber = 2809172
        OR bibNumber = 2811405
        OR bibNumber = 2811585
        OR bibNumber = 2815178
        OR bibNumber = 2815215
        OR bibNumber = 2815218
        OR bibNumber = 2815249
        OR bibNumber = 2816343
        OR bibNumber = 2816368
        OR bibNumber = 2817343
        OR bibNumber = 2830487
        OR bibNumber = 2832924
        OR bibNumber = 2834040
        OR bibNumber = 2834331
        OR bibNumber = 2834486
        OR bibNumber = 2838392
        OR bibNumber = 2838891
        OR bibNumber = 2839344
        OR bibNumber = 2840485
        OR bibNumber = 2840491
        OR bibNumber = 2841718
        OR bibNumber = 2841786
        OR bibNumber = 2844523
        OR bibNumber = 2846192
        OR bibNumber = 2846233
        OR bibNumber = 2854425
        OR bibNumber = 2856416
        OR bibNumber = 2858802
        OR bibNumber = 2858813
        OR bibNumber = 2860050
        OR bibNumber = 2860711
        OR bibNumber = 2862264
        OR bibNumber = 2867019
        OR bibNumber = 2867026
        OR bibNumber = 2871038
        OR bibNumber = 2874300
        OR bibNumber = 2874394
        OR bibNumber = 2874680
        OR bibNumber = 2875283
        OR bibNumber = 2877275
        OR bibNumber = 2882295
        OR bibNumber = 2882296
        OR bibNumber = 2882298
        OR bibNumber = 2882299
        OR bibNumber = 2883971
        OR bibNumber = 2899950
        OR bibNumber = 2903400
        OR bibNumber = 2909094
        OR bibNumber = 2915942
        OR bibNumber = 2923188
        OR bibNumber = 2927237
        OR bibNumber = 2927578
        OR bibNumber = 2930684
        OR bibNumber = 2932038
        OR bibNumber = 2932064
        OR bibNumber = 2935488
        OR bibNumber = 2939991
        OR bibNumber = 2940997
        OR bibNumber = 2941339
        OR bibNumber = 2945367
        OR bibNumber = 2945450
        OR bibNumber = 2946917
        OR bibNumber = 2957387
        OR bibNumber = 2960639
        OR bibNumber = 2960730
        OR bibNumber = 2969676
        OR bibNumber = 2969737
        OR bibNumber = 2991354
        OR bibNumber = 3004523
        OR bibNumber = 3011053
        OR bibNumber = 3011223
        OR bibNumber = 3013461
        OR bibNumber = 3014930
        OR bibNumber = 3018325
        OR bibNumber = 3023533
        OR bibNumber = 3032340
        OR bibNumber = 3035306
        OR bibNumber = 3036128
        OR bibNumber = 3044155
        OR bibNumber = 3046065
        OR bibNumber = 3051159
        OR bibNumber = 3052227)
        AND (SUBSTRING(itemType, 3, 4) = 'dvd')
GROUP BY checkOutMonth
The sql code for CD is here:

Code: Select all

SELECT 
    DATE_FORMAT(checkOut, '%Y-%m') AS checkOutMonth,
    COUNT(checkout) AS CheckoutCount,
    SUBSTRING(itemType, 3, 4) AS type
FROM
    spl3._rawXmlDataCheckIns
WHERE
    (bibNumber = 1594342
        OR bibNumber = 2254490
        OR bibNumber = 2334542
        OR bibNumber = 2351236
        OR bibNumber = 2368614
        OR bibNumber = 2385227
        OR bibNumber = 2400404
        OR bibNumber = 2400405
        OR bibNumber = 2431852
        OR bibNumber = 2436195
        OR bibNumber = 2440936
        OR bibNumber = 2452138
        OR bibNumber = 2459581
        OR bibNumber = 2462269
        OR bibNumber = 2472743
        OR bibNumber = 2483975
        OR bibNumber = 2496250
        OR bibNumber = 2499179
        OR bibNumber = 2503241
        OR bibNumber = 2505901
        OR bibNumber = 2510243
        OR bibNumber = 2510261
        OR bibNumber = 2511098
        OR bibNumber = 2511099
        OR bibNumber = 2512209
        OR bibNumber = 2513892
        OR bibNumber = 2514170
        OR bibNumber = 2517677
        OR bibNumber = 2519406
        OR bibNumber = 2521075
        OR bibNumber = 2521277
        OR bibNumber = 2521290
        OR bibNumber = 2523199
        OR bibNumber = 2524606
        OR bibNumber = 2524607
        OR bibNumber = 2524608
        OR bibNumber = 2528650
        OR bibNumber = 2529452
        OR bibNumber = 2530439
        OR bibNumber = 2530479
        OR bibNumber = 2531825
        OR bibNumber = 2531902
        OR bibNumber = 2533448
        OR bibNumber = 2535393
        OR bibNumber = 2535396
        OR bibNumber = 2535948
        OR bibNumber = 2539304
        OR bibNumber = 2539884
        OR bibNumber = 2540464
        OR bibNumber = 2540505
        OR bibNumber = 2543400
        OR bibNumber = 2549302
        OR bibNumber = 2549309
        OR bibNumber = 2549322
        OR bibNumber = 2549743
        OR bibNumber = 2550060
        OR bibNumber = 2553984
        OR bibNumber = 2556519
        OR bibNumber = 2556551
        OR bibNumber = 2556571
        OR bibNumber = 2556572
        OR bibNumber = 2556908
        OR bibNumber = 2556910
        OR bibNumber = 2558574
        OR bibNumber = 2558575
        OR bibNumber = 2558576
        OR bibNumber = 2559385
        OR bibNumber = 2559663
        OR bibNumber = 2560954
        OR bibNumber = 2561294
        OR bibNumber = 2561384
        OR bibNumber = 2561733
        OR bibNumber = 2562316
        OR bibNumber = 2562671
        OR bibNumber = 2562911
        OR bibNumber = 2562988
        OR bibNumber = 2565436
        OR bibNumber = 2566510
        OR bibNumber = 2566553
        OR bibNumber = 2566612
        OR bibNumber = 2566634
        OR bibNumber = 2566701
        OR bibNumber = 2566943
        OR bibNumber = 2569054
        OR bibNumber = 2571459
        OR bibNumber = 2573009
        OR bibNumber = 2574230
        OR bibNumber = 2574289
        OR bibNumber = 2575184
        OR bibNumber = 2575208
        OR bibNumber = 2575286
        OR bibNumber = 2577340
        OR bibNumber = 2577347
        OR bibNumber = 2579568
        OR bibNumber = 2580718
        OR bibNumber = 2583384
        OR bibNumber = 2585069
        OR bibNumber = 2586395
        OR bibNumber = 2588624
        OR bibNumber = 2590574
        OR bibNumber = 2595651
        OR bibNumber = 2599379
        OR bibNumber = 2599426
        OR bibNumber = 2599480
        OR bibNumber = 2600512
        OR bibNumber = 2601890
        OR bibNumber = 2603028
        OR bibNumber = 2603044
        OR bibNumber = 2603791
        OR bibNumber = 2603800
        OR bibNumber = 2607795
        OR bibNumber = 2608218
        OR bibNumber = 2612337
        OR bibNumber = 2613822
        OR bibNumber = 2614667
        OR bibNumber = 2614669
        OR bibNumber = 2614673
        OR bibNumber = 2615440
        OR bibNumber = 2615471
        OR bibNumber = 2616710
        OR bibNumber = 2616773
        OR bibNumber = 2618806
        OR bibNumber = 2618808
        OR bibNumber = 2618983
        OR bibNumber = 2618990
        OR bibNumber = 2618994
        OR bibNumber = 2620858
        OR bibNumber = 2622464
        OR bibNumber = 2622465
        OR bibNumber = 2622508
        OR bibNumber = 2622665
        OR bibNumber = 2623097
        OR bibNumber = 2624647
        OR bibNumber = 2625627
        OR bibNumber = 2626046
        OR bibNumber = 2626477
        OR bibNumber = 2626652
        OR bibNumber = 2626915
        OR bibNumber = 2627322
        OR bibNumber = 2629289
        OR bibNumber = 2631266
        OR bibNumber = 2631321
        OR bibNumber = 2632635
        OR bibNumber = 2632658
        OR bibNumber = 2633956
        OR bibNumber = 2634499
        OR bibNumber = 2634932
        OR bibNumber = 2635980
        OR bibNumber = 2636226
        OR bibNumber = 2636259
        OR bibNumber = 2636283
        OR bibNumber = 2638105
        OR bibNumber = 2638899
        OR bibNumber = 2639354
        OR bibNumber = 2640297
        OR bibNumber = 2642611
        OR bibNumber = 2644392
        OR bibNumber = 2645566
        OR bibNumber = 2645602
        OR bibNumber = 2645798
        OR bibNumber = 2645814
        OR bibNumber = 2648428
        OR bibNumber = 2648433
        OR bibNumber = 2648452
        OR bibNumber = 2649553
        OR bibNumber = 2649718
        OR bibNumber = 2650784
        OR bibNumber = 2652718
        OR bibNumber = 2652985
        OR bibNumber = 2653622
        OR bibNumber = 2653798
        OR bibNumber = 2654311
        OR bibNumber = 2654355
        OR bibNumber = 2655297
        OR bibNumber = 2656425
        OR bibNumber = 2656883
        OR bibNumber = 2657409
        OR bibNumber = 2658156
        OR bibNumber = 2658161
        OR bibNumber = 2658181
        OR bibNumber = 2659280
        OR bibNumber = 2663542
        OR bibNumber = 2663557
        OR bibNumber = 2663749
        OR bibNumber = 2663962
        OR bibNumber = 2664535
        OR bibNumber = 2665135
        OR bibNumber = 2666698
        OR bibNumber = 2666714
        OR bibNumber = 2667985
        OR bibNumber = 2668090
        OR bibNumber = 2668113
        OR bibNumber = 2668123
        OR bibNumber = 2668139
        OR bibNumber = 2668755
        OR bibNumber = 2669615
        OR bibNumber = 2669978
        OR bibNumber = 2670266
        OR bibNumber = 2671106
        OR bibNumber = 2672846
        OR bibNumber = 2673740
        OR bibNumber = 2675311
        OR bibNumber = 2675327
        OR bibNumber = 2678898
        OR bibNumber = 2679103
        OR bibNumber = 2680974
        OR bibNumber = 2681390
        OR bibNumber = 2681927
        OR bibNumber = 2681979
        OR bibNumber = 2682586
        OR bibNumber = 2682596
        OR bibNumber = 2682791
        OR bibNumber = 2683103
        OR bibNumber = 2683622
        OR bibNumber = 2685693
        OR bibNumber = 2686042
        OR bibNumber = 2686232
        OR bibNumber = 2686233
        OR bibNumber = 2686561
        OR bibNumber = 2686574
        OR bibNumber = 2686595
        OR bibNumber = 2687223
        OR bibNumber = 2689521
        OR bibNumber = 2689813
        OR bibNumber = 2697227
        OR bibNumber = 2699308
        OR bibNumber = 2699472
        OR bibNumber = 2699910
        OR bibNumber = 2701213
        OR bibNumber = 2701831
        OR bibNumber = 2701903
        OR bibNumber = 2702729
        OR bibNumber = 2705420
        OR bibNumber = 2707824
        OR bibNumber = 2708539
        OR bibNumber = 2708581
        OR bibNumber = 2713105
        OR bibNumber = 2714923
        OR bibNumber = 2714956
        OR bibNumber = 2715124
        OR bibNumber = 2715262
        OR bibNumber = 2716334
        OR bibNumber = 2716337
        OR bibNumber = 2716794
        OR bibNumber = 2718088
        OR bibNumber = 2719385
        OR bibNumber = 2728693
        OR bibNumber = 2729581
        OR bibNumber = 2730380
        OR bibNumber = 2730895
        OR bibNumber = 2731084
        OR bibNumber = 2732372
        OR bibNumber = 2733588
        OR bibNumber = 2734461
        OR bibNumber = 2737921
        OR bibNumber = 2738980
        OR bibNumber = 2739984
        OR bibNumber = 2740021
        OR bibNumber = 2743502
        OR bibNumber = 2743589
        OR bibNumber = 2744458
        OR bibNumber = 2744629
        OR bibNumber = 2744630
        OR bibNumber = 2746833
        OR bibNumber = 2747267
        OR bibNumber = 2748155
        OR bibNumber = 2748527
        OR bibNumber = 2750672
        OR bibNumber = 2751807
        OR bibNumber = 2755536
        OR bibNumber = 2756282
        OR bibNumber = 2756308
        OR bibNumber = 2762382
        OR bibNumber = 2766258
        OR bibNumber = 2767297
        OR bibNumber = 2771604
        OR bibNumber = 2792709
        OR bibNumber = 2792824
        OR bibNumber = 2794603
        OR bibNumber = 2794626
        OR bibNumber = 2794637
        OR bibNumber = 2795061
        OR bibNumber = 2795232
        OR bibNumber = 2795559
        OR bibNumber = 2796319
        OR bibNumber = 2800237
        OR bibNumber = 2800806
        OR bibNumber = 2800873
        OR bibNumber = 2801237
        OR bibNumber = 2801616
        OR bibNumber = 2801859
        OR bibNumber = 2802329
        OR bibNumber = 2802453
        OR bibNumber = 2802635
        OR bibNumber = 2806269
        OR bibNumber = 2806664
        OR bibNumber = 2807917
        OR bibNumber = 2808983
        OR bibNumber = 2809172
        OR bibNumber = 2811405
        OR bibNumber = 2811585
        OR bibNumber = 2815178
        OR bibNumber = 2815215
        OR bibNumber = 2815218
        OR bibNumber = 2815249
        OR bibNumber = 2816343
        OR bibNumber = 2816368
        OR bibNumber = 2817343
        OR bibNumber = 2830487
        OR bibNumber = 2832924
        OR bibNumber = 2834040
        OR bibNumber = 2834331
        OR bibNumber = 2834486
        OR bibNumber = 2838392
        OR bibNumber = 2838891
        OR bibNumber = 2839344
        OR bibNumber = 2840485
        OR bibNumber = 2840491
        OR bibNumber = 2841718
        OR bibNumber = 2841786
        OR bibNumber = 2844523
        OR bibNumber = 2846192
        OR bibNumber = 2846233
        OR bibNumber = 2854425
        OR bibNumber = 2856416
        OR bibNumber = 2858802
        OR bibNumber = 2858813
        OR bibNumber = 2860050
        OR bibNumber = 2860711
        OR bibNumber = 2862264
        OR bibNumber = 2867019
        OR bibNumber = 2867026
        OR bibNumber = 2871038
        OR bibNumber = 2874300
        OR bibNumber = 2874394
        OR bibNumber = 2874680
        OR bibNumber = 2875283
        OR bibNumber = 2877275
        OR bibNumber = 2882295
        OR bibNumber = 2882296
        OR bibNumber = 2882298
        OR bibNumber = 2882299
        OR bibNumber = 2883971
        OR bibNumber = 2899950
        OR bibNumber = 2903400
        OR bibNumber = 2909094
        OR bibNumber = 2915942
        OR bibNumber = 2923188
        OR bibNumber = 2927237
        OR bibNumber = 2927578
        OR bibNumber = 2930684
        OR bibNumber = 2932038
        OR bibNumber = 2932064
        OR bibNumber = 2935488
        OR bibNumber = 2939991
        OR bibNumber = 2940997
        OR bibNumber = 2941339
        OR bibNumber = 2945367
        OR bibNumber = 2945450
        OR bibNumber = 2946917
        OR bibNumber = 2957387
        OR bibNumber = 2960639
        OR bibNumber = 2960730
        OR bibNumber = 2969676
        OR bibNumber = 2969737
        OR bibNumber = 2991354
        OR bibNumber = 3004523
        OR bibNumber = 3011053
        OR bibNumber = 3011223
        OR bibNumber = 3013461
        OR bibNumber = 3014930
        OR bibNumber = 3018325
        OR bibNumber = 3023533
        OR bibNumber = 3032340
        OR bibNumber = 3035306
        OR bibNumber = 3036128
        OR bibNumber = 3044155
        OR bibNumber = 3046065
        OR bibNumber = 3051159
        OR bibNumber = 3052227)
        AND (SUBSTRING(itemType, 3, 4) = 'cd')
GROUP BY checkOutMonth
The processing code: [deleted for old version]
Attachments
updated_project1b_weihao.zip
The processing source code
(657.52 KiB) Downloaded 227 times
Last edited by qiu0717 on Fri Feb 05, 2016 12:51 pm, edited 11 times in total.

markhirsch8
Posts: 3
Joined: Wed Jan 06, 2016 1:43 pm

Where To Turn. Reactions to the Financial Crisis of 2008

Post by markhirsch8 » Sun Jan 24, 2016 11:16 pm

CONCEPT:

As an institution based on the collection and dissemination of knowledge in the service of the public, our access to the data set of the Seattle Public Library provides an insightful window into the behaviors and patterns of the public’s acquisition of knowledge over time. The time span of this collected data, 2006-2015, naturally encapsulates one of the most important events of recent history: the bursting of the American housing market bubble and resulting financial crisis of 2008.

Given this glimpse into a people’s means for seeking & acquiring information, we can begin to focus one lens for studying the public’s reaction to the 2008 financial crisis. By studying relationships of check-out frequency for Biblical Texts & Financial Best Sellers, in relation to the financial fulcrum of 2008, it is possible to make gain an understanding on the way a particular public (that of Seattle) reacts in the wake of financial crisis. Do they turn towards their faith? Or do they place their faith in understanding the world of finance.

This visualization creates a 2D matrix in which higher checkout rates correlate to a more visible display of the text representing each category.

MySQL query:

Code: Select all

SELECT
MONTH(checkOut),
YEAR(checkOut),
COUNT(IF( deweyClass >=220 AND deweyClass < 221, 1, NULL)) as "220",
COUNT(IF( deweyClass >=221 AND deweyClass < 222, 1, NULL)) as "221",
COUNT(IF( deweyClass >=222 AND deweyClass < 223, 1, NULL)) as "222",
COUNT(IF( deweyClass >=223 AND deweyClass < 224, 1, NULL)) as "223",
COUNT(IF( deweyClass >=224 AND deweyClass < 225, 1, NULL)) as "224",
COUNT(IF( deweyClass >=225 AND deweyClass < 226, 1, NULL)) as "225",
COUNT(IF( deweyClass >=226 AND deweyClass < 227, 1, NULL)) as "226",
COUNT(IF( deweyClass >=227 AND deweyClass < 228, 1, NULL)) as "227",
COUNT(IF( deweyClass >=228 AND deweyClass < 229, 1, NULL)) as "228",
COUNT(IF( deweyClass >=229 AND deweyClass < 230, 1, NULL)) as "229",
COUNT(IF( title LIKE '%total money makeover%', 1, NULL)) as "Total Money Makeover",
COUNT(IF( title LIKE '%think and grow rich%', 1, NULL)) as "Think and Grow Rich",
COUNT(IF( title LIKE '%wealthy barber%', 1, NULL)) as "the wealthy barber",
COUNT(IF( title LIKE '%money book for the young, fabulous & broke%', 1, NULL)) as "the money book for the young fabulous, & broke",
COUNT(IF( title LIKE '%science of getting rich%', 1, NULL)) as "the science of getting rich",
COUNT(IF( title LIKE '%financial peace revisited%', 1, NULL)) as "financial peace revisited",
COUNT(IF( title LIKE '%women & money%', 1, NULL)) as "women & money",
COUNT(IF( title LIKE '%buffettology%', 1, NULL)) as "buffettology",
COUNT(IF( title LIKE '%sound mind investing%', 1, NULL)) as "sound mind investing"

FROM
spl3._rawXmlDataCheckOuts
WHERE
(deweyClass >= 220 AND deweyClass < 230) OR (deweyClass >= 330 AND deweyClass < 340) OR deweyClass = 650
AND DATE(checkOut) >= '2006­01­01'
AND DATE(checkOut) <= '2014­12­31'

GROUP BY MONTH(checkOut), YEAR(checkOut)
ORDER BY YEAR(checkOut), MONTH(checkOut) 
Processing Code:

Code: Select all

float hMargin = 160;
float vMargin = 100;

Table table;
int numRows, numColumns;
float [][] dataMatrix;
float maxValue, minValue;

float cellWidth, cellHeight;

boolean normalization = false;

String[] labelNames = new String[21];

PImage bibleText;
PImage ecText;

void setup() {
  size(1280, 720);
  surface.setResizable(true);

  table = loadTable("bible_finance.csv", "header");
  numRows = table.getRowCount();
  numColumns = table.getColumnCount();
  dataMatrix = new float[numColumns][numRows];
  println("Rows: " + numRows + " Columns: " + numColumns);

  for (int i=0; i<numColumns-1; i++) {
    for (int j=0; j<numRows; j++) {
      dataMatrix[i][j] = table.getFloat(j, i+1);
    }
  }

  maxValue = max2D(dataMatrix);
  minValue = min2D(dataMatrix);

  println("Max Value is " + maxValue);
  println("Min Value is " + minValue);

  labelNames[0] = "Month";
  labelNames[1] = "Year";
  labelNames[2] = "Bible";
  labelNames[3] = "Old Testament";
  labelNames[4] = "Historical Books (OT)";
  labelNames[5] = "Poetic books (OT)";
  labelNames[6] = "Prophetic books (OT)";
  labelNames[7] = "New Testament";
  labelNames[8] = "Gospels & Acts";
  labelNames[9] = "Epistles";
  labelNames[10] = "Revelation (Apocalypse)";
  labelNames[11] = "Apocrypha, pseudepigrapha";
  labelNames[12] = "Total Money Makeover";
  labelNames[13] = "Think & Grow Rich";
  labelNames[14] = "The Wealthy Barber";
  labelNames[15] = "The Money Book";
  labelNames[16] = "The Science of Getting Rich";
  labelNames[17] = "Financial Peace Revisited";
  labelNames[18] = "Women & Money";
  labelNames[19] = "Buffettology";
  labelNames[20] = "Sound Mind Investing";

  bibleText = loadImage("test.png");
  ecText = loadImage("test2.png");
}

void draw() {
  //println(mouseX, mouseY);
  background(255);
  
  image(bibleText, hMargin + cellWidth + 3, vMargin + cellHeight);
  image(ecText, hMargin + cellWidth + 3, vMargin + cellHeight*12);
  //modifying the cell size according to window size
  cellWidth = (width - hMargin*2)/numRows;
  cellHeight = (height - vMargin*2)/(numColumns-1);

  //Draw 2D Matrix
  for (int i=1; i<numColumns-1; i++) {
    for (int j=0; j<numRows; j++) {
      noStroke();
      //stroke(255);
      //strokeWeight(1);
      float greyScale = map(dataMatrix[i][j], minValue, maxValue, 255, 0);

      fill(255, greyScale);
      //fill(10);
      rect(hMargin + cellWidth*j, vMargin 
        + cellHeight*i, cellWidth, cellHeight);
    }
  }

  drawLabels();

  if (normalization == true) normalization();
  else if (normalization == false) resetData();
}

void drawLabels(){
  //draw label border
  fill(50);
  rect(0, vMargin, cellHeight*6.5, cellHeight*15);
  fill(100);
  rect(0, cellHeight*15, cellHeight*6.5, cellHeight*10);
  //Draw vertical labels
  for (int i=2; i<numColumns; i++) {
    textAlign(RIGHT, CENTER);
    fill(255);
    textSize(11);
    text(labelNames[i], hMargin, 
      vMargin + cellHeight/2 + cellHeight*(i-1)*1.003);
  }

  //draw timeline
  fill(200);
  rect(hMargin + cellWidth*22 + (3.4*cellWidth), vMargin-47, 32, 20);

  stroke(50);
  strokeWeight(1);
  line(hMargin + 8, vMargin - 10, width - (hMargin+29), vMargin - 10);
  for (int k=1; k< 98; k++) {
    for (int m = 1; m < 96; m+=12) {
      //months
      line(hMargin + cellWidth*k, vMargin-10, hMargin + cellWidth*k, vMargin-20);
      //years
      fill(10);
      strokeWeight(0);
      text(int(table.getFloat(m, 1)), hMargin + cellWidth*m + (3.5*cellWidth), vMargin-40);
      line(hMargin + cellWidth*m, vMargin-10, hMargin + cellWidth*m, vMargin-40);
    }
  }

  //draw title
  textSize(34);
  text("Where", width - hMargin/3, 20);
  noFill();
  rect(width - 45, 10, 40, 40);

  pushMatrix();
  rotate(radians(90));  
  text("To Turn", 190, -width + 20);
  popMatrix();

  textSize(12);
  textAlign(RIGHT);
  //Monthly Checkout Rates of Biblical Texts and Financial Best Sellers Surrounding the Financial
  //Crisis of 2008
  text("Monthly Checkout Rates of Biblical Texts and Financial Best Sellers", width-55, height - 35);
  text("Surrounding the Financial Crisis of 2008", width-55, height - 15);
  rect(width - 45, height - 50, 40, 40);
  
}

//Function to get max value from a 2d array
float max2D(float[][] array2D) {
  float max = 0;
  for (int i=2; i<array2D.length; i++) {
    for (int j=0; j<array2D[i].length; j++) {
      if (array2D[i][j] > max) {
        max = array2D[i][j];
      }
    }
  }
  return max;
}

//Function to get min value from a 2d array
float min2D(float[][] array2D) {
  float max = max2D(array2D);
  float min = max;
  for (int i=2; i<array2D.length; i++) {
    for (int j=0; j<array2D[i].length; j++) {
      if (array2D[i][j] < min) {
        min = array2D[i][j];
      }
    }
  }
  return min;
}

Analysis:


I am happy with the way in which text transparency is acting as the main element to visualize the data. I was having issues with the Normalization (which I feel would help the data to "pop" more). The immediate next step I'd like to tweak is the fonts and color spectrum.
Attachments
HIRSCH_screen_grab copy.jpg
bible_finance.csv
(5.71 KiB) Downloaded 217 times
Last edited by markhirsch8 on Sun Jan 24, 2016 11:19 pm, edited 4 times in total.

changhe
Posts: 6
Joined: Wed Jan 06, 2016 1:39 pm

Re: PROJ 1b: VISUALIZING the CULTURE ANALYSIS in 2D (PROCESS

Post by changhe » Sun Jan 24, 2016 11:16 pm

When "New" Books Are No Longer New

Concept:
My idea is to explore the checkout frequency and trends of those recently bought new books in Seattle Public Library. The interesting question is that how popular are those new books and will they be the same popular among readers several years later. After I looked up the SPL data, I felt that it might be some clear pattern in the data if I categorize them based on their content. Therefore I chose fiction books and non-fiction books, and compared them. The data showed different patterns which was a interesting result.
My 2D visualisation design is also based on my initial questions together with the characters of data.

About Data:
There are 3 trends pretty clear in my query result:
1. Those new books were much more popular in the first 2 years than the following years.
2. Comparing to non-fiction books, those fiction items were more popular among readers.
3. The dramatic drop of people's interest in fictions were more obvious and severe than non-fictions.

I also explored the average checkout duration based on years and category, which is my update on mysql query.
Here is my MySQL query:

Code: Select all

SELECT 
    right(callNumber, 4) as versionYear,
    CASE
        WHEN length(deweyClass) > 0 THEN 'non-fiction'
        ELSE 'fiction'
    END as isFiction,
    AVG(TIMESTAMPDIFF(DAY, checkOut, checkIn))  AS 'Average Days',
    SUM(CASE
        WHEN Year(checkOut) = 2006 THEN 1
        ELSE 0
    END) AS '2006',
    SUM(CASE
        WHEN Year(checkOut) = 2007 THEN 1
        ELSE 0
    END) AS '2007',
    SUM(CASE
        WHEN Year(checkOut) = 2008 THEN 1
        ELSE 0
    END) AS '2008',
    SUM(CASE
        WHEN Year(checkOut) = 2009 THEN 1
        ELSE 0
    END) AS '2009',
    SUM(CASE
        WHEN Year(checkOut) = 2010 THEN 1
        ELSE 0
    END) AS '2010',
    SUM(CASE
        WHEN Year(checkOut) = 2011 THEN 1
        ELSE 0
    END) AS '2011',
    SUM(CASE
        WHEN Year(checkOut) = 2012 THEN 1
        ELSE 0
    END) AS '2012',
    SUM(CASE
        WHEN Year(checkOut) = 2013 THEN 1
        ELSE 0
    END) AS '2013',
    SUM(CASE
        WHEN Year(checkOut) = 2014 THEN 1
        ELSE 0
    END) AS '2014',
    SUM(CASE
        WHEN Year(checkOut) = 2015 THEN 1
        ELSE 0
    END) AS '2015'
FROM
    spl3._rawXmlDataCheckIns
WHERE
    substring(collectionCode from 3 for 3) = 'new'
        AND right(callNumber, 4) > 2005
        AND right(callNumber, 4) < 2016
        AND itemType = 'acbk'
		AND checkOut != "1970-01-01 00:00:00"
GROUP BY versionYear , isFiction
ORDER BY versionYear , isFiction
To explain myself that why not explore data in monthly dimension, the result will be meaningless. First of all, we won't able to know if the book was a new one in the desired month, because the way of knowing the public time is to check the call number and collection code, which can only provide us the publication year. Second, we also couldn't know the exact number of books that library bought every month. So even the data shows a clear decrease or growth of checkout volume, we couldn't know if it is because people borrow them more often or library just simply buy more book than last time. As a conclusion, I have to work with annual data based on my question.

Visualisation:
The concept of visualisation is frankly simple. I want to compare 2 categories, so I make the graph symmetric. The number of annual checkouts determined how big each circle was, which can reflect the trend in a fairshaped way. Colors showed how many years passed after these books were published. Additionally, I load several color maps, so user can interact with this visualization. I also chose a font I think was appropriate to this theme instead using the default font in processing.
mode2+num.png
project screenshot in mode2 with numbers
Interations:
Press 1,2,3 to change color modes.
Press N or n to show some figures in graph and to hide them.
mode1.png
project screenshot in mode1
mode3+num.png
project screenshot in mode3 with numbers
The whole project with processing program, cvs file, query and more screenshots are in the zip file attached.
Attachments
MAT259hw1.zip
2D Matrix Visualisation 2016w by Hilda Chang HE
(1.32 MiB) Downloaded 222 times
Last edited by changhe on Mon Jan 25, 2016 2:25 pm, edited 5 times in total.

akibmayadav
Posts: 3
Joined: Tue Jan 12, 2016 11:57 am

Re: PROJ 1b: VISUALIZING the CULTURE ANALYSIS in 2D (PROCESS

Post by akibmayadav » Sun Jan 24, 2016 11:28 pm

CONCEPT :

This project revolves about visualizing the data obtained as a part of the previous project " Is the Sun Out ? ".
To understand the process behind and output of the project "Is the Sun Out ?" , please visit the page : http://www.mat.ucsb.edu/forum/viewtopic ... 1768#p1768.

The last iteration of my previous project led me to a massive dataset, which could be best understood by visualizing it. I have taken up a spherical grid and concept to illustrate the dataset.
The sketch below gives an overview of how the various details of this visualization
IMG_4020.jpg
If we move along the radius of the circle it is equivalent to moving in time. The circle has been sectioned into 20 arcs, where every arc indicates the precipitation/temperature ,in other words the weather parameters.The increase in this parameter is in the anticlockwise direction. The individual arc is then color coded depending on the number of checkouts on that particular day.

TEMPERATURE DEPENDENCY OF CHECKOUTS
TempVsCheckouts.png
The visualization of this data depicts that the Seattle Public library was visited majorly during the moderate temperatures only. But,the number of checkouts during very hot or very cold days is also quite a lot . Rather even during extreme summers (mid-2009,2013,2014) and winters (end-2009,2010,2013), the number of checkouts were very high . This implies that extreme weather also did not hinder people from visiting the library.

RAIN DEPENDENCY OF CHECKOUTS
RainfallVsCheckouts.png
The visualization of this data depicts that the Seattle Public library was visited majorly during the the days of no rainfall.The effect of rain is not the same as temperature.Heavy rainfalls do hinder accessibility to Seattle Public library.
One thing that can be very clearly seen in this visualization, not pertaining to rain , is that there was a sudden increase in the number of checkouts in the time 2008-2011.

SQL QUERY

Temperature Analysis

Code: Select all

SELECT Assign1.library_data.Date as Date ,
 Assign1.library_data.TotalCheckouts as TotalCheckouts ,
 Assign1.weather_temp.Average_Temp as Average_Temp
FROM Assign1.library_data
LEFT JOIN Assign1.weather_temp
ON Assign1.library_data.date=Assign1.weather_temp.date
ORDER BY Assign1.library_data.Date
Output:
weather_temp_comparingcheckouts.csv
(61.34 KiB) Downloaded 248 times
Processing Time :2.421 sec

Precipitation Analysis

Code: Select all

SELECT Assign1.library_data.Date as Date ,
 Assign1.library_data.TotalCheckouts as TotalCheckouts ,
 Assign1.weather_prep.Precipitation as Average_Prep
FROM Assign1.library_data
LEFT JOIN Assign1.weather_prep
ON Assign1.library_data.date=Assign1.weather_prep.date
ORDER BY Assign1.library_data.Date
Output:
weather_prep_comparingcheckouts.csv
(62.21 KiB) Downloaded 235 times
Processing Time :1.407 sec

PROCESSING CODE :

Code: Select all

// Layout variables 
float constantHorizontalMargin = 160;
float constantVerticalMargin = 100;

// 2D matrix table related variables
Table table; // to read the csv file
int numRows, numColumns; //number of rows and cols in the table
float[][] dataMatrix; // new datastructure to hold contents we need from the table
float maxtempValue, mintempValue,max_CheckOuts,min_CheckOuts,maxprepValue,minprepValue; //max and min values to plot
float[] start_angle,end_angle; //mark the angles to start and end the arcs
color[] c,c_center; // colors for the markings
PImage grid_prep,grid_checkout;
boolean switch_compare=false;
void setup ()
{
  size(6000,6000);                    
  surface.setResizable(true);
 //Put data into Processing table from csv
 if(switch_compare == true)
  table = loadTable("weather_temp_comparingcheckouts.csv", "header");
 else if(switch_compare == false)
  table = loadTable("weather_prep_comparingcheckouts.csv", "header");
  numRows = table.getRowCount(); 
  numColumns = table.getColumnCount();
  dataMatrix = new float[numRows][numColumns-1];
  start_angle=new float[numRows];
  end_angle=new float[numRows];
  c= new color[numRows];
  c_center= new color[22];
  grid_prep=loadImage("Prep_Temp_Grid.jpg");
  grid_checkout=loadImage("Grid_Checkouts1.jpg");
  
  println("Rows: " + numRows + " Columns: " + numColumns);

  // Storing tables contents that we need into a new 2D array dataMatrix
  for (int i=0; i<numRows; i++) {
    for (int j=0; j<numColumns-1; j++) {
      dataMatrix[i][j] = table.getFloat(i,j+1);
    }
  }
  
  // Max and Min values for plotting
  if(switch_compare == true)
  {
    maxtempValue = max2D(dataMatrix,1,numRows);
    mintempValue = min2D(dataMatrix,1,numRows);
  }
  else if(switch_compare == false)
  {
    maxprepValue = max2D(dataMatrix,1,numRows);
    minprepValue = min2D(dataMatrix,1,numRows);
  }
   
    max_CheckOuts = max2D(dataMatrix,0,numRows);
    min_CheckOuts = min2D(dataMatrix,0,numRows);
    
    //println("Max Temperature Value is " + maxtempValue);
    //println("Min Temperature Value is " +  mintempValue);
    //println("Min Checkouts Value is " +  min_CheckOuts);
    //println("Max Checkouts Value is " +  max_CheckOuts);
 
  // To find the start and end angle of arc which depends on the amount of precipitation that day
  if(switch_compare == true)
  {
  float difference = (maxtempValue - mintempValue)/20;
  for (int i =0 ; i<numRows; i++)
  {
    for (int n=0 ; n<21 ; n++)
    {
      if ((dataMatrix[i][1]>=mintempValue+(difference*n))&&(dataMatrix[i][1]<mintempValue+(difference*(n+1))))
      {
        start_angle[i]=n*(PI/10);
        end_angle[i]=(n+1)*(PI/10);
      } 
    }
  }
  // last value (88 temp) is not included in the loop above.
    start_angle[1243]=(19*PI)/10;
    end_angle[1243]=(20*PI)/10;
  }
  
  else if (switch_compare == false)
  {
    
    float difference = (maxprepValue - minprepValue)/20;
  for (int i =0 ; i<numRows; i++)
  {
    for (int n=0 ; n<21 ; n++)
    {
      if ((dataMatrix[i][1]>=minprepValue+(difference*n))&&(dataMatrix[i][1]<minprepValue+(difference*(n+1))))
      {
        start_angle[i]=n*(PI/10);
        end_angle[i]=(n+1)*(PI/10);
      } 
    }
  }
  // last value (88 temp) is not included in the loop above.
    start_angle[644]=(19*PI)/10;
    end_angle[644]=(20*PI)/10;
   
  }
  
  //loading image for color mapping 
    String[] colorPath = {"Grid_Checkouts1.jpg","Prep_Temp_Grid.jpg"};
    PImage colorBar_checkouts = loadImage(colorPath[0]);
    PImage colorBar_prep = loadImage(colorPath[1]);
    for (int j=0; j<numRows; j++) {
    c[j] = colorBar_checkouts.get((int)map(dataMatrix[j][0], min_CheckOuts, max_CheckOuts,2,colorBar_checkouts.width-2),colorBar_checkouts.height/2);
    }
    for (int j=0; j<21; j++) {
    c_center[j] = colorBar_prep.get((int)map(j,0,20,15,colorBar_checkouts.width),colorBar_checkouts.height/2);
    }
}

void draw() {
  background(255,255,255,35); 
  float x_c=600;
  float y_c=520;
  
   // SHADING index the precipitation areas
  for (int i =0 ;i<20;i++)
  {
    //0.26 is the magic number which is fitting the visual in this area
    fill(c_center[i],80);
    noStroke();
    arc(x_c,y_c,1200,1200,i*(PI/10),(i+1)*(PI/10));
    
  } 
  
   
  // Drawing lines along to index the precipitation areas
  int l = 550;
  for (int i=0;i<10;i++)
  {
    float m = tan(i*PI/10);
    float x_l= x_c+sqrt((l*l)/((m*m)+1));
    float y_l= y_c+m*(sqrt((l*l)/((m*m)+1)));
    float x_l1= x_c-sqrt((l*l)/((m*m)+1));
    float y_l1= y_c-m*(sqrt((l*l)/((m*m)+1)));
    stroke(0,0,0,50);
    noFill();
    strokeWeight(1);
    line(x_c,y_c,x_l,y_l);   
    line(x_c,y_c,x_l1,y_l1); 
  }
  
    //INDEXING FOR YEARS ( CIRCLES)
   
  stroke(0,0,0,20);
  noFill();
  //2006
  strokeWeight(43.94);
  ellipse(x_c,y_c,243.94,243.94);
  //2007- blank space
  //2008
  strokeWeight(47.19);
  ellipse(x_c,y_c,420.87,420.87);
  //2009- blank space
  //2010
  strokeWeight(45.76);
  ellipse(x_c,y_c,605.08,605.08);
  //2011
  //2012
  strokeWeight(44.98);
  ellipse(x_c,y_c,787.02,787.02);
  //2013
  //2014
  strokeWeight(44.33);
  ellipse(x_c,y_c,969.15,969.15);
 
 
  for (int i =0 ;i<numRows;i++)
  {
    //0.26 is the magic number which is fitting the visual in this area
    float r = i*0.26+200;
    noFill();
    stroke(c[i]);
    //we want width of one day to be 0.26 and hence the strokeweight would be 0.13,0.13 on either side
    //strokeWeight(0.13);
    strokeWeight(1.2);
    arc(x_c,y_c,r,r,start_angle[i],end_angle[i]);
    
  }
  
  // TEXT INDEX
   //YEARS
   textSize(10);
   fill(0,0,0);
   text("2006", x_c+107 , y_c); 
   text("2007", x_c+152, y_c);
   text("2008", x_c+197 , y_c); 
   text("2009", x_c+242 , y_c); 
   text("2010", x_c+287 , y_c); 
   text("2011", x_c+332 , y_c); 
   text("2012", x_c+377 , y_c); 
   text("2013", x_c+422 , y_c); 
   text("2014", x_c+467 , y_c); 
   text("2015", x_c+512 , y_c); 
   
  //SIDE COMMENTRY
  textSize(60);
  fill(95,95,95);
  text("IS THE SUN OUT ?",1340,70);
  
  textSize(10);
  fill(80,80,80);
  text("MAT 259 : Visualizing Information | Ambika Yadav",1342,87);
  
  textSize(20);
  fill(95,95,95);
  
  text("Visualizing Seattle Public Library Checkouts",1345,130 );
  text("dependency on temperature and rainfall levels  ",1345,155);
  text("in Seattle on a daily basis from 2006-2015. ",1345,180);
  
  textSize(10);
  fill(95,95,95);
  text("Every day from 1st January 2006 to 22 January 2015 is depicted by an arc constricted in a angle ",1345,200 );
  if(switch_compare == true)
  text("which depicts the temperature in Seattle on that particular the day. The number of checkouts",1345,212);
  else if(switch_compare == false)
  text("which depicts the rainfall in Seattle on that particular the day. The number of checkouts",1345,212);
  text("color coded where black indicates the minimum checkouts. ",1345,224);
 
  // GRIDS
  
  // Checkouts
  textSize(10);
  fill(95,95,95);
  text("NUMBER OF CHECKOUTS",1345,255);
  
  image(grid_checkout, 1345,260,width/25, height/220);
  textSize(10);
  fill(95,95,95);
  text("1",1345,300);
  text("38693",1555,300);
  
  textSize(10);
  fill(95,95,95);
  if(switch_compare == true)
  text("TEMPERATURE",1345,330);
  else if(switch_compare == false)
  text("RAINFALL",1345,330);
  
  // Temp/Prep
  image(grid_prep, 1345,335,width/25, height/220);
  textSize(10);
  fill(95,95,95);
  if(switch_compare == true)
  {
  text("22",1345,375);
  text("88",1570,375);
  }
  else if(switch_compare == false)
  {
  text("0.00",1345,375);
  text("3.98",1570,375);
  }
}
//MAX-MIN FUNCTION
//Function to get max value from a 2d array
float max2D(float[][] array2D, int column, int len) {
  float max = 0;
  for (int i=0; i<len; i++) {
    int j =column;
      if (array2D[i][j] > max) {
        max = array2D[i][j];
      }
  }
  return max;
}

//Function to get min value from a 2d array
float min2D(float[][] array2D ,int column, int len) {
  float max = max2D(array2D , column, len);
  float min = max;
  for (int i=0; i<len; i++) {
    int j= column;
      if (array2D[i][j] < min) {
        min = array2D[i][j];
      }
    }
  return min;
}
// INTERACTION
void keyPressed() {
  if(key == 'n' || key == 'N')
  {
    if (switch_compare == false)
    {
    println("Key Pressed");  
    switch_compare= true;
    }
    else if (switch_compare== true)
    {
    println("Key Pressed");
    switch_compare= false;
    }
  }
}
Last edited by akibmayadav on Wed Jan 27, 2016 10:25 am, edited 1 time in total.

junxiangyao
Posts: 10
Joined: Wed Jan 06, 2016 1:38 pm

Re: PROJ 1b: VISUALIZING the CULTURE ANALYSIS in 2D (PROCESS

Post by junxiangyao » Sun Jan 24, 2016 11:59 pm

How Reading Preferences of Books about Sports in the Library Varies with Time

Concept
In this project, I was using revised version of the dataset created in last project. I want to find if there is any particular pattern that can show that field of data was impact by some kinds of factors, like world wide sports events, weather, climate, politic reasons, geographical reasons and so on. I want to bring out the differences by organizing the layout of the whole image.

In the 2D matrix, I want to highlight the differences not only in each fields, but also between each fields. To foil the main body, I used different shades of grey to demonstrate the title, graphics that are not displaying data and other information that are not included in the main data chart.

In order to reduce the verbal information displaying in the screen , I used icons to represent different kinds of sports. Only when the mouse is hovering around the icon, the verbal name of that kinds of books will be displayed.Icons used were downloaded from https://icons8.com/web-app/new-icons/all

In addition, when the mouse is hovering around the certain year below the chart, the column of that year, including 12 ellipses representing data of each month in that year, will be emphasized by changing the background color of that column.

MySQL query:

Code: Select all

SELECT
YEAR(checkout) AS Year,  
MONTH(checkout) AS Month, 
SUM(CASE
WHEN deweyClass >= 796.323 AND deweyClass < 796.324 Then 1
ELSE 0 END) AS 'Basketball',
SUM(CASE
WHEN deweyClass >= 796.325 AND deweyClass < 796.326 Then 1
ELSE 0 END) AS 'Volleyball',
SUM(CASE
WHEN deweyClass >= 796.33 AND deweyClass < 796.34 Then 1
ELSE 0 END) AS 'Football',
SUM(CASE
WHEN deweyClass >= 796.342 AND deweyClass < 796.343 Then 1
ELSE 0 END) AS 'Tennis',
SUM(CASE
WHEN deweyClass >= 796.346 AND deweyClass < 796.347 Then 1
ELSE 0 END) AS 'Table Tennis',
SUM(CASE
WHEN deweyClass >= 796.352 AND deweyClass < 796.353 Then 1
ELSE 0 END) AS 'Golf',
SUM(CASE
WHEN deweyClass >= 796.357 AND deweyClass < 796.358 Then 1
ELSE 0 END) AS 'Baseball',
SUM(CASE
WHEN deweyClass >= 796.4 AND deweyClass < 796.5 Then 1
ELSE 0 END) AS 'Weight Lifting,Track&Field, Gymnastics',
SUM(CASE
WHEN deweyClass >= 796.6 AND deweyClass < 796.7 Then 1
ELSE 0 END) AS 'Cycling',
SUM(CASE
WHEN deweyClass >= 796.7 AND deweyClass < 796.8 Then 1
ELSE 0 END) AS 'Motor',
SUM(CASE
WHEN deweyClass >= 796.8 AND deweyClass < 796.9 Then 1
ELSE 0 END) AS 'Combat',
SUM(CASE
WHEN deweyClass >= 796.9 AND deweyClass < 797 Then 1
ELSE 0 END) AS 'Ice&Snow',
SUM(CASE
WHEN deweyClass >= 797.1 AND deweyClass < 797.2 Then 1
ELSE 0 END) AS 'Boating',
SUM(CASE
WHEN deweyClass >= 797.2 AND deweyClass < 797.3 Then 1
ELSE 0 END) AS 'Swimming & Diving',
FROM spl3._rawXmlDataCheckOuts
WHERE
itemtype = 'acbk'
AND YEAR(checkOut) >= '2006'
AND YEAR(checkOut) < '2015'
GROUP BY  MONTH(checkOut) , 
YEAR(checkOut) 
ORDER BY YEAR(checkOut)  , MONTH(checkOut)
Processing time: 445.702 sec


Processing code:

Code: Select all

/********************************************************
 * MAT259 PROJ.1b   2D Matrix                           *
 *                                                      *
 * Junxiang Yao                                         *     
 *                                                      *                          
 ********************************************************/
//layout 
int horizontalMargin = 150;
int verticalMargin = 140;

//data matrix related
Table table;
int rows, cols;
float[][] dataMatrix;
float max, min;
float cellWidth, cellHeight;
float r;

//color scheme
PImage colorBar;

//icons and names of data fields
PImage[] images;
String[] f = {"Basketball", "Volleyball", "Football", 
  "Tennis", "Table Tennis", "Golf", "Baseball", "Weight Lifting\nTrack&Field\nGymnastics", 
  "Cycling", "Motor", "Combat", "Ice&Snow", "Boating", "Swimming\n& Diving", };

// initialize the year
int startYear = 2006;

void setup() {
  size(1280, 720);
  surface.setResizable(true);
  //initialize the data
  table = loadTable("AllSports.csv", "header");
  rows = table.getRowCount(); 
  cols = table.getColumnCount();
  dataMatrix = new float[cols-2][rows];
  max = 0;
  for (int i=0; i<cols-2; i++) {
    for (int j=0; j<rows; j++) {
      dataMatrix[i][j] = table.getFloat(j, i+2);
      //find the max value
      if (dataMatrix[i][j]>max) {
        max = dataMatrix[i][j];
      }
    }
  }
  //find the min value
  min = max;
  for (int i=0; i<cols-2; i++) {
    for (int j=0; j<rows; j++) {
      if (dataMatrix[i][j]<min) {
        min = dataMatrix[i][j];
      }
    }
  }
print(max);

  // using colors from colorbar
  colorBar = loadImage("colorBar.jpg");

  //image array for the icons
  images = new PImage[cols-2];
  for (int i = 0; i < images.length; i++ ) {
    images[i] = loadImage( i + ".png" );
  }
}


void draw() {
  smooth();
  //refresh the canvas every frame
  background(40);

  //modifying the cell size according to window size
  cellWidth = (width - horizontalMargin*2)/rows;
  cellHeight = (height - verticalMargin*2)/cols;
  r = cellWidth/2;

  //set the position of the years
  for (int i=0; i<9; i++) {
    textAlign(CENTER, CENTER);
    fill(120);
    textSize(22);
    text(startYear+i, horizontalMargin + 12*cellWidth*i + cellWidth*6-3, 
      height - verticalMargin + 10 );
      //brighten the background to emphasize the years when mouse is hovering
    if (mouseX>(horizontalMargin + 12*cellWidth*i + cellWidth/2-cellWidth+2)&&
      mouseX< (horizontalMargin + 12*cellWidth*i + cellWidth/2-cellWidth+2+12*cellWidth) 
      && mouseY>(height - verticalMargin -20) && mouseY < height-verticalMargin+48) {
      fill(255, 10);
      noStroke();
      rect(horizontalMargin + 12*cellWidth*i + cellWidth/2-cellWidth+2, 180, cellWidth*12, height - verticalMargin*2 + 2);
    }
  }

  //draw 2D Matrix
  for (int i=0; i<cols-2; i++) {
    for (int j=0; j<rows; j++) {
      noStroke();
      color c = colorBar.get((int)map(dataMatrix[i][j], min, max, (colorBar.width-2)*5/6, 2), colorBar.height/2);
      fill(c);
      //except for the color, size is another argument while displaying data
      //the brighter the color is, the larger the ellipse will be
      float size = map(brightness(c), 0, 255, -3, 5);
      ellipse(horizontalMargin + cellWidth*j + r/2, verticalMargin + cellHeight*i + cellHeight/2 +50, r*size, r*size);
    }
  }
  
  //draw the icons from the image array
  for (int i=0; i<cols-2; i++) {
    imageMode(CENTER);
    image(images[i], horizontalMargin-cellWidth*2, verticalMargin + cellHeight*i + cellHeight/2+50, 20, 20);
  }

  // set the text version of the name of the rows by the left side of the icons, and
  // display when the position of the mouse is appropriate.
  if (horizontalMargin-cellWidth*2-10<mouseX&&horizontalMargin-cellWidth*2+10>mouseX) {
    for (int i = 0; i < cols-2; i++) {
      if (mouseY>verticalMargin + cellHeight*i + cellHeight/2+40&&
        mouseY<verticalMargin + cellHeight*(i+1) + cellHeight/2+40) {
        textAlign(RIGHT, CENTER);
        fill(100);
        textSize(17);
        text(f[i], horizontalMargin-cellWidth*2-15, verticalMargin + cellHeight*i + cellHeight/2 + 47);
      }
    }
  }
  
  
  //header
  textAlign(LEFT, CENTER);
  fill(200);
  textSize(36);
  text("How Reading Preferences of Books about",
  horizontalMargin-cellWidth*2+10,50);
  text("Sports in the Library Varies with Time",
  horizontalMargin-cellWidth*2+10,90);
  fill(120);
  textSize(20);
  text("Checkout times of the sports related books in the Seattle Public Library",
  horizontalMargin-cellWidth*2+10,130);
  noStroke();
  fill(120);
  rect(horizontalMargin-cellWidth*2-cellWidth*2+5,180,width - horizontalMargin*2+20, 3);
  
  //author
  textAlign(RIGHT, CENTER);
  textSize(12);
  text("Junxiang Yao", 
  width - horizontalMargin-12 ,151);
  text("MAT259 PROJ 1b", 
  width - horizontalMargin-12 ,167);
  
  
  //Colorbar
  textAlign(LEFT);
  textSize(12);
  text("Numbers of CheckOuts", 
  horizontalMargin-cellWidth*2-cellWidth*2+10,height - verticalMargin + 80);
  

  imageMode(CENTER);
  image(colorBar,horizontalMargin-cellWidth*2-cellWidth*2 + 230,
  height - verticalMargin + 76,150,12);
  
  textAlign(LEFT);
  textSize(12);
  text("443", 
  horizontalMargin-cellWidth*2-cellWidth*2+155,height - verticalMargin + 100);
  text("0", 
  horizontalMargin-cellWidth*2-cellWidth*2+305,height - verticalMargin + 100);
}
Analysis
1.From the chart, I think reading behavior about sports related books of Seattle citizen is impacted by the factors in the real world to some level. Like in the row of ice&snow sports, there are increases in every winter. And there are also increase in the rows of boating and cycling every summer.

2.Having compared each rows of ellipses, I found that ellipses in rows like volleyball and table tennis are too small to see the change, but other ellipses in rows like football and baseball is more obvious, both in size and color. I think this difference between each rows can tell the popularity of the sports related books. And I have two assumptions about why check out times of books about volleyball and table tennis is so small. The first one is Seattle citizens don't like those two kinds of sports; The second one is they do like these two kinds of sports, but they don't like to read or borrow books about these sports from Seattle Public Library. As for the rows of football, baseball, cycling, boating, etc, the data show that those sports are more popular. The data in the row of "weight lifting,track&field,gymnastics" is a special case. The number in this row is quite obvious because I summed up all the branches under this category in order to find a particular pattern. Otherwise the data will be scattered.

3.I think sports events in the real world are also impacting Seattle citizen's reading behavior. Since in 2008 and 2012, there are increases in the row of "weight lifting,track&field,gymnastics" in June, July and August, which are the months Beijing Olympics and London Olympics were hosted. In addition, there is another clear rise I may have an assumption to explain. In the row of football, from 2013 to 2015, the growth is obvious. I think the reason might be that in 2014, Seattle Seahawks, a NFL team from Seattle, won there first Super Bowl champion ship and almost defended it in 2015.
屏幕快照 2016-02-05 下午11.59.19.png
屏幕快照 2016-02-05 下午11.59.02.png
Attachments
JunxiangYaoHW1b.zip
(302.6 KiB) Downloaded 221 times
AllSports.csv
(5.89 KiB) Downloaded 211 times
Last edited by junxiangyao on Tue Feb 16, 2016 1:23 pm, edited 26 times in total.

jordanhughes
Posts: 4
Joined: Wed Jan 06, 2016 12:48 pm

Frequently Challenged Books

Post by jordanhughes » Mon Jan 25, 2016 12:16 am

FINAL EDIT:

Added option to reorder with 'r' key, added circle/rectangle option with 'e' key. Uploaded final code:
Project1.zip
Final Code
(2.92 MiB) Downloaded 169 times
EDIT*******************************************************************************************************************************

I went ahead and edited my original 2D matrix. I swapped the columns and rows so the book titles would be more readable. Additionally, I changed the color schemes to be more easily visible. However, the majority of the work was to make on-demand interactivity within the grid. On a mouse-over of a particular circle in the grid, the user will now see the number of checkouts, the years in which the book was challenged, a short description of the book, a picture of the cover, and the reasons for the challenges to the book.

I have attached updated screenshots for the visualization and the code itself in a zip file.
transposed axis.png
color_scheme.png
selected_title.png
FrequentlyChallengedEdit.zip
(2.9 MiB) Downloaded 170 times
/EDIT*******************************************************************************************************************************


Concept:

My project has to do with frequency of checkouts for particular books that were frequently challenged throughout the years 2006 through 2014. As for the visualization itself, I wanted something minimalistic and modern looking to represent the data. I stuck with Helvetica Light as my main font for this reason, and I opted for a clean dark background. The data itself is normalized and represented with a simple outlined circle, and a small legend indicating checkout frequency. I toyed with several color schemes, including solely black and white, a pastel color set, a blue-white gradient, and neons.

Processing Code:

Code: Select all

//FrequentlyChallengedMatrix.pde
Table table;
int numRows, numColumns;

float[][] dataMatrix;
float maxValue, minValue;

//rects
int horMargin = 160;
int verMargin = 40;
int topMargin = 10;
float cellWidth, cellHeight;

//Lablel
int startYear = 2006;
int endYear = 2014;

int circleRadius = 15;

boolean normalization = false;
boolean colorApplied = false;
String[] titles = {
"absolutely true diary of a part time indian",
"adventures of captain underpants",
"adventures of huckleberry finn",
"and tango makes three",
"athletic shorts",
"a bad boy can be good for a girl",
"bless me ultima",
"the bluest eye",
"bone volume 1: out from boneville",
"brave new world",
"catcher in the rye",
"the chocolate war",
"the color of earth",
"the color purple",
"crank",
"drama",
"the earth my butt and other big round things",
"fifty shades of grey",
"flashcards of my life",
"the glass castle",
"the golden compass",
"gossip girl",
"the hunger games",
"i know why the caged bird sings",
"its perfectly normal",
"the kite runner",
"looking for alaska",
"lush",
"my moms having a baby",
"my sisters keeper",
"nickel and dimed",
"olive's ocean",
"the perks of being a wallflower",
"persepolis",
"revolutionary voices",
"saga",
"scary stories",
"starting with alice",
"a stolen life",
"thirteen reasons why",
"to kill a mockingbird",
"ttyl",
"twilight",
"uncle bobby's wedding",
"what my mother doesnt know"};

void printDataMatrix(){
   for(int i=0; i<numColumns; i++){
    for(int j=0; j<numRows; j++){
      print(dataMatrix[i][j]);
      print(" ");
    }
    println();
   }
}

void setup(){
  size(1440, 800);
  surface.setResizable(true);

  //set the pixel density for retina display
  int d = displayDensity();
  pixelDensity(2);
  
  //load the data from the csv
  table = loadTable("FrequentlyChallengedList.csv","header");
  numRows = table.getRowCount();
  numColumns = table.getColumnCount();
  
  dataMatrix = new float[numColumns][numRows];
  println("Rows: " + numRows + " Columns: " + numColumns);
  
  maxValue = 0;
  dataMatrix = new float[numColumns][numRows];
  for(int i=0; i<numColumns; i++){
    for(int j=0; j<numRows; j++){
      dataMatrix[i][j] = table.getFloat(j, i);
      if(dataMatrix[i][j] > maxValue){
        maxValue = dataMatrix[i][j];
      }
    }
  }
  
 // printDataMatrix();
  
  minValue = maxValue;
  for(int i=0; i<numColumns; i++){
    for(int j=0; j<numRows; j++){
      dataMatrix[i][j] = table.getFloat(j, i);
      if(dataMatrix[i][j] < minValue){
        minValue = dataMatrix[i][j];
      }
    }
  }
  
  println("Max Value: " + maxValue);
  println("Min Value: " + minValue);
  
  //print the available fonts
   //String[] fontList = PFont.list();
  //printArray(fontList);
}

void draw(){
  //background(#282D48);
  background(0);
  cellWidth = (width - 2*horMargin)/numRows;
  cellHeight = (height - 2*verMargin)/(numColumns) -10;
  
   //Drawing 2D Matrix on cavas
    for(int i=0; i<numColumns; i++){
      for(int j=0; j<numRows; j++){
        float brightness = map(dataMatrix[i][j], minValue, maxValue, 255, 0);
        fill(brightness);
        //hide the grid
        //rect( horMargin + cellWidth*j, topMargin + cellHeight*i ,cellWidth,cellHeight);
        ellipse(horMargin + cellWidth*j + cellWidth/2, topMargin + cellHeight*i + cellHeight / 2, circleRadius, circleRadius);
      }
    }
    
     //Add Vertical Labels
  PFont myFont = createFont("Helvetica-Light", 14);
  textFont(myFont);   
     
  for(int i=0; i<9; i++){
    fill(255);
    textAlign(RIGHT, CENTER);
    text(startYear+i, horMargin- 10, topMargin + cellHeight/2 + cellHeight*i);
  }
  
  //Add title labels
   PFont newFont = createFont("Helvetica-Light", 9);
   textFont(newFont); 
   textAlign(CENTER, CENTER);
  
  //Add text labels
  for(int i=0; i<titles.length; i++){
     pushMatrix();
     translate(horMargin + i * cellWidth + cellWidth/2, topMargin + cellHeight*(numColumns) + 10);
     rotate(-45);
     textAlign(RIGHT);
     text(titles[i],0 ,0 );
     popMatrix();
  }
  
  //Draw Title
  textAlign(RIGHT, CENTER);
  textSize(18);
  text("frequently", width - topMargin, verMargin/2);
  text("challenged", width - topMargin, verMargin/2 + 20);
  text("titles", width - topMargin, verMargin/2 + 40);
  text("2006 - 2014", width - topMargin, verMargin/2 + 60);
  
  //Add the legend
  textAlign(RIGHT, CENTER);
  textSize(14);
  text("checkout frequency", width - topMargin, height/2 );
  for (int i=0; i <13; i++){
    float brightness = map(((maxValue - minValue) / 13) * i, minValue, maxValue, 255, 0);
    fill(brightness);
    ellipse(width - topMargin - 120 + (10*i), height/2 + 20 , circleRadius - 8, circleRadius - 8);
  }
  
  if(normalization == true) normalization();
  else if(normalization == false) denormalize();
  
  if(colorApplied == true) colorScheme();
 
}
//ColorScheme
PImage colorBar;

String[] colorPath = {"pastel.jpg", "neon.jpg", "blue_white.JPG", "Colormap4.jpg"};

int colorType = 0;

void colorScheme(){
  colorBar = loadImage(colorPath[colorType-1]);
  
  for (int i=0; i<numColumns; i++) {
    for (int j=0; j<numRows; j++) {
      stroke(255);
      strokeWeight(1);      
      color c = colorBar.get((int)map(dataMatrix[i][j], minValue, maxValue, 2, colorBar.width-2), colorBar.height/2);
      fill(c);
      //rect( horMargin + cellWidth*j, topMargin + cellHeight*i ,cellWidth,cellHeight);
      ellipse(horMargin + cellWidth*j + cellWidth/2, topMargin + cellHeight*i + cellHeight / 2, circleRadius, circleRadius);
    }
  }
  
  for (int i=0; i <13; i++){
    color c = colorBar.get((int)map(((maxValue - minValue) / 13) * i, minValue, maxValue, 2, colorBar.width-2), colorBar.height/2);
    fill(c);
    ellipse(width - topMargin - 120 + (10*i), height/2 + 20 , circleRadius - 8, circleRadius - 8);
  }
}
//Interaction
void keyPressed(){
  if(key == 'n' || key == 'N'){
     normalization = !normalization; 
  }
  
   if(key == '1' || key == '2' || key == '3' || key == '4'){
    colorApplied = true;
    if(key == '1') colorType = 1;
    else if(key == '2') colorType = 2;
    else if(key == '3') colorType = 3;
    else if(key == '4') colorType = 4;
  }
}
//Max_2D
//Function to get max value from a 2d array
float max2D(float[][] array2D) {
  float max = 0;
  for (int i=0; i<array2D.length; i++) {
    for (int j=0; j<array2D[i].length; j++) {
      if (array2D[i][j] > max) {
        max = array2D[i][j];
      }
    }
  }
  return max;
}

//Function to get min value from a 2d array
float min2D(float[][] array2D) {
  float max = max2D(array2D);
  float min = max;
  for (int i=0; i<array2D.length; i++) {
    for (int j=0; j<array2D[i].length; j++) {
      if (array2D[i][j] < min) {
        min = array2D[i][j];
      }
    }
  }
  return min;
}

void normalization(){
   for (int i=0; i<numColumns; i++) {
    for (int j=0; j<numRows; j++) {
      if (dataMatrix[i][j] != 0.0){
        dataMatrix[i][j] = log(table.getFloat(j, i));
      }
    }
  }
  maxValue = max2D(dataMatrix);
  minValue = min2D(dataMatrix);
  
}

void denormalize(){
   for (int i=0; i<numColumns; i++) {
    for (int j=0; j<numRows; j++) {
      dataMatrix[i][j] = table.getFloat(j, i);
    }
  }
  maxValue = max2D(dataMatrix);
  minValue = min2D(dataMatrix);
}
Analysis:

I am happy with my result, there are however a few updates that I will make in the future. I would like to sort and reorder the data so one can easily see the most frequently checked out at a glance. I want to add more interactivity to the visualization, and I would like to make it so the years that the books made the list are visible as well.
Attachments
FrequentlyChallenged.zip
(191.36 KiB) Downloaded 138 times
Screen Shot 2016-01-24 at 11.46.28 PM.png
blackwhite
Screen Shot 2016-01-24 at 11.47.40 PM.png
bw_gradient
Screen Shot 2016-01-24 at 11.47.49 PM.png
neon
Screen Shot 2016-01-24 at 11.47.57 PM.png
pastel
Last edited by jordanhughes on Mon Mar 14, 2016 5:42 pm, edited 3 times in total.

mayelsherif
Posts: 4
Joined: Wed Jan 06, 2016 1:42 pm

A dynamic comparative tool for labeling analysis

Post by mayelsherif » Mon Jan 25, 2016 12:30 am

In part 1 of the project, I attempted to explore the correlation between the number of subject entries (labels/tags) that describe an item in the Seattle Public Library and the number of checkouts and if it differs across different Dewey classes?

Motivation:
In this part, I will introduce a comparative tool that can be used to answer this question using a 2D matrix implementation of the scatter plot in Figure 1.
withoutJitter.png
As depicted in Figure 1, each point is color coded according to the Dewey classification of the item. The problem is that different points coincide on the top of each other. So, it is not easy to spot discrepancies across Dewey Classes.

Canvas description:
In this part of the project, I designed a comparative tool that can help spot differences between check out rates and its relationship with the number of labels across different Dewey Classes.
The tool begins by displaying an empty canvas as shown in Figure 2.
clearedCanvas.png
The only things that are rendered are the number of labels vertically from 1 to 25, the log to the base 10 of the check out rate horizontally and a legend consisting of different Dewey categories and their colors. I chose the range [1, 25] for the labels because more than 95% of the points lie in it. To avoid the elephant and mice problem, I chose to render the log to the base 10 of the checkout rate horizontally. The checkout rate axis consists of 4 columns. The first column is for values in the range [1, 10]. The second column is for values in the range (10 to 100]. The third column is for values in the range (100 to 1,000]. The third column is for values in the range (1,000 to 10,000]. The legend assigns different numbers to different Dewey Classes as follows:
  • 0 for CS, info and generic
  • 1 for Philosophy and Psychology
  • 2 for Religon
  • 3 for Social Science
  • 4 for Language
  • 5 for Science
  • 6 for Tech
  • 7 for Arts and Rec
  • 8 for Literature
  • 9 for History and Geog
The legend also depicts different shades of color ranging from light colors to dark colors. Light colors are used to represent smaller values and darker colors are used to represent larger numbers. The different shades used are purple, blue, pink, green, red, yellow, brown, orange, rainbow and gray.

How to use the tool?
After getting the canvas up and running, you can start comparing different Dewey Classes using different keyboard keys. If you press a, which represents all Dewey Classes, you will see the canvas filled with different spheres each representing the checkout rate per Dewey Class as in Figure 3.
all.png
The size of the sphere is proportional to the value of the log to the base 2 of the number of items in the same checkout range. The color is directly correlated with the number of items of the same checkout rate as well. Simply, a big sphere with darker color symbolizes a large number of items in that checkout range and vice versa.
To clear the canvas again, all you have to do is press c (i.e. clear).

To compare different elements of different Dewey Classes, simply press the number associated with this class in the legend after you clear the canvas as you can see in Figure. 4. In Figure 4, we were interested in comparing the entries of the Dewey Classes corresponding to Philosophy and Psychology, Social Sciences and Arts and recreation. So, we pressed 1, 3 and 7 after clearing the canvas(by pressing the letter 'c'). The canvas plotted the different checkout rates for these categories.
137.png
Conclusion:
In conclusion, in this project, I presented a dynamic tool that can be used to compare different Dewey Classes and their check out rate in comparison to the number of labels.
N.B. The query used and its processing time is described in the last assignment.
Attachments
MayElSherif_Project2DMatrix.zip
(2.66 MiB) Downloaded 148 times

theuniqueeye
Posts: 4
Joined: Wed Jan 06, 2016 12:51 pm

Re: PROJ 1b: VISUALIZING the CULTURE ANALYSIS in 2D (PROCESS

Post by theuniqueeye » Mon Jan 25, 2016 2:05 am

How does the dead rock star stay alive?
:: Jing Yan

:: :: :: :: :: Here is the Revision (update 2016-1-30 ) :: :: :: :: :: :: :: :: :: ::

Data
I revised MySQL code to get more detail data. To be more specific, I split the data of books and CDs to each different titles.

NEU MySQL code
each CD's checkout times per month

Code: Select all

SELECT 
    itemType,
    title,
    barcode,
    DATE_FORMAT(checkout, '20%y-%m') AS date,
    COUNT(checkout) AS checkoutTimes,
    AVG(TIMESTAMPDIFF(DAY, checkout, checkin)) AS itemDuration
FROM
    spl3._rawXmlDataCheckIns
WHERE
    bibNumber = '1952906'
        OR bibNumber = '2148651'
        OR bibNumber = '2023159'
        OR bibNumber = '2362135'
        OR bibNumber = '3029080'
        OR bibNumber = '2023157'
        OR bibNumber = '2299335'
        OR bibNumber = '1954184'
        OR bibNumber = '1736211'
        OR bibNumber = '2627462'
        OR bibNumber = '2128387'
        OR bibNumber = '3061214'
        OR bibNumber = '1959048'
        OR bibNumber = '1950899'
        OR bibNumber = '2444123'
        OR bibNumber = '2515298'
        OR bibNumber = '1976192'
        OR bibNumber = '2086964'
        OR bibNumber = '1953017'
        OR bibNumber = '2867039'
        OR bibNumber = '3057303'
        OR bibNumber = '1639110'
        OR bibNumber = '2363644'
        OR bibNumber = '2567243'
        OR bibNumber = '2211550'
        OR bibNumber = '3067034'
        OR bibNumber = '2631168'
        OR bibNumber = '1954182'
        OR bibNumber = '1880152'
        OR bibNumber = '2412531'
        OR bibNumber = '1976321'
        OR bibNumber = '2296937'
        OR bibNumber = '1972971'
        OR bibNumber = '2448150'
        OR bibNumber = '2612658'
        OR bibNumber = '1953009'
GROUP BY title,date
ORDER BY date,title
each Book's checkout times per month

Code: Select all

SELECT 
    itemType,
    title,
    barcode,
    DATE_FORMAT(checkout, '20%y-%m') AS date,
    COUNT(checkout) AS checkoutTimes,
	AVG(TIMESTAMPDIFF(DAY, checkout, checkin)) AS itemDuration

FROM
    spl3._rawXmlDataCheckIns
WHERE
    bibNumber = '1836438'
        OR bibNumber = '1965047'
        OR bibNumber = '2277690'
        OR bibNumber = '1823619'
        OR bibNumber = '2613601'
        OR bibNumber = '2707908'
        OR bibNumber = '2723037'
        OR bibNumber = '2815071'
        OR bibNumber = '2917442'
        OR bibNumber = '2941304'
        OR bibNumber = '3029321'
GROUP BY title,date
ORDER BY date,title
Visualization layout
sketch.JPG
all on.png
" ALL ON " general layout
cd with normalization.png
CD data with normalization
book with normalization.png
book data with normalization
I put the titles on the Y-axis. And the X-axis is still the timeline.
The Data of CD and book are distinguished by different color: blue for CD, and red for book. And they are all to some extent transparent to get an overlay view.
The checkout times per month is mapping to the length of the square

Interaction
The idea of ruler and footnote-data is kept. The ruler is updated to follow the mouse movement to be more useful. And footnote-data shows each value the mouse points at.
first view.png
first view
title off.png
title off
label off.png
label off
I like the way data pattern speaks for themselves, thus I spread them all over the screen. And make them the most obvious thing on the interface. To eliminate the distraction, I make switches which allows you to shut off the title and labels. It seems there are too much of them, I will change them to buttons next time.

Different color combination
yellowCyan.png
yellow and cyan
redBlue.png
red and blue
redLightCyan.png
red and light cyan
Style
In this revision, I explore more about Ryoji Ikeda’s art style. The background is changed from white to black to express a sense of empty both in time and space. The design is another attempt to create a feeling of calm, rationality and accuracy.

NEU Processing code
main tab

Code: Select all

/* Data Visualization - 2D Matrix (Processing 3)
 Based on Rodger's 2D Matrix Demo  
 
 ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 ::::::: How does Dead Rock Star Stay Alive :::::::::::::::::::::::
 ::::::::::::::::::::::::::::::::::::::::::::code: Jing Yan :::::::
 ::::::::::::::::::::theuniqueeye@gmail.com ::::::::::::::::::::::*/
 

// &&&&&&&&&&&&   HEY! here are all the switches   &&&&&&&&&&&&&&&&&&&
// C/c for CD; B/b for Book; T/t for title; N/n for normalization; L/l for label
// you press once to switch on and press again to switch off
// I am sorry there are a lot to remember. 

// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

// Layout variables 
float horizontalMargin = 10;
float verticalMargin = 20;

// 2D matrix table related variables
Table table0, table1, table2;
int numRows, numColumns;
int numBooks, numCDs;
float[][] dataMatrix;
String[] titlePool;
float maxValue, minValue;

// ### NOTE ### Because the checkout times for books are much smaller than the CDs.
// You can only get a general feeling of comparison by using maxValue of both CD and books.
// In order to exaimne more clearly the pattern for Books, I define this variable.
// It's used in normalization of Books' data. Press key N/n to have a try!
float maxValueBook; 

// width and height for each cell
float cellWidth, cellHeight;

// position to draw the square
float positionX, positionY;

// some switches for interaction
boolean showCDs, showBooks, showTitle, showLabel;

// font for different text
PFont titleFont, labelFont1, labelFont2;

// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

void setup() {

  // setup the size of the window
  size(1080, 720);

  // Load checkout times for both CD and Book
  table0 = loadTable("DB_title.csv", "header");
  table1 = loadTable("CD_CoutMonth.csv", "header");
  table2 = loadTable("BK_CoutMonth.csv", "header");

  // load font
  titleFont = loadFont("Carlito-Bold-48.vlw");
  labelFont1 = loadFont("KohinoorDevanagari-Light-48.vlw");
  labelFont2 = loadFont("WaseemLight-48.vlw");

  // Row: each different item from book and CD
  // Column: every month from 2005/8 to 2015/1
  numColumns = 42; 
  numRows = 114; // 5+9*12+1
  numBooks = 11;
  numCDs = 31;

  showCDs = false;
  showBooks = false;
  showTitle = true;
  showLabel = false;

  dataMatrix = new float[numRows][numColumns];
  titlePool = new String[numColumns];
  println("Rows: " + numRows + " Columns: " + numColumns);

  // ### NOTE ###  titlePool 
  // store every title in titlePool
  for (int i=0; i<numColumns; i++) {
    titlePool[i] = table0.getString(i, 0);
  }

  // Select by title to pick out each related row
  // then get the month and cout values from that row 

  for (int i=0; i<numColumns; i++) {
    for (TableRow row : table1.findRows(titlePool[i], 1)) { 
      String date = row.getString(3);
      int year = Integer.parseInt(date.substring(0, 4));
      int month = Integer.parseInt(date.substring(5, 7));
      int j = (year-2006)*12 + month + 4;
      if (j<=numRows) dataMatrix[j][i] = row.getInt(4);
    }

    for (TableRow row : table2.findRows(titlePool[i], 1)) { 
      String date = row.getString(3);
      int year = Integer.parseInt(date.substring(0, 4));
      int month = Integer.parseInt(date.substring(5, 7));
      int j = (year-2006)*12 + month + 4;
      if (j<=numRows) dataMatrix[j][i] = row.getInt(4);
    }
  }

  //turn the variable into month-format
  //same as the month-format in CD.csv data
  //String month= str(2005+(i+7)/12)+"/"+nf((i+8)%12, 2, 0);

  //### NOTE ### Try to keep the timeline evenly distribute. Not used yet.
  //if (row!=null) { 
  // dataMatrix[i][j] = table1.getFloat(j,i+1) + table2.getFloat(j,i+1);
  //} else {
  // dataMatrix[i][j] = 0;
  //}

  maxValue = max2D(dataMatrix);
  minValue = min2D(dataMatrix);
  maxValueBook = maxValue;

  println("Max Value is " + maxValue);
  println("Min Value is " + minValue);
  pixelDensity(displayDensity());
}

// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

void draw() {

  //refresh the canvas every frame
  background(0);

  // draw 2D matrix for Books & CDs 
  // show title and 
  if (showCDs == true) showCDs();
  if (showBooks == true) showBooks();
  if (showTitle == true) showTitle();
  if (showLabel == true) showLabel();

  // draw Ruler examine the timeline
  drawRuler();
}
show Books

Code: Select all

// &&&&&&&&&&&&& For books &&&&&&&&&&&&&&&&&&&&&&
void showBooks() {
  for (int i=0; i<numRows; i++) {
    for (int j=0; j<numBooks; j++) {

      // cellWidth is a constant related to number of months
      cellWidth = (width-2*horizontalMargin)/(numRows-1);

      // cellHeight is related to the number of Books
      cellHeight = (height-2*verticalMargin)/(numBooks-1);

      // the size of each pixel-like-square is mapping to the checkout times
      float squareLength = map(dataMatrix[i][j], minValue, maxValueBook, 3, 20);

      // the (x,y) position of each pixel-like-square
      positionX = i * cellWidth + horizontalMargin;
      positionY = j * cellHeight + verticalMargin;

      // some layout settings
      noStroke();
      fill(220, 20, 60, 150); // red transparency 95% 
      rectMode(CENTER);
      rect(positionX, positionY, squareLength, squareLength);
      
      
      // ### data showing for book-checkout-times ### 
      
      boolean mouseXIn = mouseX<(positionX+cellWidth/2) && mouseX>(positionX-cellWidth/2);
      boolean mouseYIn = mouseY<(positionY+cellHeight/2) && mouseY>(positionY-cellHeight/2);

      if (mouseXIn && mouseYIn) {
        int mouseData = int(dataMatrix[i][j]);
        textAlign(RIGHT, TOP);
        textFont(labelFont2, 8);
        fill(255);
        text("Checkout", width-75, height-12);
        textFont(labelFont1, 10);
        text(mouseData+" Book", width-6, height-12);
      }
    }
  }
}
show CDs

Code: Select all

// &&&&&&&&&&&&& For CDs &&&&&&&&&&&&&&&&&&&&&&
void showCDs() {
  for (int i=0; i<numRows; i++) {
    for (int j=numBooks; j<numColumns; j++) {

      // cellWidth is a constant related to number of months
      cellWidth = (width-2*horizontalMargin)/(numRows-1);

      // cellHeight is related to the number of CDs
      cellHeight = (height-2*verticalMargin)/(numCDs-1);

      // the size of each pixel-like-square is mapping to the checkout times
      float squareLength = map(dataMatrix[i][j], minValue, maxValue, 1, 20);

      // the (x,y) position of each pixel-like-square
      positionX = i * cellWidth + horizontalMargin;
      positionY = (j-numBooks) * cellHeight + verticalMargin;

      // some layout settings
      noStroke();
      fill(0, 245, 255, 150); // blue transparency 95% 
      rectMode(CENTER);
      rect(positionX, positionY, squareLength, squareLength);


      // ### data showing for CD-checkout-times ### 
      boolean mouseXIn = mouseX<(positionX+cellWidth/2) && mouseX>(positionX-cellWidth/2);
      boolean mouseYIn = mouseY<(positionY+cellHeight/2) && mouseY>(positionY-cellHeight/2);

      if (mouseXIn && mouseYIn) {
        int mouseData = int(dataMatrix[i][j]);
        textAlign(RIGHT, TOP);
        textFont(labelFont2, 8);
        fill(255);
        text("Checkout", width-75, height-12);
        textFont(labelFont1, 10);
        text(mouseData+" CD", width-45, height-12);
      }
    }
  }
}
interaction

Code: Select all

// &&&&&&&&&&&&   here are all the switches   &&&&&&&&&&&&&&&&&&&
// C/c for CD; B/b for Book; T/t for title; N/n for normalization
// you press once to switch on and press again to switch off

void keyPressed() {

  // press key for showing and hidding
  if (key == 'C'|| key =='c')
    showCDs = !showCDs;
  if (key == 'B'|| key =='b') 
    showBooks = !showBooks;
  if (key =='T'|| key =='t')
    showTitle = !showTitle;
  if (key =='L'|| key =='l')
    showLabel = !showLabel;

  // press key for normalization of Book patterns
  if (key =='N'|| key=='n') {
    if (maxValueBook == maxValue)
      maxValueBook = 17;
    else maxValueBook = maxValue;
  }
}
update_2DBowie_EYE.zip
update_Processing files
(289.35 KiB) Downloaded 154 times

:: :: :: :: :: Here is the Original Version ( 2016-1-24 ) :: :: :: :: :: :: :: :: :: ::

Concept
In project 1, I think the “aliveness” of David Bowie can be examined through two dimension: the quantity and quality. While the checkout times could be regarded as the quantity index, the checkout duration could be considered as the quality index.

In project 2, I mainly focus on the quantity dimension. I select the data of David Bowie’s CDs’ and related books’ checkout times per month from 2005 to 2015 in the Seattle Public Library.

Here is the Query code.
David Bowie’s CDs checkout times by year/month/day

Code: Select all

SELECT 
    DATE_FORMAT(checkout, '20%y-%m-%d') AS formatted_date,
    COUNT(checkout) AS checkoutTimes
FROM
    spl3._rawXmlDataCheckIns
WHERE
    bibNumber = '1952906'
        OR bibNumber = '2148651'
        OR bibNumber = '2023159'
        OR bibNumber = '2362135'
        OR bibNumber = '3029080'
        OR bibNumber = '2023157'
        OR bibNumber = '2299335'
        OR bibNumber = '1954184'
        OR bibNumber = '1736211'
        OR bibNumber = '2627462'
        OR bibNumber = '2128387'
        OR bibNumber = '3061214'
        OR bibNumber = '1959048'
        OR bibNumber = '1950899'
        OR bibNumber = '2444123'
        OR bibNumber = '2515298'
        OR bibNumber = '1976192'
        OR bibNumber = '2086964'
        OR bibNumber = '1953017'
        OR bibNumber = '2867039'
        OR bibNumber = '3057303'
        OR bibNumber = '1639110'
        OR bibNumber = '2363644'
        OR bibNumber = '2567243'
        OR bibNumber = '2211550'
        OR bibNumber = '3067034'
        OR bibNumber = '2631168'
        OR bibNumber = '1954182'
        OR bibNumber = '1880152'
        OR bibNumber = '2412531'
        OR bibNumber = '1976321'
        OR bibNumber = '2296937'
        OR bibNumber = '1972971'
        OR bibNumber = '2448150'
        OR bibNumber = '2612658'
        OR bibNumber = '1953009'
GROUP BY formatted_date
David Bowie’s related books’ checkout times by year/month/day

Code: Select all

SELECT 
    DATE_FORMAT(checkout, '20%y-%m-%d') AS formatted_date,
    COUNT(checkout) AS checkoutTimes
FROM
    spl3._rawXmlDataCheckIns
WHERE
    bibNumber = '1836438'
        OR bibNumber = '1965047'
        OR bibNumber = '2277690'
        OR bibNumber = '1823619'
        OR bibNumber = '2613601'
        OR bibNumber = '2707908'
        OR bibNumber = '2723037'
        OR bibNumber = '2815071'
        OR bibNumber = '2917442'
        OR bibNumber = '2941304'
        OR bibNumber = '3029321'
GROUP BY formatted_date
The idea of visualization layout is showed in the following sketches.
sketch_1.JPG
sketch - layout
sketch_2.JPG
sketch - theme and inspiration
General layout
I create a 2-column matrix to compare the CD and books. There are 114 rows which show every month from 2005/08 to 2015/01. The width of each cell-bar is mapped to the checkout times.
Inspired by David Bowie’s famous image of Ziggy Stardust, I would like to shape the layout of the visualization somehow related. Thus I break the matrix into lightning shape.

Interaction
I try to create a general view of the idea at first glance. And by interaction with key “C/c”, the color scheme and normalization will be applied which allow audience to examine the detailed relationship between data much easier. By press the key “R/r”, a ruler of timeline will show up for positioning time. Moreover, by moving the mouse, related label will get dark on the top of the screen and precise data number will show up at the left bottom of the screen.

2D-Matrix
with ruler
screenshoot3.png
screenshoot - without color scheme and normalization
with color scheme and normalization
screenshoot1.png
screenshoot - with mouse interaction in CD area
screenshoot2.png
screenshoot- with mouse interaction in Book area
Here is the Processing code.
main tab

Code: Select all

/* Data Visualization - 2D Matrix (Processing 3)
 Based on Rodger's 2D Matrix Demo  
 
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::: How does Dead Rock Star Stay Alive :::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::code: Jing Yan :::::::
::::::::::::::::::::theuniqueeye@gmail.com ::::::::::::::::::::::*/

// :: Interaction KEY 
// :: press R / r to show a ruler
// :: press C / c to apply the color scheme and do normalization

// Layout variables    
float constantVerticalMargin = 15;

// 2D matrix table related variables
Table table1, table2;
int numRows, numColumns;
float[][] dataMatrix;
float maxValue, minValue, maxBookValue;

// width and height for each cell and title
float cellWidth1, cellWidth2, cellHeight;  
float TitleWidth, TitleHeight;

boolean colorApplied = false;
boolean normalization = false;
boolean drawRuler = false;

// font for each text
PFont titleFont, subtitleFont, labelFont, noteFont;
PImage titleImage, labelImage1, labelImage2;


// Mouse data
boolean cdOrBook;
int mouseData;

// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

void setup() {
  // create a vertical interface
  size(560, 960); 

  // Make the screen resizable.                     
  surface.setResizable(true);

  // Load checkout times for both CD and Book
  table1 = loadTable("CD_CheckoutByMonth.csv", "header");
  table2 = loadTable("BK_CheckoutByMonth.csv", "header");

  titleFont = loadFont("KohinoorDevanagari-Bold-13.vlw");
  subtitleFont = loadFont("KohinoorDevanagari-Medium-10.vlw");
  labelFont = loadFont("OratorStd-8.vlw");
  noteFont = loadFont("KohinoorDevanagari-Demi-7.vlw");

  titleImage = loadImage("title-04.png");
  labelImage1 = loadImage("label-05.png");
  labelImage2 = loadImage("label-06.png");

  cdOrBook = false;

  // Row: 2 types for book and CD
  // Column: every month from 2005/8 to 2015/1
  numColumns = 2; 
  numRows = 114; // 5+9*12+1 

  dataMatrix = new float[numRows][numColumns];
  println("Rows: " + numRows + " Columns: " + numColumns);

  // The following for loop is used to load data into dataMatrix.
  // It's important to keep the timeline evenly distribute.

  for (int i=0; i<numRows; i++) {

    // turn the variable into month-format
    // same as the month-format in CD.csv data
    String month= str(2000+(i+8)/12+5)+"-"+nf((i+8)%12+1, 2, 0);

    // load CD's data into the 1st column
    TableRow row = table1.findRow(month, 0);
    if (row!=null) {
      dataMatrix[i][0] = row.getInt(1);
    } else {
      dataMatrix[i][0] = 0;
    }

    // turn the variable into month-format
    // same as the month-format in Book.csv data
    month= str(2000+(i+8)/12+5)+"/"+nf((i+8)%12+1, 2, 0);

    // load book's data into the 2rd column
    row = table2.findRow(month, 0);
    if (row!=null) {
      dataMatrix[i][1] = row.getInt(1);
    } else {
      dataMatrix[i][1] = 0;
    }
  }

  // get the maxValue, minValue 
  maxValue = max2D(dataMatrix);
  minValue = min2D(dataMatrix);
  println("Max Value is " + maxValue);
  println("Min Value is " + minValue);

  pixelDensity(displayDensity());
  smooth();
  noStroke();
}

// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

void draw() {
  //noStroke(); 
  background(245);
  TitleWidth = 150;
  TitleHeight = 50;

  // the height of each cell is the same
  cellHeight = (height - constantVerticalMargin*2 - TitleHeight)/(numRows);

  // Draw 2D Matrix!!
  noStroke(); 
  rectMode(CORNER);

  // Break the 2D matrix into 2 parts 
  // 1st part
  for (int i=0; i<65; i++) {

    // the width of each cell is related to the data value
    cellWidth1 = map(dataMatrix[i][0], minValue, maxValue, 0, 200);
    cellWidth2 = map(dataMatrix[i][1], minValue, maxValue, 0, 200); 

    // draw cells along the hypotenuse of "lightening"
    float x = (2-float(i)/76)*width/3;
    float y = constantVerticalMargin + cellHeight * i; 
    float gap = 5;

    fill(128);

    rect(x-cellWidth1-gap, y, cellWidth1, 0.3*cellHeight);
    rect(x+gap, y, cellWidth2, 0.3*cellHeight);

    // interaction with mouse position 
    // when the mouse falls in the range of each data, 
    // show the number of the data on left down corner of screen
    // when the mouse falls in the CD or book part of data, darken the label respectively
    
    boolean isMouseXIn = mouseX < (x-cellWidth1-gap+cellWidth1);
    boolean isMouseYIn = mouseY > y && mouseY < y + 0.3*cellHeight;
    if (isMouseXIn && isMouseYIn) {
      mouseData = int(dataMatrix[i][0]);
      cdOrBook = false;
    }

    isMouseXIn = mouseX > x+gap ;
    isMouseYIn = mouseY > y && mouseY < y + 0.3*cellHeight;
    if (isMouseXIn && isMouseYIn) {
      mouseData = int(dataMatrix[i][1]);
      cdOrBook = true;
    }
  }

  // 2nd part
  for (int i=65; i<114; i++) {

    cellWidth1 = map(dataMatrix[i][0], minValue, maxValue, 0, 200);
    cellWidth2 = map(dataMatrix[i][1], minValue, maxValue, 0, 200); 

    float x = (2-float(i)/76)*width/3 + TitleWidth;
    float y = constantVerticalMargin + cellHeight * i+TitleHeight; 
    float gap = 5;

    fill(128);

    rect(x-cellWidth1-gap, y, cellWidth1, 0.3*cellHeight);
    rect(x+gap, y, cellWidth2, 0.3*cellHeight);  
    
    // interaction with mouse position 
    // when the mouse falls in the range of each data, 
    // show the number of the data on left down corner of screen
    // when the mouse falls in the CD or book part of data, darken the label respectively
    
    boolean isMouseXIn = mouseX < (x-cellWidth1-gap+cellWidth1);
    boolean isMouseYIn = mouseY > y && mouseY < y + 0.3*cellHeight;
    if (isMouseXIn && isMouseYIn) {
      mouseData = int(dataMatrix[i][0]);
      cdOrBook = false;
    }

    isMouseXIn = mouseX > x+gap;
    isMouseYIn = mouseY > y && mouseY < y + 0.3*cellHeight;
    if (isMouseXIn && isMouseYIn) {
      mouseData = int(dataMatrix[i][1]);
      cdOrBook = true;
    }
  }

  // apply color and normalization
  if (colorApplied == true) colorScheme();
  
  // draw a timeline
  if (drawRuler == true) drawRuler();
  
  // draw title and labels and note
  drawText();
}

// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
color scheme

Code: Select all

// Let's apply grey color to the 2D matrix
// and meanwhile normalize it.

void colorScheme() {

  // use maxBookValue to minimize the scale difference between books and CDs.
  maxBookValue = 21;
  
  // Draw 2D Matrix with color and normalization
  for (int i=0; i<65; i++) {
    
    // the width of each cell is related to the data value
    cellWidth1 = map(dataMatrix[i][0], minValue, maxValue, 0, 200);
    cellWidth2 = map(dataMatrix[i][1], minValue, maxBookValue, 0, 200); 
    
    float x = (2-float(i)/76)*width/3;
    float y = constantVerticalMargin + cellHeight * i; 
    float gap = 5;
    
    // apply color with mapping
    fill(map(cellWidth1, 0, 200, 255, 0));
    rect(x-cellWidth1-gap, y, cellWidth1, 0.3*cellHeight);
    
    fill(map(cellWidth2, 0, 200, 255, 0));
    rect(x+gap, y, cellWidth2, 0.3*cellHeight);

  }
  for (int i=65; i<114; i++) {
    
    // the width of each cell is related to the data value
    cellWidth1 = map(dataMatrix[i][0], minValue, maxValue, 0, 200);
    cellWidth2 = map(dataMatrix[i][1], minValue, maxBookValue, 0, 200); 
    
    float x = (2-float(i)/76)*width/3 + TitleWidth;
    float y = constantVerticalMargin + cellHeight * i+TitleHeight; 
    float gap = 5;
    
    // apply color with mapping
    fill(map(cellWidth1, 0, 200, 255, 0));
    rect(x-cellWidth1-gap, y, cellWidth1, 0.3*cellHeight);
    
    fill(map(cellWidth2, 0, 200, 255, 0));
    rect(x+gap, y, cellWidth2, 0.3*cellHeight);
  }
}

draw ruler

Code: Select all

// Let's draw a ruler!
// This part is used to draw a timeline 
// start from 2005-08 end at 2015-01

void drawRuler() {
  stroke(0);
  strokeWeight(0.4);
  fill(0);
  
  // draw a long vertical line
  line(460, 0, 460, height);

  for (int i = 0; i<65; i++) {
      float y = constantVerticalMargin + cellHeight * i; 
    
    // draw a longer horizontal line for each year
    if ((i+8)%12 == 0 ) {
      line(453, y, 460, y);
      
      // add year(label) to longer lines
      textAlign(CENTER, TOP);
      textFont(labelFont, 8);
      pushMatrix();
      translate(465, y);
      rotate(- PI/2.0);
      textSize(8);
      text(str(2000+(i+8)/12+5), 0, 0);
      popMatrix();
      
      // draw short horizontal lines for each month
    } else line(457, y, 460, y);
  }
  
  // the title seperate the ruler into 2 parts
  for (int i = 65; i<114; i++) {
    float y = constantVerticalMargin + cellHeight * i + TitleHeight; 
    if ((i+8)%12 == 0 ) {
      // draw year lines
      line(453, y, 460, y);
      
      // year label
      textAlign(CENTER, TOP);
      textFont(labelFont, 8);
      pushMatrix();
      translate(465, y);
      rotate(- PI/2.0);
      text(str(2000+(i+8)/12+5), 0, 0);
      popMatrix();
      
      // draw month lines
    } else  line(457, y, 460, y);
  }
  
  // The stroke is pretty wired, it just cannot turn down.
  noStroke(); 
}
draw text

Code: Select all

// Let's draw TITLE, labels and notes.

void drawText() {
  textAlign(RIGHT, TOP);
  //textFont(titleFont, 20);
  //text("HOW DOES DEAD ROCK STAR STAY ALIVE", 457, constantVerticalMargin + cellHeight * 65+4);
  image(titleImage, 0, constantVerticalMargin + cellHeight * 65+4);
  if (cdOrBook == false) image(labelImage1, 0, 0);
  else image(labelImage2, 0, 0);

  textFont(labelFont, 8);
  //text("CD", 375, 10);
  //text("Book", 385, 10);

  fill(215,26,33);
  textAlign(LEFT, BOTTOM);
  text(str(mouseData), 53, height-constantVerticalMargin);
  textAlign(RIGHT, BOTTOM);
  text(" times per month", 147, height-constantVerticalMargin);
}
Analysis+Development
I really appreciate the style of Ryoji Ikeda’s visualization art work. And as the theme is about death and aliveness, I try to create a feeling of calm, rationality, accuracy and make the scene somehow like an electrocardiogram.

About the color scheme, there should be some development in the future.As David Bowie is famous for his constantly changing images and also known as pioneer of visual rock, I am thinking of picking colors from his CD covers to use as color scheme.
Attachments
sketch_2DBowie.zip
Processing files
(119.65 KiB) Downloaded 149 times
Last edited by theuniqueeye on Sun Jan 31, 2016 11:54 am, edited 9 times in total.

joo
Posts: 4
Joined: Thu Jan 07, 2016 10:19 am

Re: PROJ 1b: VISUALIZING the CULTURE ANALYSIS in 2D (PROCESS

Post by joo » Mon Jan 25, 2016 2:32 am

Travel Book Checkouts from 2009 to 2014

Concept description
I was curious about which area attracted people's attention the most during the vacation. To observe the differences between six dewey classes in a particular month and year, I referred to checkout counts in a travel book category (from 914 to 919) in the Seattle Public Library for 6 years (from 2009 to 2014).

914: Europe
915: Asia
916: Africa
917: North America
918: South America
919: Australasia, Pacific Ocean, Atlantic Ocean, Arctic islands, and Antarctica

Screen Shots

1. Color Classified by Dewey Class - Each Dewey Class has a particular hue.
dewey.png
2. Color Classified by Dewey Class - Each Dewey Class has a particular range of hues.
c1.png
3. Color Classified by Year
yearview.jpg
4. Height mapping with Color Variation 1
03.jpg
5. Height mapping with Color Variation 2
02.jpg
MySQL query

Code: Select all

SELECT 
	FLOOR(deweyClass) AS Dewey,
    MONTH(checkOut) AS MONTH,
    
    SUM(CASE
        WHEN YEAR(checkOut) = 2009 THEN 1
        ELSE 0
    END) AS '2009',
    SUM(CASE
        WHEN YEAR(checkOut) = 2010 THEN 1
        ELSE 0
    END) AS '2010',
    SUM(CASE
        WHEN YEAR(checkOut) = 2011 THEN 1
        ELSE 0
    END) AS '2011',
    SUM(CASE
        WHEN YEAR(checkOut) = 2012 THEN 1
        ELSE 0
    END) AS '2012',
    SUM(CASE
        WHEN YEAR(checkOut) = 2013 THEN 1
        ELSE 0
    END) AS '2013',
    SUM(CASE
        WHEN YEAR(checkOut) = 2014 THEN 1
        ELSE 0
    END) AS '2014'

FROM
    spl3._rawXmlDataCheckOuts
WHERE
    deweyClass >= 914 AND deweyClass <= 919

GROUP BY MONTH, Dewey
Processing time
38.930sec

Analysis
1. For an example of the basic block shape, color shows well about the popularity. However, due to the same size, it is difficult to recognize the increasing or decreasing checkout counts. It looks abstract in comparison to 2nd and 3rd images.

2. I mapped the number of checkouts into height of each matrix. In addition to color information, it is offering the difference values in more intuitive way. It makes clear to check the popularity and the rate of increase(or decrease) checkouts month by month.

3. I applied complementary color(red and green) to avoid too much simplicity. In case of 3rd image, color changes from warm to cold hues, and highest checkouts go back to a warm color again.

4. By the time of summer vacation(around June), checkout counts dramatically increase especially for North America. It may shows that people in Seattle prefer domestic trips.

5. Travel books were checked out more in summer rather than winter. The vacation period may affect the checkout rates.

6. The popularity between regions never change during 6 years, North America travel books checked out the most followed by Europe, Asia, South America, and Africa.

Processing Code - Regular Type

Code: Select all

//Assignment 1b - Woohun Joo

//font
PFont myFont;

//Layout Variable
int horMargin = 200;
int verMargin = 300;

//2D matrix variables
Table table;
int numRows, numColumns;
float[][] dataMatrix;
float[][] newSat;
float maxValue, minValue;

int cellDist = 10;

//cell width, height
float cellWidth, cellHeight;

//year labels
int startYear = 2009;

//normalization, color, reorder status
boolean normalization = false;
boolean colorApplied = false;
boolean reorder = false;

//month
String [] Month = {"Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec"};
int numMonth = 12;

void setup() {
  
  smooth();
  size(1280, 720);
  
  //font
  myFont =createFont("Helvetica", 38);
  textFont(myFont);
  
  //resize option
  surface.setResizable(true);
  
  //load csv file
  table = loadTable("assignment1b.csv", "header");
  
  //get the number of rows and cols
  numRows = table.getRowCount();
  numColumns = table.getColumnCount();
  
  //dataMatix = Float Array
  //print the number of Rows and Columns
  //question: why column-1? , dataMatrix has each value from table? 
  dataMatrix = new float[numColumns-2][numRows];
  println("Rows: " + numRows + " Columns: " + numColumns);
  
  //get max and min value
  //question: does i mean horizontal numbers of columns? 
  for(int i=0; i<numColumns-2; i++){
    for(int j=0; j<numRows; j++){
      //question: why j = i?
      dataMatrix[i][j] = table.getFloat(j, i+2);
    }
  }
  //?
  maxValue = max2D(dataMatrix);
  minValue = min2D(dataMatrix);
  
  println("Max Value " + maxValue);
  println("Min Value " + minValue);

}

//Refresh the canvas every frame
void draw() {  
  //background color
  
  background(50, 50, 50);
  
  //question
  //calculate width and height for each cell
  cellWidth = (width-2*horMargin)/numRows;
  cellHeight = (height-2*verMargin)/(numColumns-2);
  
  colorMode(HSB, 360, 255, 100);
  
  //drawing 2d matrix on canvas
  for(int i=0; i<numColumns-2; i++){
    float xTrans = 0;
    for(int j=0; j<numRows; j++){
      float sat = map(dataMatrix[i][j], minValue, maxValue,150,255);
      //float sat = 100;
      float bri = 100;
      float hue1 = map(dataMatrix[i][j], minValue, maxValue,0,60);
      float hue2 = map(dataMatrix[i][j], minValue, maxValue,60,120);
      float hue3 = map(dataMatrix[i][j], minValue, maxValue,120,180);
      float hue4 = map(dataMatrix[i][j], minValue, maxValue,180,240);
      float hue5 = map(dataMatrix[i][j], minValue, maxValue,240,300);
      float hue6 = map(dataMatrix[i][j], minValue, maxValue,300,360);
      //println(sat);
      //float bri = map(dataMatrix[i][j], minValue, maxValue,100,100);
      
      //float bri = 100;
      //stroke(77, 77, 77);
      noStroke();
      
      if(j%6 == 0 && j >= 0){
        fill(hue1, sat, bri);
      } else if(j%6 == 1) {
        fill(hue2, sat, bri);
      } else if(j%6 == 2) {
        fill(hue3, sat, bri);
      } else if(j%6 == 3) {
        fill(hue4, sat, bri);
      } else if(j%6 == 4) {
        fill(hue5, sat, bri);
      } else if(j%6 == 5) {
        fill(hue6, sat, bri);
      } 
      
      if(j%6 == 0 && j>0){
          xTrans += cellDist;
      }
      pushMatrix();
      translate(xTrans, 0);
      rect(horMargin + cellWidth*j, verMargin + cellHeight*i, cellWidth, cellWidth);
      popMatrix();
      
      }
   }
   colorMode(RGB, 255, 255, 255);
   //add vertical lables
   //for(int i = startYear; i < endYear; i++){
   for(int i = 0; i < numColumns-2; i++){  
     textAlign(RIGHT, CENTER);
     fill(255);
     textSize(12);
     //question?
     text(startYear+i, horMargin-15, verMargin-3 + cellHeight/2 + cellHeight*i);
   }
   //color chart
   colorMode(HSB, 360, 100, 100);
   setGradient(horMargin, verMargin + verMargin/2, cellWidth+50, cellHeight/2, color(0,100,100), color(60,100,100));
   setGradient(horMargin, verMargin + verMargin/2+20, cellWidth+50, cellHeight/2, color(60,100,100), color(130,100,100));
   setGradient(horMargin, verMargin + verMargin/2+40, cellWidth+50, cellHeight/2, color(140,100,100), color(200,100,100));
   setGradient(horMargin, verMargin + verMargin/2+60, cellWidth+50, cellHeight/2, color(200,100,100), color(250,100,100));
   setGradient(horMargin, verMargin + verMargin/2+80, cellWidth+50, cellHeight/2, color(255,100,100), color(300,100,100));
   setGradient(horMargin, verMargin + verMargin/2+100, cellWidth+50, cellHeight/2, color(300,100,100), color(359,100,100));
   
   colorMode(RGB, 255, 255, 255);
   //title text
   textAlign(CENTER, CENTER);
   textSize(15);
   
    
    //month Text
   for(int p = 0; p < numMonth; p++){
      fill(255);
      textAlign(LEFT, CENTER);
      textSize(13);
      text(Month[p], p*82+horMargin, verMargin - 15);
    }
    
    //number text
    //for(int q = 0; q < numMonth; q++){
    //  textSize(10);
    //  text("1  2  3  4  5  6 ", (q*72)+235, verMargin+110);
    //}
    
      
      textSize(36);
      text("Travel Book Checkouts", horMargin+3, verMargin-100);
      textSize(10);
      textAlign(LEFT, CENTER);
      text("Europe", horMargin+70, verMargin+155);
      text("Asia", horMargin+70, verMargin+175);
      text("Africa", horMargin+70, verMargin+195);
      text("N.America", horMargin+70, verMargin+215);
      text("S.America", horMargin+70, verMargin+235);
      text("etc.", horMargin+70, verMargin+255);
    
    if(normalization == true) normalization();
    else if(normalization == false) resetData();
    if(reorder == true) reorder();
    if(colorApplied == true) colorScheme();
  
}

void setGradient(float x, float y, float w, float h, color c1, color c2){
  //colorMode(HSB, 360, 100, 100);
  for(float i = x; i <= x+w; i++){
    float inter = map(i, x, x+w, 0, 1);
    color c = lerpColor(c1, c2, inter);
    stroke(c);
    line(i, y, i, y+h);
  }
}
//get max and min function
float max2D(float[][] array2D) {
  float max = 0;
  for (int i=0; i<array2D.length; i++) {
    for (int j=0; j<array2D[i].length; j++) {
      if (array2D[i][j] > max) {
        max = array2D[i][j];
      }
    }
  }
  return max;
}

float min2D(float[][] array2D) {
  float max = max2D(array2D);
  float min = max;
  for (int i=0; i<array2D.length; i++) {
    for (int j=0; j<array2D[i].length; j++) {
      if (array2D[i][j] < min) {
        min = array2D[i][j];
      }
    }
  }
  return min;
}
Processing Code - Mountain Type

Code: Select all

//Assignment 1b - Woohun Joo

//font
PFont myFont1;
PFont myFont2;

//Layout Variable
int horSpace = 100;
int verSpace = 130;

//2D matrix variables
Table table;
int numRows, numColumns;
float[][] dataMatrix;
float maxValue, minValue;

//triangle width, height
float triWidth, triHeight;

//year labels
int year = 2009;

//normalization, color, reorder status
boolean normalization = false;
boolean colorApplied = false;
boolean reorder = false;
boolean mouseOver = false;

//month
String [] Month = {"Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec"};
int numMonth = 12;

//array distance
int cellDist = 20;

//screen variables
int screenX, screenY;

void setup() {
  smooth();
  size(1280, 720);
  //size(1920, 1280);
  
  //font
  myFont1 =createFont("Value", 38);
  myFont2 =createFont("Gotham Medium", 38);
  textFont(myFont1);
  textFont(myFont2);
  
  //resize option
  surface.setResizable(true);
  
  //load csv file
  table = loadTable("assignment1b.csv", "header");
  
  //get the number of rows and cols
  numRows = table.getRowCount();
  numColumns = table.getColumnCount();
  
  //dataMatix = Float Array
  //print the number of Rows and Columns 
  dataMatrix = new float[numColumns-2][numRows];
  println("The Number of Rows: " + numRows + "The Number of Columns: " + numColumns);
  
  //get max and min value 
  for(int i=0; i<numColumns-2; i++){
    for(int j=0; j<numRows; j++){
      dataMatrix[i][j] = table.getFloat(j, i+2);
    }
  }

  maxValue = max2D(dataMatrix);
  minValue = min2D(dataMatrix);
  
  println("Max Value " + maxValue);
  println("Min Value " + minValue);

}

//Refresh the canvas every frame
void draw() {  
  //background color
  background(222, 222, 222);
  
  //calculate width and height for each cell
  triWidth = (width-2*horSpace-cellDist*10)/numRows;
  triHeight = (height-2*verSpace)/(numColumns-2);
  
  //drawing 2d matrix on canvas
  for(int i=0; i<numColumns-2; i++){
   float xTrans = 0;
    
    for(int j=0; j<numRows; j++){
      
      //float greyScale = map(dataMatrix[i][j], minValue, maxValue, 255, 0);
      float gColor = map(dataMatrix[i][j], minValue, maxValue, 255, 0);
      float yHeight = map(dataMatrix[i][j], minValue, maxValue, 60, 10);
      
      //triangle coordinate
      float x1, x2, x3;
        x1 = horSpace + triWidth*j - triWidth/2;
        x2 = (horSpace + triWidth*j) + (triWidth/2) - triWidth/4;
        x3 = horSpace + triWidth + (triWidth*j);
      
      if(j%6 == 0 && j>0){
          xTrans += cellDist;
          //println(j);
          //println(xTrans);
          //println(" ");
      }
          
      float y1 = verSpace + (triHeight*(i+1));
      float y2 = verSpace + triHeight*i + yHeight;
      float y3 = verSpace + (triHeight*(i+1));
      
      noStroke();
      strokeJoin(ROUND);
      strokeWeight(2);
      fill(gColor, 200);
      
      ////triangle shape
      pushMatrix();
      translate(xTrans, 0);
      triangle(x1, y1, x2, y2, x3, y3);
      screenX = (int)screenX(x1, y1);
      screenY = (int)screenY(x1, y1);
      popMatrix();
      
      if (abs(mouseX - screenX) < triWidth && abs(mouseX - screenX - triWidth) < triWidth && 
        abs(mouseY - screenY) < triHeight && abs(mouseY - screenY - triHeight) < triHeight) {
        line(20, y2, 500, y2);
        stroke(153);
      }
      
     }        
  }
  //title text
  textAlign(LEFT, BOTTOM);
  fill(0);
  textFont(myFont1);
  textSize(48);
  text("Travel Book Checkouts", horSpace-10, verSpace/2+40);
  
  //year text
  for(int i = 0; i < numColumns-2; i++){
    textAlign(LEFT, BOTTOM);
    textFont(myFont2);
    fill(0);
    textSize(14);
    text(year+i, horSpace-55, verSpace + triHeight + triHeight*i + 2);
  }
  
  //month text
  for(int p = 0; p < numMonth; p++){
    fill(0);
    textFont(myFont1);
    textAlign(LEFT, CENTER);
    textSize(13);
    text(Month[p],p*92+horSpace-8, verSpace+ triHeight*6+18);
  }
  
  //region text
  textAlign(LEFT, BOTTOM);
  fill(0);
  textFont(myFont1);
  textSize(14);
  //text("EUROPE, ASIA, AFRICA, N.AMERICA, S.AMERICA, ETC.", width/2, height-20);
  text("EUROPE, ASIA, AFRICA, N.AMERICA, S.AMERICA, ETC.", horSpace-8, verSpace/2+50);
  
  //color applying
  if(colorApplied == true) colorTheme();
  //reorder
  if(reorder == true) reorder();
  //normalization
  if(normalization == true) normalization();
    else if(normalization == false) resetData();
}
String[] colorPath = {"color2a.jpg"};

PImage colorBar;

//order 
int colorMode = 1;

void colorTheme(){
  colorBar = loadImage(colorPath[colorMode-1]);
  
  for (int i=0; i<numColumns-2; i++) {
    float xTrans = 0;
    for (int j=0; j<numRows; j++) {
      
      //float greyScale = map(dataMatrix[i][j], minValue, maxValue, 255, 0);
      //float gColor = map(dataMatrix[i][j], minValue, maxValue, 255, 0);
      float yHeight = map(dataMatrix[i][j], minValue, maxValue, 55, 5);
      
      //triangle coordinate
      float x1, x2, x3;
        x1 = horSpace + triWidth*j - triWidth/2;
        x2 = (horSpace + triWidth*j) + (triWidth/2) - triWidth/4;
        x3 = horSpace + triWidth + (triWidth*j);
      
      if(j%6 == 0 && j>0){
          xTrans += cellDist;
      }
          
      float y1 = verSpace + (triHeight*(i+1));
      float y2 = verSpace + triHeight*i + yHeight;
      float y3 = verSpace + (triHeight*(i+1));
      
      noStroke();
      strokeJoin(ROUND);
      strokeWeight(2);
      //image
      color c = colorBar.get((int)map(dataMatrix[i][j], minValue, maxValue, 2, colorBar.width-2), colorBar.height/2);
      fill(c, 220);
      pushMatrix();
      translate(xTrans, 0);
      //println(xTrans);
      triangle(x1, y1, x2, y2, x3, y3);
      popMatrix();
    }
  }
  
}
//get max and min function
float max2D(float[][] array2D) {
  float max = 0;
  for (int i=0; i<array2D.length; i++) {
    for (int j=0; j<array2D[i].length; j++) {
      if (array2D[i][j] > max) {
        max = array2D[i][j];
      }
    }
  }
  return max;
}

float min2D(float[][] array2D) {
  float max = max2D(array2D);
  float min = max;
  for (int i=0; i<array2D.length; i++) {
    for (int j=0; j<array2D[i].length; j++) {
      if (array2D[i][j] < min) {
        min = array2D[i][j];
      }
    }
  }
  return min;
}

csv file and code that created the image
Attachments
assignment1b_woohun.csv
(2.19 KiB) Downloaded 139 times
Last edited by joo on Fri Feb 05, 2016 12:55 am, edited 10 times in total.

Post Reply