For this project, I decided to continue on the route that I have been looking into for my previous projects: how different genres react to different days of the week and times of days. I implemented functions that are able to sort the times for each individual genre by either a) how popular that time is or b) how strong of a deviation does that time have depending on the day.
I was actually able to modify my query so I could get data more easily, but at the moment I'm not sure how many genres I want to include, since I want to have individual time data for each genre.
Soon I was able to find a better color scheme that would look more similar to a heat mapping however I was having an issue in that it was hard to tell the relevance of any of the color. What's dense? what's sparse? everything seemed equally important and this simply was not the case.
Finally, I realized that by making the background color the same color as my least important color I was able to achieve an effect where the least important pieces of data fade into the background, while the most important information appears to burn as a red hot spot.
Code: Select all
/*
class demo on Jan 15, 2015
By Mohit Hingorani
if you have any questons regarding the code please email me at mohit@mat.ucsb.edu
we will be going over on how to import any table into processing and arrays again in next class
in this demo we are importing a simple integer table
This demo creates a two-dimensional grid where each cell has 3 values: a verticallocation, a horizontal location,
and a cell colorvalue. All the values are stored in a csv file which has 11 columns of integers acquired through
a MySQL quary in the SPL database. There are 31rows of data representing a query which has looked for data for 31 days
COMMENTS: any line that begins with // or is in-between /* */
/* is commented out and the program does not see it, only humans.
------------
Variables include
int = are integers such as, 5, 89, 594803
float = are decimal based numbers such as 5.45, 1489.3482
string = "life", "overthetop" strings are a sequence of characters and alwasy in double quotes
int []array = {34,65,2} is a 1 dimensional array, a list of data separated by commas
int[][]array = a 2 dimensional array as we use in this demo
*/
/* initializing a variable outside of a function makes it global. The variable is active and available throughtout the programe
Variables initialized inside a function are called local variables and lose their values once the program exits the function
*/
float colormap_hcl_1[][] = {{ 0.1804, 0.0824, 0.0510 },
{ 0.2431, 0.1255, 0.0784 },
{ 0.3059, 0.1686, 0.1020 },
{ 0.3725, 0.2157, 0.1255 },
{ 0.4392, 0.2667, 0.1490 },
{ 0.5020, 0.3176, 0.1686 },
{ 0.5647, 0.3765, 0.1882 },
{ 0.6235, 0.4314, 0.2078 },
{ 0.6824, 0.4941, 0.2314 },
{ 0.7412, 0.5569, 0.2510 },
{ 0.7922, 0.6235, 0.2745 },
{ 0.8431, 0.6941, 0.2980 },
{ 0.8863, 0.7647, 0.3255 },
{ 0.9294, 0.8353, 0.3569 },
{ 0.9686, 0.9098, 0.3922 }};
int colorInts[] = {
#C71C2E,#C0192E,#B9152D,#B1122D,#AA0F2C,#A30C2C,#89216C,#941560,#9B0754,#A30039,#A30C2C,#89216C,#812B77,#753481,#673D8B,#554593,#3D4C99,#1B2A59,#213165,#273772,#2E3E7E,#36458C,#3D4C99};
import java.util.Collections;
import java.lang.Math;
int colorLength = colormap_hcl_1.length;
int radius =100;
int xPosition = 20;
// we added these variables in class on tuesday
int cellWidth = 20;
int cellHeight = 50;
char AFLAG = 'C';
int rowMargin =180;
int columnMargin = 80;
/*Creating a two-dimensional array we are calling "Data Matrix", and initialize its values to null.
A two-dimensional array is really nothing more than an array of arrays (a three-dimensional array
is an array of arrays of arrays).
*/
float [][] standardDevMatrix = null;
float [][] averageMatrix = null;
// a variable to keep track of the MaxCount
float maxCount ;
float maxCount2;
//variables to represent the vertical and horizontal locations of the grid we will draw
int numRows, numColumns;
// crating a font of size 16 and helvetica
PFont font = createFont( "Helvetica", 24, true);
// creating a table. Table objects store data with multiple rows and columns, much like in a traditional spreadsheet
Table myTable;
Table avTable;
float[][] averages;
int[][] avIndeces;
float[][] stDevs;
int[][] stDevIndeces;
String[] a= new String[7];
void setup()
{
//setting up a screen size 640*360
size( 1280,800);
//colorMode(HSB);
// set background to white
background(0,2,2);
//activate smoothing anti-aliasing functions between pixels
smooth();
// set framerate to 10 per second. NOrmal video is 30 or 60
frameRate( 10);
//Print out the text in the command prompt once the program reaches here
println( " setup done");
a[0]="Su";
a[1]="M";
a[2]="T";
a[3]="W";
a[4]="Th";
a[5]="F";
a[6]="Sa";
//in this step we copy the data from the csv file into our own table.
//we use header flag to tell processing to ignore the first line of the csv file as it contains the names of the columns
myTable = loadTable( "onemonthmindacbkjcbk.csv");
avTable = loadTable("averageData.csv");
// assign these variables to contain the number of rows and columns from myTable
numRows = avTable.getRowCount();
numColumns = avTable.getColumnCount();
// initialize the 2D array with number of rows and columns
standardDevMatrix = new float[numRows][numColumns];
averageMatrix = new float[numRows][numColumns];
averages = new float[4][numColumns];
avIndeces = new int[4][numColumns];
stDevs = new float[4][numColumns];
stDevIndeces = new int[4][numColumns];
// copy everything from table into a 2D array
// use two for loops to iterate over both rows and columns
// this step is not necessary, but helps in matrix manipulations which we will be doing later
for ( int i = 0 ; i< numRows ; i++) // a for loop where i is set to 0 and increments all the way to numRows by 1
{
for ( int j = 0 ; j< numColumns ; j++)// a for loop where j is set to 0 and increments all the way to numColumns by 1
{
standardDevMatrix[i][j] = myTable.getFloat(i,j); // copying the table integer value at mytable (i,j) position into the standardDevMatrix
stDevs[i/7][j] += standardDevMatrix[i][j];
}
}
println("original input data");
for ( int i = 0 ; i< numRows ; i++) // a for loop where i is set to 0 and increments all the way to numRows by 1
{
for ( int j = 0 ; j< numColumns ; j++)// a for loop where j is set to 0 and increments all the way to numColumns by 1
{
averageMatrix[i][j] = avTable.getFloat(i,j); // copying the table integer value at mytable (i,j) position into the standardDevMatrix
print(avTable.getFloat(i,j) + " ");
averages[i/7][j] += averageMatrix[i][j];
}
println("");
}
println("\n\n");
println("after input");
for(int i = 0; i<numRows; i++){
for ( int j = 0 ; j< numColumns ; j++) {
print(averageMatrix[i][j] + " ");
}
println("");
}
for(int i = 0; i<4; i++){
for ( int j = 0 ; j< numColumns ; j++) {
print(averages[i][j] + " ");
}
println("");
}
for(int i = 0; i<4; i++){
for ( int j = 0 ; j< numColumns ; j++) {
avIndeces[i][j] = j;
stDevIndeces[i][j]= j;
}
}
println("avIndeces");
for(int i = 0; i<4; i++){
for(int j = 0; j<numColumns; j++){
print(avIndeces[i][j] +" ");
}
println();
}
for(int i = 0; i<4; i++){
mySort(averages[i], avIndeces[i]);
mySort(stDevs[i], stDevIndeces[i]);
}
println("avIndeces");
for(int i = 0; i<4; i++){
for(int j = 0; j<numColumns; j++){
print(avIndeces[i][j] +" ");
}
println();
}
//
}
//The Draw() processing function repeats itselfs continuously at 60 frames per second unless the frameRate is changed
void draw()
{
// refresh background every frame
background(200);
int addedWeight = 0;
//creating the cells sequentially
// this where the actual drawing of data happens
// we run two nested loops, one for rows and the other for columns , we go through each cell to retrive its value
// and fill the color of the cell accordingly
for(int k = 0; k < 4; k++){
for ( int i = 0 ; i<numRows/4 ; i++)
{
if(i%7==0 && i!=0){
// fill(200);
// rect(rowMargin+ i * cellWidth ,columnMargin +j * cellHeight ,cellWidth, cellHeight ); // draw the rectange of size 15,25 at the appropriate position, the position of the cell depends on its value in the table position (i,j)
addedWeight+=3;
// println("calling addweight");
}
for ( int j = 0 ; j < numColumns ; j++) // -1 as the last column is empty, our standardDevMatrix is smaller than the table by one column
{
stroke(128); // turn color of borders to gray
strokeWeight(0.5); // make the borders thinner
colorMode(HSB); // switch color mode to HSB space
if(AFLAG=='C'){
colorMode(RGB); //switch colorspace back to RGB
int r = (int)Math.floor(standardDevMatrix[i+k*7][j]*(colorLength-1));
int g = (int)Math.floor(averageMatrix[i+k*7][j]*(colorLength-1));
int b = (int)Math.floor(standardDevMatrix[i+k*7][j]*(colorLength-1));
// println("hue brightness: " + 255*colormap_hcl_1[b][2]);
fill(colorInts[19 - (int)(averageMatrix[i+k*7][j]*19)], 100 +155*(2*colormap_hcl_1[b][2]) ); //
rect(rowMargin+ (i + addedWeight+k*10)*cellWidth ,columnMargin +j * cellHeight ,cellWidth, cellHeight ); // draw the rectange of size 15,25 at the appropriate position, the position of the cell depends on its value in the table position (i,j)
}
else if(AFLAG == 'A'){
println("standard dev = " + standardDevMatrix[i][avIndeces[k][j]]);
println("average = " + averageMatrix[i][j]);
colorMode(RGB); //switch colorspace back to RGB
int r = (int)Math.floor(standardDevMatrix[i+k*7][avIndeces[k][j]]*(colorLength-1));
int g = (int)Math.floor(averageMatrix[i+k*7][avIndeces[k][j]]*(colorLength-1));
int b = (int)Math.floor(standardDevMatrix[i+k*7][avIndeces[k][j]]*(colorLength-1));
// fill(255*colormap_hcl_1[r][0] , 255*colormap_hcl_1[g][1], 100 +155*(2*colormap_hcl_1[b][2]) );
fill(colorInts[19 - (int)(averageMatrix[i+k*7][avIndeces[k][j]]*19)], 100 +155*(2*colormap_hcl_1[b][2]) ); //
colorMode(RGB); //switch colorspace back to RGB
rect(rowMargin+ (i + addedWeight+k*10)*cellWidth ,columnMargin +j * cellHeight ,cellWidth, cellHeight ); // draw the rectange of size 15,25 at the appropriate position, the position of the cell depends on its value in the table position (i,j)
}
else{
colorMode(RGB); //switch colorspace back to RGB
int r = (int)Math.floor(standardDevMatrix[i+k*7][stDevIndeces[k][j]]*(colorLength-1));
int g = (int)Math.floor(averageMatrix[i+k*7][stDevIndeces[k][j]]*(colorLength-1));
int b = (int)Math.floor(standardDevMatrix[i+k*7][stDevIndeces[k][j]]*(colorLength-1));
// fill(255*colormap_hcl_1[r][0] , 255*colormap_hcl_1[g][1], 100 +155*(2*colormap_hcl_1[b][2]) ); //
fill(colorInts[19 - (int)(averageMatrix[i+k*7][stDevIndeces[k][j]]*19)], 100 +155*(2*colormap_hcl_1[b][2]) ); //
rect(rowMargin+ (i + addedWeight+k*10)*cellWidth ,columnMargin +j * cellHeight ,cellWidth, cellHeight ); // draw the rectange of size 15,25 at the appropriate position, the position of the cell depends on its value in the table position (i,j)
}
textAlign(CENTER ,CENTER ); // align text to CENTER
fill( 100);
text(a[i%7], rowMargin+ (i + addedWeight)* cellWidth+cellWidth/2 , columnMargin*.9);
}
}
}
//the % is called modulo. It finds the remainder after division. So 21% 20 returns 1, 21%12 returns 7, 21%21 returns 0
textAlign(CENTER ,CENTER ); // align text to CENTER
fill( 0); // make color of text to light gray
// for(int i = 0; i < numColumns; i++)
// text(a[i%7], rowMargin+ (i + addedWeight)* cellWidth , columnMargin*.9);
for(int j = 0; j<4; j++){
for ( int i = 0 ; i<numColumns ;i++){
if(AFLAG=='C'){
text( i+8 + ":00" , rowMargin-cellWidth +j*10*cellWidth , columnMargin+cellHeight/2+i*cellHeight);
}
else if(AFLAG == 'A'){
text( avIndeces[j][i]+8 + ":00" , rowMargin-cellWidth +j*10*cellWidth , columnMargin+cellHeight/2+i*cellHeight);
}
else{
text( stDevIndeces[j][i]+8 + ":00" , rowMargin-cellWidth +j*10*cellWidth , columnMargin+cellHeight/2+i*cellHeight);
}
}
}
//
// text( "Arts" , rowMargin * 0.75, columnMargin + cellHeight/2 );
// text( "Astronomy" , rowMargin * 0.75, columnMargin + cellHeight/2 + cellHeight);
// text( "Home+Family" , rowMargin * 0.75, columnMargin + cellHeight/2 + 2 * cellHeight);
// text( "Literature" , rowMargin * 0.75, columnMargin + cellHeight/2 + 3 * cellHeight);
text( "Arts" , rowMargin + cellWidth*3.5 , columnMargin/2);
text("Astronomy" , rowMargin + cellWidth*3.5 + cellWidth*10, columnMargin/2);
text("Home+Family" , rowMargin + cellWidth*3.5 + cellWidth*20, columnMargin/2);
text("Literature" , rowMargin + cellWidth*3.5 + cellWidth*30, columnMargin/2);
// repeat the process for day numbers
// for ( int i = 1 ; i<=13 ;i++)
// text( i+7 + ":00" , rowMargin - cellWidth/2 + i * cellWidth , height- 1.25 * columnMargin);
//
if ( frameCount % 20 ==0)
{
// println( "draw called " + frameCount ); // here we are printing out the frameCount ( how many frames have been drawn so far)
}
}
int[] mySort(float[] a, int[] indeces){
int j;
boolean flag = true; // set flag to true to begin first pass
int temp; //holding variable
while ( flag )
{
flag= false; //set flag to false awaiting a possible swap
for( j=0; j < a.length -1; j++ )
{
if ( a[ j ] < a[j+1] ) // change to > for ascending sort
{
// temp = num[ j ]; //swap elements
// num[ j ] = num[ j+1 ];
// num[ j+1 ] = temp;
swap(a,indeces, j, j+1);
flag = true; //shows a swap occurred
}
}
}
return indeces;
}
void swap(float[] a, int[] ind, int b, int c){
int indTmp;
float tmp;
tmp = a[b];
indTmp = ind[b];
a[b] = a[c];
ind[b]=ind[c];
a[c] = tmp;
ind[c] = indTmp;
}