navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

Projects for Interactive Data Visualization with Processing

Projects for Interactive Data Visualization with Processing

with Barton Poulson

 


Creating a well-crafted data visualization is a hands-on process. Challenge yourself with this series of real-world data visualization scenarios in Processing, an open-source drawing and development environment. Barton Poulson, author of the companion Interactive Data Visualization with Processing course, reinforces core concepts with mini-projects that help you practice drawing and interacting with data. A comprehensive challenge at the end of the course shows how to take data from a spreadsheet to a full-fledged online, interactive experience.

show more

author
Barton Poulson
subject
Developer, Programming Languages
software
Processing
level
Intermediate
duration
1h 41m
released
Apr 22, 2013

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Overview
00:00 (music playing)
00:04 Hi, I'm Bart Poulson. This is a companion course to interactive
00:07 data visualization with processing, here in the Lynda.com online training library.
00:13 The challenges in this course are divided into a few sections.
00:16 Each building on a few chapters from the processing course.
00:20 At the end of this series of videos, you'll find a large project that
00:22 incorporates a wide array of the concepts introduced throughout the processing course.
00:27 Let's get started.
00:28
Collapse this transcript
Using the exercise files
00:00 This course includes several videos called Challenges.
00:03 Challenges are quick activities that give you a hands on opportunity to practice
00:07 and master what you're learning. I'll start each challenge by describing
00:12 your core objectives for the activity. If the challenge involves using any
00:16 sample files, I'll tell you where to find them.
00:18 I'll also give you a rough estimate of how much time it took me to complete the challenge.
00:24 When you've completed a challenge, make sure to click the matching solution video.
00:29 In each solution, I'll show you how I've solved the challenge, and give you some
00:33 of my thinking along the way. Again, this is an opportunity for you to
00:37 master what you've been learning. Enjoy.
00:41
Collapse this transcript
1. Section Challenges
Chapter 3 challenge: Drawing with Processing
00:00 This is the Chapter 3 challenge for projects for Interactive Data
00:04 Visualization with Processing. For this challenge, I want you to imagine
00:08 you've been contracted by the manager of four manufacturing projects.
00:14 And she wants you to create a way to visualize the progress of the projects on
00:17 two dimensions, such as the percentage of the engineering plans that's been completed.
00:22 And the percentage of marketing plans that have been completed.
00:26 And so, the idea here is that you have project A and B and C and D.
00:31 And then for each one of them, I've specified a rough amount that has to be done.
00:36 So for project A, engineering is nearly complete.
00:40 And marketing is nearly complete. For project B, however, engineering is
00:45 only about a third and marketing is just beginning.
00:49 For project C, engineering is about 2 3rd and marketing is about three quarters.
00:55 For project D, engineering is just beginning but marketing is about halfway done.
01:01 Now for this exercise, you don't need to use precise percentages and you don't
01:04 need to label the graphs. We just need the pictures themselves.
01:08 Try to create something that's asthetically pleasing, that's
01:11 interesting, and that's informative. You should allow yourself about 20
01:15 minutes for this exercise, and then we'll meet again to see one way to resolve this
01:18 and compare it with your own.
01:21
Collapse this transcript
Chapter 3 solution: Drawing with Processing
00:00 In the challenge we gave for Chapter 3, I asked you to create a visualization of
00:05 four projects, and the percentage completion on each of two elements of
00:09 those projects. So fundamentally, what you're doing is
00:14 showing two percentages or proportions on four items.
00:17 Now, for my chart, I chose to go with circular charts.
00:22 Now I understand that there are often problems with pie charts.
00:26 But I feel in terms of progress towards completion, these worked well.
00:29 And so what I have is four circles that represent each of the four projects.
00:35 And for each one of them, I've got a dark red circle the represents the entire thing.
00:41 And then I've got a very thick line that comes around an arc that represents
00:45 progress on one aspect of the project. And then the pie in the middle represents
00:50 progress on the other aspect of the project.
00:53 And when both of them get back up to 12 o'clock, the project's totally done.
00:57 Now in this example, I chose to go with a variation on the pie charts.
01:01 Another obvious choice would have been to use a linear measurements, like a bar or
01:05 a column chart. That would work very well for this
01:08 situation also. I chose to go with the pie charts because
01:10 I thought it was more interesting in this situation, and it looked more like the
01:14 gauges coming around, to get to completion or a clock.
01:18 And I felt that that communicated completion or the sense of a deadline or
01:22 progress pretty effectively. Now what we're going to do is we're
01:25 going to switch over to code and I'm going to show you how I created this
01:28 particular chart. I began by creating a window that was
01:34 1,000 pixels wide and 300 pixels tall. And then I created a variable for y
01:39 because all of these circles and arcs are on the same top to bottom axis, and so I
01:43 just needed a single y variable. And I wanted to center them so I used the
01:49 height of the window that's a built in processing variable.
01:53 Once you've specified the size of the window, then you can refer back to height
01:55 and width. And I just wanted to do height divided by
01:59 two to put them right in the center of the top and bottom.
02:02 Also, I created a second variable here, d for diameter.
02:06 And that's for the diameter that I used for the circles and the arcs all the way through.
02:10 And by setting up these variables up here, I saved myself a lot of repitition
02:14 later on. Then I turn on smooth, which is for the
02:17 anti-aliasing, makes shapes like circles and arcs appear a little bit better.
02:23 And then I pick a background color. Now, I actually got a palette of colors
02:26 that I adapted from the Kuler site for Adobe, that's kuler.adobe.com, where I
02:31 looked at some palettes. And then I made some changes for what I
02:35 felt would be most appropriate. And from those I got the hex codes that I
02:39 put in here. So this background is the tan color.
02:43 Then what I did is I had to create the red circles, I had to create the pies
02:46 that were within the circles, and then I had to create the arcs on the outline of
02:49 the circle. Now because of the way processing works,
02:54 I wanted to do these in a particular order.
02:57 The thin circles, that would seem like an obvious thing to do first, but they got a
03:00 little overlapped with the pies and so I put them second.
03:04 So I started with the pies in the middle. First I turn off the outlines, I only
03:09 wanted to fill. Then I specified the fill and then I used
03:13 the arc command. And what these have is an x and y position.
03:18 So I've put each one of these 200 pixels apart.So the first one is centered 200
03:22 pixels from the left margin. The next one's 400, the next one's 600,
03:27 the next one's 800. Then the next one is, you see the y is
03:31 there, all at exactly the same up and down position, y is halfway down.
03:37 And then I have d, that's the diameter, you have to specify a set (INAUDIBLE) for
03:40 the width and height for the arc. And if you want them to be the same, then
03:44 you use the same value, which is one of the reasons I'm using d here.
03:48 Now arcs, you have to specify the beginning and the end of them in radians.
03:52 It's a little unusual but that's a unit of pie.
03:56 It starts at zero and it goes to two pie. Two times pie where one times pie is
04:01 halfway around. Two times pie is all the way around.
04:05 Now another peculiar thing is the arc start as 3 o'clock and I wanted them to
04:08 start at 12 o'clock. So what I had to do was I had to set the
04:12 beginning of each of these arcs at pie times minus one half.
04:17 So as 90 degrees backing up its half a pie negative to start.
04:21 And then the next one is pie times a certain value.
04:24 It needs to be less than two and actually so it does not rely up on the top it
04:28 wanted to be less than 1.5 and I just picked values that seem to say this is
04:31 nearly done, this is just, you know, about a third, this is half way, and so on.
04:38 I'm just eyeballing those ones. And so, they all start at 12 o'clock,
04:43 which in radians is pi times negative 0.05, and they go to a certain extent.
04:49 So those are the pis that are within the circles first.
04:52 Then I'm going to scroll down here a little bit.
04:55 The next thing I do is I draw the circles that go all the way around.
05:00 They just serve as a container, as a nice boarder for what I have.
05:04 It's sort of a dark red. And, so I have the stroke and that's the
05:07 color of it. That's a dark red.
05:09 That the HEX code. And, then I made strokeweight to make
05:12 them three pixels thick and I turned off the fill because, otherwise, they would
05:15 be solid circles. I just want the outline.
05:19 And then I use the Ellipse command. And I have them centered on the same
05:22 places as the arch above. At 200 pixels over 400, 600, 800 pixels
05:26 over from the left edge. They all have the same y coordinate.
05:32 They're half way down. And they have the same diameter.
05:35 And then finally, I want to put the thick arc on the perimeter, which measures
05:39 progress on another one of the dimensions.
05:43 I change the color to stroke, and then I use a very thick stroke weight.
05:48 I made it 12 pixels thick. That's when I had to just kind of bounce
05:52 around to see what worked well. Also, by default, the strokes have
05:56 rounded edges, which are kind of pretty but when you're trying to get sort of a
05:59 precise sense of what the value is, that can be hard to read.
06:04 And so I put in Stroke Cap Square, and that cuts 'em off with square ends on the arc.
06:09 And then I used the same arc command that I used before.
06:13 I use arc and I had to specify the x position which is pixels from the left
06:17 margin, 200, 400, 600, 800. They are centered on the same y position
06:22 as everything else have the same diameter as everything else and then I start them
06:26 at 12 'o clock and that's pi times negative 0.5.
06:31 And then I pick a value that seems to communicate approximately.
06:35 Almost done, just beginning, and so on. And when I Iayer those on top of each
06:40 other, I get my finished sketch. (SOUND) Which, again, looks like this.
06:48 So first, I drew the pies in the middle. And the, sort of, the khaki green.
06:52 Then I put on the red border around it to give it sort of an enclosure, like it's a gauge.
07:00 And then I put the very thick arc on the outline to communicate the second
07:03 dimension that I'm showing. And that's one way to communicate
07:08 percentages on two dimensions for each of four objects.
07:13 And you could have done something very different, for instance, with lines, but
07:16 I thought this would be one pleasing and informative method that had an analogy to
07:20 gauges and completion.
07:23
Collapse this transcript
Chapter 6 challenge: Drawing with data I
00:00 For the second challenge, we're going to get a little more elaborate.
00:03 We've talked about variables and arrays and for loops.
00:07 And some other constructs that we can use in creating our graphics.
00:11 So challenge two is drawing with data one.
00:14 Here's the scenario. Imagine that you've been commissioned to
00:17 create a live financial tracking graph. And you'll need to track 100 fictional stocks.
00:23 On both their market value and their volatility, which are updated once per second.
00:27 So, you have 100 data points. And you have two dimensions for each one.
00:32 When a stock is high on both market value and volatility, that places it in a
00:36 critical quadrant. And you need to make it stand out, so
00:40 appropriate action can be taken. It needs to be highlighted in some way.
00:44 In addition, put some text on the graph that counts how many stocks are in the
00:48 critical quadrant at any moment. Now, for purposes of this exercise the
00:53 stocks are fictional. The market value and volatility are both
00:57 random numbers that change randomly over time.
01:01 You don't need to label the stocks, but you do need to highlight them somehow
01:04 when they're above the criterion values that you choose.
01:07
Collapse this transcript
Chapter 6 solution: Drawing with data I
00:00 Our second challenge for data visualization involved creating a chart
00:04 to track the performance of 100 fictional stocks, on both market value and volatility.
00:11 The goal was to create a chart so that when stocks went into a critical
00:14 quadrant, that is where they were high on market value and high on volatility.
00:20 Their data points would get highlighted. In addition, there would be a counter
00:24 that would actually say and text how many data points there were in that critical quadrant.
00:30 Now there's a lot of room for creativity and different solutions in this one.
00:34 Let me show you my solution. I've created a simple square drawing that
00:38 has lines bisecting each dimension. And I've randomly placed one hundred dots.
00:45 And so, about 25% of them start in the upper right quadrant.
00:50 I also have them randomly incrementing once per second.
00:54 And I've set up the increment, incidentally, so that everything is
00:57 gradually moving to the upper right corner.
01:01 So you'll see the numbers increasing. And at the top I have some (UNKNOWN) that
01:04 reach critical stocks, and it's counting how many were there.
01:06 Let me show you how I created this one. (SOUND).
01:09 The first thing I did was create a variable that indicated the number of
01:14 points to draw. I also created a variable d to say the
01:19 diameter of the points because these are actually being drawn with point and not
01:22 ellipse, and this is going to be used for the strokeweight.
01:27 Also, I created a variable m that I used to limit the movement from one frame to another.
01:33 You'll see where that comes in a little bit later.
01:35 Then I create two empty arrays. One is to hold the x positions of the
01:39 dots, and the other one is to hold the y positions.
01:43 Then I have a color palette. I chose hexcodes and put them in here.
01:48 And then finally, I create a variable called CritN, and that's a variable that
01:51 is used to count how many points are in the critical quadrant.
01:56 In the next block of set up, I have a 600 by 600 window, I set frame rate to 1
01:59 frame per second. And then, I use a four loop to put random
02:04 numbers into the arrays for the x and the y positions.
02:08 And I set it so that it can be anywhere between negative 100 and positive 100 on
02:12 both, which is why it looks kind of like a square data set when it first opens up.
02:18 Then I scroll down to draw. And one of the things I do, is I thought
02:22 it might be a little easier to do some of this, if I translated, so that the origin
02:26 point, the (0,0), was in the middle of the chart.
02:31 So that's the very first thing that happens in draw.
02:34 And you need to put that in draw and you need to have it there because it's sort
02:37 of undoes the translation at the end of every one, so you need to have it repeated.
02:41 And then I put the background color. Then I initialize my variable critN.
02:47 I need it to start at zero every time it goes through a draw because it's counting
02:50 and updating the number every time. After that, I have some code that draws
02:56 lines to divide the window into quadrants.
03:01 I set strokeweight to 1 pixel. I pick the number from the palette to be
03:04 used for the color of the strokes. And then, I draw the two lines using the
03:09 coordinates for the translated grid system.
03:12 Beneath that, I have a for loop, and what that does is it goes through every point
03:16 in the x and the y arrays. And it first determines whether they're
03:21 in the critical quadrant. It said if x is greater than zero, that
03:25 puts it to the right of the midpoint and if y is less than zero, because remember,
03:28 you're counting from the top of the box down and so if it's above the midpoint,
03:32 it's going to be a negative number. And then what I say is, if it's in that
03:39 critical quadrant, then take its strokeweight, make it bigger, twice as
03:43 big, and use a particular color as the index number two in the palette.
03:48 And then, for the critN, that's the variable that is counting how many dots
03:52 there are in this quadrant, add one on. Increment it by one every time it finds a
03:56 dot that falls in there. Now that's my if loop.
04:00 I then have an else. And say, for everything else, so
04:03 basically anything that is not in the critical quadrant, give it the regular
04:06 strokeweight, and give it a different color on the pallet.
04:11 And then once that's done, those loops set the size and the color of the points,
04:15 then I draw the points. And then I finish off my for loop by
04:19 incrementing, providing a random increment for each of the coordinates.
04:24 Now you'll notice here, I have the variable m.
04:27 That's what I use to limit the movement, and I declared it and initialized it at
04:31 the top of the sketch. And I modified it a little bit because II
04:35 want things to not just always be centered in the middle but to move a
04:38 little bit. And so by multiplying one of the limits
04:42 by 0.8, I am actually forcing everything to move to the critical quadrant.
04:47 If you wait long enough, everything will end up in there.
04:50 I know that's not how real life works but it, I just wanted to have the critical
04:54 number changing over time. The last thing I have here is the text.
05:00 And you have to specify fill. That's how you change the color of text.
05:04 And so I'm using index number two in the palette.
05:07 And then I have the text that says critical stocks, then I have a space,
05:10 then I close the quotes. And then I put plus critN, so it's
05:13 actually going to insert the variable value there.
05:16 And then I position it. And that's how I make the sketch.
05:19 And lets take a quick look one more time. (SOUND).
05:22 So it's a pretty simple sketch. It's a nice color scheme, it's
05:28 informative, it's very easy to see which ones are in the critical region.
05:32 It's nice to have the counting variable as well as the back up.
05:36 And if I were to expand on this one, I would make it so that you could freeze
05:38 the chart so that you could identify individual points, maybe see which ones
05:42 just crossed over the lines one way or the other.
05:46 But those are other options. Right now, this is one that meets the
05:49 requirements of the assignment, and hopefully you came up with something that
05:52 also was creative, was interesting and informative in helping you to understand,
05:56 for instance, the movement of points and the movement of data over time.
06:01
Collapse this transcript
Chapter 10 challenge: Drawing with data II
00:00 In the third challenge we're going to be using some of the new skills we've
00:03 learned, which include interactivity with the mouse and the keyboard.
00:08 We've learned how to create functions in objects and we've learned how to
00:11 incorporate data from both external and embedded sources into our drawings.
00:17 So, for challenge three, Drawing with Data 2, imagine that you've been asked to
00:20 create an interactive graphic that displays data on two kinds of trees.
00:26 We're doing just two to keep it simple for now.
00:28 Your sketch should do the following. First, display images of leaves from each tree.
00:33 Second, highlight the images when the mouse hovers over them.
00:39 Third, display a popup data box when the leaves are clicked.
00:43 And fourth, I want you to just create the sketch using arrays and four loops so
00:47 that, while we only have two in this particular one, it would be easy to add
00:51 additional leaves and information at a future point.
00:57 Use the images provided as well as the data.
00:59 Now, as a note, the data provided in a CSV file from a spreadsheet, and that's
01:03 in a tabular format. In the current beta version of processing
01:07 2.0, the table function which is a new thing, isn't working completely right,
01:11 and so the data will need to be entered manually into the sketch.
01:16 However, that table function would simply enter the data into a raise like you
01:19 would do manually. So, that's really just one step that's
01:23 missing and all the rest would be the same.
01:26 Again, interactive display of leaves with data that pops up when they're clicked on.
01:31 Give yourself about half an hour to work on this sketch.
01:35 Best of luck!
01:35
Collapse this transcript
Chapter 10 solution: Drawing with data II
00:00 The assignment for the third challenge was to create an interactive graphic that
00:04 showed images of two kinds of leaves and provided information when people clicked
00:09 on the leaves. Now there's a lot of different ways to do this.
00:15 Let me show you the way that I worked on this one in particular.
00:18 The first thing I did was I created a variable n that said how many items I was
00:22 going to display. Right now it only has two.
00:25 A later one could have ten or 50 or 200. Then when I created was an array called x
00:32 for the x position of the leaves. The x coordinates of each one.
00:37 These are entered manually. You would also be able to read these from
00:39 a spreadsheet if you needed to or use a folio to implement them.
00:44 After that I have a y variable for the positions, then I have a variable called
00:48 r for radius because I'm going to be creating, circle gradients that go behind
00:51 the leaves to highlight them. Then I have two other variables that are
00:58 T for tint and TA for Tinting Alpha. Those are things that I use to put a
01:03 little grey tint over the leaves when they are not selected.
01:07 I'll show you how that works in a minute. Next is the data for the trees.
01:10 As I mentioned, processing 2.0 is currently in beta and the new table class
01:14 isn't yet able to read the data straight from the csv file.
01:19 It will have that functionality soon but for right now.
01:22 You just look at the csv file and enter the information manually into arrays.
01:27 And again, that's what the table function would be doing for you.
01:31 You would create the arrays, you would have a foward loop and it would get the
01:33 information out of the csv. And put it into arrays.
01:36 So this is just one step that you need to do manually.
01:39 The rest of it would be the same. First, I have an array for the images.
01:43 That's a pimage, that's a processing image.
01:46 And it's a blank array, where I simply created two spaces.
01:49 It's called images. Next I have a string array called Trees.
01:54 And that's the name of the trees. Then I have another string array called
01:58 Inames which is the image names for the files with the dot png extension.
02:03 Don't forget these are case sensitive. So you need to have the capitalization
02:07 exactly the way it appears in the files. After that as another string array for
02:11 the genus of the trees. Again in quotes because these are strings.
02:17 After that an integer array that holds the number of species of each kind of tree.
02:23 And then finally I have one more string that I call uses where I just put down
02:27 some things that people use these trees for.
02:31 Now for the sketch itself, I create a window that is 600 pixels wide, 200
02:35 pixels tall. I turn on the anti-aliasing with smooth
02:38 and I'm going to be placing images by their center.
02:42 That way when I do things, like the hovering or I do a gradient, they can all
02:46 be positioned using the same coordinate system.
02:50 After that, I have a four loop that I use to load the images into the image array.
02:56 That's a PImage array, so, there's only two items right now, but it's going to go
03:00 through and take the names from the inames array and use those to load the
03:04 images into the images array. Next is the Drawloop.
03:11 Because this is an interactive graphic, and things are going to be changing, I
03:14 need to have background in this one. So I have a white background.
03:19 Then, I have a fill for the text. I'm going to put some instructions on the bottom.
03:23 The fill is 180. It's a medium grey.
03:26 And it says click on the leaf for more information.
03:28 And I place it in the bottom left of the sketch.
03:31 After that, I create a for loop that positions all of the information for each leaf.
03:36 Let me scroll down a little bit more, and what you see here is it starts with the
03:39 for loop, this is int i, so it goes from zero up to n.
03:43 n in this case is just 2, so it's only going to do this twice.
03:47 But again, thing thing about a for loop is you could do it a thousand times
03:49 without having any additional code. What I'm doing first is I'm going to add
03:54 a tent. Now, a tent is something that you can use
03:56 to change the appearance of an image. And what I want to do is take the
04:00 pictures of the leaves and make them gray.
04:03 And so, they're obviously not highlighted.
04:07 And the way you do this is by choosing a color of tint, and I chose a gray.
04:11 T is a variable that I defined up earlier, used 180.
04:15 And then TA is an alpha. When you have two arguments and tent or
04:18 stroke or whatever, it means that you have a grayscale number and an alpha
04:22 transparency number. And that's going to lighten the things up.
04:27 So, they're obviously there, they're identifiable, but they're not selected.
04:32 Then what I have inside this for-loop is an if statement.
04:36 And it's looking at the distance between the center of the object.
04:40 Remember these things are positioned by the x and the y, and that's the center of
04:43 the image. And then I have the mouse x and y, and as
04:47 long as that is within a certain range, the r is for radius, then it will trigger
04:51 something called the gradient circle. Now that's a function that I created for
04:57 this sketch. I'll show it to you in just a moment.
05:00 But it's a circle that' a gradient. It goes from light to dark.
05:03 Light on the outside to dark in the middle.
05:05 And I position it with the x position from the array of axis.
05:10 The y and the r is the radius the size of the circle.
05:13 Also I then have a function no tenth. Now I added ten just a couple of lines ago.
05:18 But, if the mouse is hovering over an image, I want to remove the tent.
05:23 And because I have that subsequent of the first one, even though it turned the tint
05:26 on earlier, it now turns it back off. Then I place the image of the leaf.
05:31 Again, I do that with an array function. So, it goes to the array of images called Images.
05:37 And then it positions it with the x coordinate from the array, and then the y
05:40 coordinate with the same for all of them. Next I have another if statement and this
05:45 is to see if things are clicked. The first one is the same as the hovering command.
05:50 It looks at the distance and it says if it's less than the array.
05:54 And then I add the logical and that's the two ampersands here and then mouse press.
05:58 So, not only is the mouse over the image, it also gets clicked.
06:02 And that's why I say if clicked here on the end.
06:05 If that happens, that triggers another function that I created for this called databox.
06:09 And it says to do it for object i, so that's going to be either the first one
06:12 or the second one or whatever. And I'll show that to you in just a second.
06:17 And that finishes the Draw block, on this one.
06:21 Now let's go down and take a look at these two functions.
06:27 The first one's a gradient function. And I've put void gradient circle.
06:30 It's a custom function, so I say, doesn't return a value.
06:33 That's why it's void. Grading Circle is the name.
06:35 And three arguments get passed in. The x coordinate.
06:39 The y coordinate. And the radius of the x, y, and r.
06:43 I turn on the ellipse mode to radius. And then I have, a loop that I run through.
06:47 Because what I'm actually doing to do is get a grading here, is I'm drawing a
06:50 whole series of Ellypsis. Starting with the largest one is going to
06:54 be white, an as they get smaller an smaller they get darker an darker.
06:59 I turn on no stroke cause I don't want the outline.
07:01 If I leave the outline, then the whole thing just turns solid black.
07:04 I turn off the outline, that's no stroke, an then I change the fill.
07:08 An I use a formula for the fill. And what it does is I want it to be as
07:12 light as possible at maximum diameter. And remember, Straight White is 255.
07:17 And so what I do is by having my incrementing going backwards by setting
07:21 it up, so that the I instead of starting with zero it starts with r, the maximum value.
07:28 That's the radius. And then it goes down on over time, I
07:32 minus minus. So we start with a value that's equal r.
07:36 So r divided by r is 1 times 255 gives 255.
07:40 So the very first step the fill is at maximum value 255.
07:44 And as it goes through until it reaches for instance it goes down until it gets
07:49 to 0 then its 0 divided by r is 0 times 255.
07:53 And that gives us a grayscale of zero, which is solid black.
07:56 So, it goes from full scale diameter and pure white down the zero and solid black.
08:03 I also have an alpha on this one of 20. And what this does is it makes it very
08:07 highly transparent, which gives it a much smoother transition.
08:12 If I don't have that, you can actually see the rings as it goes through.
08:16 And then, I draw the ellipses and I draw a whole bunch of em, layered on top of
08:18 one another to produce the gradient. Finally on the bottom, I create a data
08:23 box function and this is a little pop up window.
08:27 The only thing that needs to get passed in is: which item is it drawing it for,
08:31 so that's I Now I start by pushing the matrix.
08:35 And the reason for that is, I want to use a different coordinate system for these boxes.
08:40 because then it's easier for me to arrange everything in them.
08:43 So, by pushing the matix I saved the current coordinate system that's used for
08:46 the images, and now I can change things. And I'm translating to the top left
08:51 corner of the box, so that's the origin. I turn off the stroke, I put on a light
08:55 fill that's transparent so you can see through, see the leaves underneath it and
08:59 I draw a rectangle. Then, just to make a little nicer, a
09:03 little more defined, I have a thick black line that goes down the left side.
09:07 And I turn on the stroke cap square so it's cut off nice and cleanly at each end.
09:14 Then I come down and I put in some text. I put fill 0.
09:17 Which means the text is going to be black.
09:20 And I have four lines of text. I put what it is that is being displayed name.
09:24 And then I refer to the array for tree, and that's going to fill in that value
09:28 and position it ten pixels over, 20 pixels down.
09:32 And it goes through for each one of these.
09:33 And again, the reason for using the arrays is I could add 100 trees, and I
09:36 would still be able to use the exact same code and get it through.
09:41 When I'm all done with the text box, then I turn on pop matrix, and that restores
09:44 the grid system. That I had before so that the rest of the
09:48 things in a draw block are executed correctly.
09:52 With all of that together, what I get is this.
09:59 I have my two pictures here and it says, click on leaf for more information.
10:03 If I come in and I hover, you see how the color changes because it removes the tint
10:07 and I have a gradient that appears underneath the picture.
10:11 And again, that's this thing where you have to check the order and make sure
10:14 that the gradient comes first and then the image gets placed on top of it.
10:18 As a note, one of the reasons that this works well, to have the gradient appear
10:22 under the image, is because the image is a PNG file, a P N G file.
10:26 Which allows transparency and it's actually a rectangular image.
10:30 But everything except the leaf itself has been selected.
10:34 And rendered completely transparent so you can see the grid.
10:37 If I try doing this with for instance a bit map or with a JPEG.
10:41 I wouldn't be able to get that transparency.
10:42 That's why we use PNG files for this particular exercise.
10:46 I can hover over here as well. And if I click on one while it's
10:51 hovering, it brings up the box. This is the maple, genus (INAUDIBLE).
10:55 There's 128 species, sort of, approximately.
10:59 And you can make syrup out of it. Over here, I click on this one while it's selected.
11:04 It's an oak, and you can make chairs out of it.
11:07 So, that's a way of getting popup information that's interactive about an
11:11 easily changeable number of items. I have two; you could put in dozens or
11:16 hundreds if you wanted if you just made the box bigger and had the extra information.
11:20 That's how I resolved this particular challenge, and I hope you came up with
11:23 something that was creative, information, and aesthetically pleasing as well.
11:27
Collapse this transcript
Chapter 13 challenge: Interacting with data
00:00 Challenge four is about interacting with data.
00:03 For this challenge, you're being asked to chart data from professional baseball
00:07 teams in order to explore the relationship between the teams average
00:10 runs per game by year. And their winning average for that year.
00:14 That's because this is one of the biggest predictors of winning average.
00:18 The data set has over 2,500 rows. It includes every major league team that
00:23 played at least 100 games in a season between the years of 1883, that's less
00:27 than 20 years after the end of the Civil War, up to 2010.
00:33 Your job is to do the following. First, create a scatter plot that shows
00:38 the relationship between average runs per game on the X axis, and the win
00:41 percentage on the Y axis. Second, when a user hovers over a data
00:46 point on the plot, provide the name of the team, its average runs per game, and
00:50 its win percentages. Third, use keyboard commands to zoom in
00:55 and out of the scatter plot. Fourth, allow the user to drag the
01:00 scatter plot with a mouse. And then fifth, make it possible for the
01:04 user to reset the zooming and the panning to their original values, by pressing a
01:07 key or the mouse. The data are in a tab delimited text file
01:13 called bb.txt, where bb stands for baseball.
01:17 You'll need to save this file as a tsv file for use in processing.
01:20 The file has 3 columns. The first column has the team name with
01:24 year as a text variable. The second column has the win percentage,
01:30 that's a number from 0.000 to 1.000. And the third column has a average number
01:35 of runs per game. There are no headers in this file, which
01:38 made it a little easier to convert. As a quick note, I want to point out that
01:42 it is not very difficult to put the labels on the points, and it's not very
01:45 difficult to do the zooming and the panning.
01:50 However, because of the way that the coordinate system for the mouse operates
01:54 kind of independently of the coordinate system when you zoom, keeping the
01:57 hovering information when you have transformation on the scale can be a much
02:01 more complicated task, so if you have trouble with that please be aware, it is complicated.
02:09 I'll show you my solution to it. But you can also try just doing the
02:12 hovering or just doing the zooming and panning at this point.
02:16 Give yourself about an hour for this task, and I'll see you when you're finished.
02:19
Collapse this transcript
Chapter 13 solution: Interacting with data
00:00 In Challenge four, our job is to interact with a data set.
00:04 We're going to be using a long data set, about 2500 rows with information about
00:08 baseball teams. In fact, the data set is here on the
00:13 right on my file browser, and it's bb, for baseball.txt.
00:18 Now, if you just double click on this one right now, it opens and it just looks
00:22 like a mess. However, it is a tab delimited text file,
00:25 and we're going to do two things. Number one is we need it to be a TSV file.
00:31 Now because it's already a text file, all we need to do, is come and click on the name.
00:37 Now, I have my system preference and options set to always show the file extensions.
00:42 That's important or you'll end up with a double extension and things won't work properly.
00:47 I'm going to change that to TSV, it says, it's going to change things and that's fine.
00:54 You see in fact, over here on the right, it now says, Type TSV file.
00:58 And this is the right kind of file that I need.
01:00 In fact, if I were to open this up in Excel, you could see the structure, so
01:03 that's what I'm going to do right now. (SOUND) It brings up the text, Import
01:09 Wizard, but it's in the right format, so just hit Finish.
01:20 And what you have is a data set, I'll make this one bigger, with just three columns.
01:26 The first one is the name of the baseball team along with the year, that is
01:29 reporting the results for. So we're starting with the 1883 Cleveland Blues.
01:35 The second column is their winning percentage for that year.
01:39 The Cleveland Blues won 55% of their games, usually reported as 550, as a proportion.
01:45 The third column has their average run score per game for that season.
01:48 They scored an average of 4.76 runs across their season.
01:52 Alright, I'm going to close this data set now.
01:57 I don't need to save any changes. And I'm going to go back to my file browser.
02:03 So I have my file there. But what I need to do is I need to add it
02:06 to the processing sketch. The easiest way to do that is to simply
02:10 take the file, and drag it onto the window.
02:14 And when I let go, two things happen. First, in the processing window near the
02:19 bottom, you see it says, One File Added to This Sketch.
02:23 Second, in my file browser, you now see a new folder called, Data.
02:27 If I double click on that, you see that it's placed a copy of the baseball data
02:31 set in there. So I can actually delete this originally.
02:35 I don't need that anymore. The third thing is I actually need to
02:41 explicitly add the table class to read this.
02:45 Now because the table class is here in the same folder as my sketch.
02:49 It already shows up as a tab in my sketch.
02:51 And so I'm ready to go for the data. I'm going to make this window larger now.
02:59 And I'll run through how this all works. First I have the title Challenge Four
03:02 interacting with data. Then I have a on line comment that gives
03:06 the names of the colors in my pallete that's so I can remember what these hex
03:10 codes mean. I created a color array.
03:15 So it's an array with several color variables in it.
03:18 I called it Palette, and then I put in three hex codes.
03:21 The first one is for dark blue, the second one is for light tan, and the
03:24 third one is for a medium blue. Next I need two fonts created.
03:29 One is a title font, and the other one is used for axes and for other text.
03:33 They are both based on times roman. I just need to create these, using the
03:37 tool within processing. So I'm going to go up to Tools, Create Font.
03:47 And then I'm going to come down to Times. Now, when I scroll down this list, I
03:58 notice that the font that I used when I first created the sketch on my Macintosh,
04:02 which was Times-Roman, doesn't exist on this Windows PC.
04:07 That's fine. I can use a different font.
04:09 I'm going to use Times New Roman PSMT as a standard for this one.
04:14 I'm going to create a 40 point version of that.
04:19 One way to work around the difference here is that instead of saving this new
04:23 file as Times New Roman PSMT-40. Actually just going to change it's name
04:29 to match what I have earlier. So, it'll be, Times-Roman-40 and then
04:37 press OK. Then I'm going to do the same thing to
04:42 create a 14 point version of the font. Tools, Create font.
04:49 Come down here to 14, and then I'm going to change the name here, to match what I
04:57 have in my sketch. If I go to the File browser for a moment,
05:04 I should have in my data folder now. Not just the TSV File, but the two
05:09 processing font files, so we should be good to go.
05:13 Come back to the processing sketch. After creating my color palette, and
05:19 creating my title and access fonts. The next thing I do is I create an object
05:24 called bbd of the class table. That's the actual data set.
05:28 This is simply creating a space in memory for it.
05:30 I have to load it separately, a little bit later.
05:34 Then I have a bunch of variables. I'm using one right here, called Wide, to
05:37 specify the width of the window. I'm actually just duplicating the one I'm
05:41 going to have in size, then another one for high for the height.
05:45 The size of the border that I'm going to have within the sketch is 75 pixels all around.
05:50 And then I'm creating separate variables for each one of these to use in later formulas.
05:54 Lb for left border, rb for right border, bb for bottom border and tb for top border.
06:01 Then I create two new variables that also specify the resulting size of the grid in
06:06 terms of the grid width, that's gw. And grid height gh.
06:12 And then I have a strain that's going to appear as a subtitle that will actually
06:17 change when we have the sketch that says, data from 2252 teams.
06:23 Below that I have a few additional variables.
06:24 I specify the minimum and maximum values for x, and that's the average run scored
06:29 per game. Now I actually went through the data set.
06:32 Now nobody has an average of 0. The lowest that anybody has is around 2.4.
06:37 I just did this because it's easier to see.
06:39 And the maximum value of x is pretty close, the actual maximum was in the nines.
06:43 And then, I created the minimum and maximum values for y, and that's the win percentage.
06:49 And this one just, conceptually goes from 0% to 100%, so that makes sense.
06:54 Then I have three additional variables that are used in modifying the chart.
06:59 Z is for zoom, and this is the zoom factor.
07:01 I start with 1, which means full size. And then I have two other variables, tx
07:07 and ty, for translating on x and translating on y.
07:10 Where I set them to the middle of the screen, and these are used for panning at
07:14 the beginning. You'll see where they come in.
07:17 So that's all the prep work. Now I'm going to go into the actual setup
07:21 of blog. What you see here is I void setup, I give
07:24 the size of the window, 1000 pixels wide, 600 pixels tall.
07:29 I turn on the anti-alias scene with smooth.
07:31 I change the curser to a cross, and that makes it a little easier to identify
07:35 points in the chart. Then I actually load the fonts that I created.
07:41 I load the title font and I load the axis font.
07:46 Finally the last thing in setup is that I load the data table.
07:50 So, I created an object earlier that I called bd, that's for baseball data.
07:55 And I am declaring that it is a new object of the class table and then I give
07:59 the name of the file that's referring to bb.dsv.
08:04 That finishes the setup block and so now I can go down to the draw block.
08:09 Here I have to draw and then I have background color referring to the palette.
08:13 And that's just the first color in the palette by saying go to the array called
08:17 Palette and get index number 0 out of it. Then I created several custom functions.
08:23 This is to make it a little easier to segment my code and to see the structure.
08:28 The first one is called scatter and that actually draws the scatter plot.
08:32 It takes one arguement and that's the name of the data set to the table.
08:36 It's vbd in string format. The second is a frame.
08:40 This is actually a way of masking the points that would show, near the borders
08:44 near the four sides. The third one is the main title, and that
08:49 just goes to the top, and, again, it takes one argument here.
08:52 Then the next one is x-axis, and it's a way of specifying the x-axis as well as
08:56 putting a label on it. And the last one is y-axis, similar.
09:02 And I'll show you how these each get played out, when I create the actual functions.
09:06 But that finishes my draw blog. Now, let's go down and look at my Custom
09:10 Function scatter. This one is the most complicated.
09:14 Requires a little bit of explanation, because it also contains the Hovering commands.
09:19 First, I say void because it's not returning a data type it's drawing something.
09:24 It's called Scatter. It takes one argument.
09:26 It's a string variable and it is the name of the table object it will bring in.
09:32 Then, the next thing I do is I'm going to be doing a couple of transformations on
09:35 the matrix. I'm going to go push matrix cause I want
09:38 to save the grid form, that's being used for the other commands.
09:42 I only want to change it for the scatter plot.
09:44 So by saying push matrix, it's keeping 0,0 the origin as the top left, and scale
09:49 at 1. Then I translate.
09:53 I move the origin point to tx and ty, I defined those earlier, those go into the
09:57 middle of the sketch. Those go right to the center I also
10:01 introduce the scaling variable, which right now has the value of 1 and that's
10:05 just z. And then I change the color for strokes.
10:10 I'm using indent number 1, second item in the array called Pallet.
10:15 I change the stroke weight to 3 pixels and then I'm entering a variable that
10:18 says how many rows there are in the data. Now I know there's 2,522 because I looked
10:24 at this CSV and I saw how many rows there were.
10:29 Next, I create a loop that runs through every line in the data set.
10:35 So, it starts with I and it goes to n and it goes one step at a time.
10:40 The first thing it does, is that it loads the average runs per game.
10:44 So I have a variable, it's a floating variable because it has decimal points.
10:48 I call it x because it's going to be on the x axis.
10:51 And then what I'm doing is, I'm changing the number so that the way that they fit
10:54 on the scatter plot is correct. I'm using the map function, and what map
11:00 does is it takes a variable and it changes it from one scale to another scale.
11:06 So what I'm doing is I'm taking the variable, and it's called bbd, that's the
11:10 data table, and then .getfloat is the function.
11:14 And then I is for the row number that changes as it goes through the loop.
11:19 And then 2 is index number 2. That's the column index for the data set.
11:25 It's actually the third column but because it starts counting with 0, it
11:28 goes 0, 1, 2. I need to put in the 2.
11:31 Now the original scale for this variable goes from the min x to the max x.
11:36 This says average runs per game, and it goes from 0 to 10.
11:40 Then I'm changing it to a slightly complicated thing.
11:43 What I have is I have a variable here, called gw, which is the grid width.
11:48 I defined that earlier. And because I'm centering things, I
11:52 want to go down halfway and up halfway. So I take gw and divide it by 2 and the
11:58 low end is going to be negative gw2. So it goes down half way and the high end
12:03 is positive, it goes up half way. I also put in the z variable, which is
12:09 for zooming and changing the scale because when that variable changes, z changes.
12:15 I want the mapping to change as well. Now incidentally what this does is it
12:19 just spreads out the data points. And if I zoom in really close, the data
12:23 set would be really huge if I actually showed all of it.
12:27 But, you're not going to see all of it because the windows only so big and then
12:30 I masked off a portion of the window. But, this is the easiest way to zoom in
12:34 on the data set. Then I do a similar thing with the y variable.
12:40 That is the winning percentage in column one.
12:43 I create a floating point variable called y and then I map out the scale.
12:47 I use the table object. I use the get float function and I'm
12:51 getting from row I column 1. And again because it starts at 0 it's
12:55 actually the second column. And then I'm going from a scale on the
13:00 minimum of y to the maximum of y. I defined that earlier it goes from 0 to 1.
13:05 Then the same way that I changed it to the transform scale, I do it here.
13:10 But there's one big difference that is the negative on the second one.
13:14 The reason for that is because higher values actually need to go up towards the
13:17 top of the picture. But when you're dealing with computer
13:21 graphics that's a lower number and so I'm actually reversing the scale as I go
13:25 through here. Once I gather the x and the y by going
13:29 through this function and remapping them. Then I just use point and that draws a
13:34 point at the positions of x and y and I will do it 2522 times, once for each of
13:37 the points. Now let's scroll down a little bit.
13:42 This next piece is for the hovering. And this one gets pretty complicated.
13:46 And so it requires a fair amount of algebra, and a fair amount of trial and
13:49 error to get it to work correctly. Well, what I needed to do was to make it
13:54 so that I could hover over a data point. The problem is that even though I have
14:00 translated the grid through the scatter plot, the mouse position does not translate.
14:06 The mouse position stays with the origin at the top left in the scale of one.
14:11 And so I have to do some sort of backwards engineering to get it so that
14:14 the mouse actually knows where it is relative to the transformed scatter plot.
14:20 Here's how it works. I create 2 variables mx and my.
14:24 These are going to be for the effective mouse positions, mouse x and mouse y.
14:29 What I'm doing for each one of these is I'm taking the built in system mouse x
14:32 and mouse y, except that one stays on the original grid.
14:36 Again, where 00 the origin is on the top left and the scale is at 1.
14:41 Then what I do is I specify the original scale that each one of these is going to
14:45 be on. For x, I have lb.
14:48 That's the left border. And then it goes to the right border.
14:51 So that's the minimum and maximum value. For y, I start at the top border, and I
14:55 go to the bottom border. Then what I have is the actual mapping function.
15:00 What are my new limits? And this is where things get complicated.
15:03 The important part in here is that I have this gw variable, and I have tx.
15:09 Now gw is the grid width. What I want is I want to split the grid
15:13 in half, so I take gw and I divide it by two.
15:17 However, because of the scaling, in the other one, I multiplied the number times
15:20 the scaling. Here I need to undo that.
15:24 And so I divide by the scaling. Then I subtract a number that undoes the translation.
15:31 I take the tx, the translated value, and I subtract the halfway point, and I
15:34 divide that distance by the scaling function as well.
15:39 And so that undoes the translations so that the mouse actually knows which
15:43 datapoint it's going on, even though the mouse and the scatterplot are working on
15:47 different scales. Then I have the flip side of it for the
15:52 high end and then I do a similar function for the y.
15:57 From there, once I actually have a correspondence between the mouse
16:01 (INAUDIBLE) variables, mx and my and the point on the scatter plot, I can
16:05 determine whether the mouse is hovering over a data point.
16:10 I say if the distance between the mouse x and y, using my new variables, and the
16:15 data points x and y is less than 5. There, so I gave it a range of 5 pixels.
16:22 If the distance is less than 5, then do this.
16:25 And this is what's in that block. I say create a stat string, that's a
16:29 variable that I defined earlier. And put three things in it.
16:34 The first one is going to be the name of the team.
16:37 And I get that from the table object bbd, baseball data.
16:42 I use the .getstring function. We're going to go to row i, that means to
16:46 the current row that we're going on right now because this is part of the loop that
16:49 goes through the entire table. And go to column 0.
16:54 That's the very first column that has the names.
16:56 And then I write plus and then, after that, I'm going to add a space, a slash,
17:00 a space, and then the words runs per game, a colon, a space, and then finish
17:04 that quote. Then I add plus because I'm going to put
17:09 another variable in now. And this time, I'm going to be using
17:13 their runs per game. Now that's also from bbd, and I use
17:16 getfloat, because it has decimal places. We're going to row I to column 2, again
17:22 it goes 0, 1, 2. Except what I'm doing this time is I'm
17:26 changing the number of decimal places. I'm using the function nf, it's a string
17:30 function, or sort of like number format. And I'm telling that, the first one is a 0.
17:35 It says, do not add any zeros to the left side of the number.
17:39 And then, the second one, too, says. And reduce the decimal places to two numbers.
17:45 Because it can report 'em as more than 2. And then I add a little bit of text.
17:50 A space, a slash, a space. And then the word win percentage, colon,
17:54 a space. Then I close that quote, and then I add a
17:57 third variable. And this is done in the exact same way,
18:00 except it's getting the wind percentage, which is going to be in column 1.
18:04 And I'm rounding this one off to three decimal places, because that's how
18:07 they're traditionally reported in baseball.
18:10 That finishes my loop that I'm running for all 2522 rows in the data set.
18:17 The last thing I do here is I finish the matrix.
18:20 I go back and I do what's called pop matrix and what that does is it restores
18:24 the grid system that I had before I did the push matrix.
18:29 So, now there's origin 0.00 goes back to the top left of the sketch and the scale
18:34 returns to 1. And it goes through this process every
18:38 cycle through this command. The next block is for frame.
18:44 And this is just to mask points so I have clean edges around.
18:49 All I do is I'm creating a series of rectangles that I'm going to draw other
18:52 things on top of. So by doing the points first.
18:56 And if I did not have these masks, the point would go all the way to the edge of
18:58 the window. But by drawing these masks, and I'm just
19:01 putting rectangles on the top, bottom, left, and right.
19:05 It's going to create a clean border around it.
19:08 The next one is the title. It takes one argument and that's the
19:11 title text. And I'm going to center it left and
19:14 right, and center it top and bottom. From it's position that I give it.
19:18 I tell it which font I'm going to use, the title font.
19:20 I give it a color. The index number 1 in the palate.
19:24 And then I tell it to take that text and place it at width divided by 2, halfway
19:27 between left and right. And 25 pixels down.
19:31 And then I'm going to put another line underneath.
19:34 I'm going to use the smaller axis font. I'm going to use the same color.
19:38 And then I'm going to specify, take the stat string which I defined earlier and
19:42 then also center it and put it down a little lower at 60 pixels.
19:47 After that, I have a command, x-axis, this takes several arguments.
19:52 The first is a string that gives the name of the axis.
19:56 Then it takes xl, the left value for x. And then the floating point is for y, is
20:02 how far up and down is the x-axis. And then xr is what's the x position on
20:07 the right end of the axis. I specify the color as the index number
20:11 one from the palette. I give it a stroke weight of 2 pixels,
20:14 and I just draw a line, and that's a horizontal line going across the bottom.
20:19 Now, I'm also going to add a title beneath the axis.
20:22 So I say use the axis font, make it this color palate number 1.
20:27 And then I want you to center it left and right and center it top and bottom.
20:31 And then place the text that I gave for axis title, and then center it, and then
20:34 put it a little bit farther down than the bottom border.
20:39 Now, finally, I'm adding one more thing that's technically not an axis.
20:42 I wanted to put some instructions, and I want to put them on the bottom, and using
20:45 the x-axis was a convenient place to do this.
20:48 So I add a long string, that gives instructions on how to use the sketch.
20:52 As I hover over a point for data, use the up and down arrows to zoom, drag with the
20:56 mouse to pan, and press the Space bar to reset.
21:00 I tell it what color to make it. It's actually the same color as the other
21:03 text, and where to place it. Center it and put it just 25 pixels above
21:06 the bottom of the window. After that, I have a similar block for
21:11 the y-axis. Where I take the argument that's idle,
21:14 the x position, the left, right which is the same for the entire y-axis.
21:19 And then the y for the bottom of it, and the y for the top of it.
21:23 I specify the color. I give it 2 pixels thick.
21:26 Then I just draw the vertical line. Then to put the axis label on.
21:31 I call the axis font, I tell it the color to use.
21:34 This time I align it to the right. Because it's going to be off to the left
21:38 of the line and right align means it's going to get snug up against what I have.
21:43 And that center top and bottom. And then I place the text.
21:46 And I'm going to place it halfway, vertically.
21:48 And then just a few pixels over to the left of the plane itself.
21:53 Then I have another block for keyboard. Now key pressed is a built in code block,
21:57 that I didn't have to create this one especially, I just have to give the
22:00 commands that I want to use. So, void Keypress, and then I say, so
22:04 this only runs if a key is pressed. Then I add a couple of qualifications
22:10 onto it I say if that key is coded. So for instance the Arrow keys and the
22:15 Enter key and the Escape key are all coded keys.
22:19 And if that key code is for that up arrow, then I want you, in the next line,
22:23 to go z plus equals 0.1, so add 0.1 to the zooming function.
22:29 By the way, most of the time, you need to use curly brackets when you have an if
22:32 and then statement. Unless you're then statement, the result
22:36 of it, is just a single line. Then you don't need to add them.
22:40 So I, I don't have that on this one. And then I do a similar thing for going down.
22:45 If the key is pressed, and the key is coded, and the key code is down.
22:49 Then subtract 0.1 from z. Then I am going to use the Space Bar to
22:54 reset things. This is always in key press.
22:58 And if the key is equal to a empty space. That's what the Space Bar does.
23:03 Now because this one is several lines. I have to use the curly brackets.
23:06 And it says Reset z to 1. Reset the translation coordinates to the center.
23:13 And then also change the data that's in the subtitle at the top back to what it
23:17 was originally. Then I close off that block.
23:21 And then I have just one more block very quickly.
23:24 And this is about dragging the mouse. And mouse drag is another built-in block,
23:28 so I don't have to define it, I just have to say what I want to do with it.
23:33 So, mouse drag means that the Mouse button is pushed down and then the mouse
23:36 is moved at the same time. And all I'm saying here is, take the
23:40 variable tx which is the translation on x.
23:43 Now, by default it puts it right in the middle of the drawing.
23:47 And I say, take that variable and then add to it the amount that the mouse was dragged.
23:53 So by taking the current mouse position and subtracting the previous mouse
23:56 position, that tells me how much it got dragged and I can change the translation
24:00 with that. I have to do it separately for x and the y.
24:04 But then, I'm done. So that's how many lines of code here?
24:08 If I look at the very bottom left, I see the number 154, so there's 154 lines of code.
24:14 And lets see what it looks like when we run it.
24:16 I've got a dark blue background, I have a light tan text and dots.
24:24 Winning in baseball, 127 years of data. Then I've got my little subtitle, Data
24:29 from 2,252 teams. I have my x-axis on the bottom, average
24:33 runs per game with instructions beneath it.
24:36 I have my y-axis on the side that says win percentage, and then I have my data
24:38 points in the middle. And if I come in and I hover over a data
24:43 point, the subtitle changes to give information.
24:48 So, this point is for the 1884 St Louis Maroons, who had an average of 7.78 runs
24:52 per game and a winning percentage of 0.825.
24:56 That's incredibly high. Actually what you'll find what's
25:00 interesting, almost all of these ones on the periphery are very old teams.
25:04 There's 1887, 1895, 1894, 1899. If you go smack into the middle though,
25:10 somewhere in there, I'm on top of the 2005 Chicago Cubs.
25:17 Now, this is nice in and of itself, but we can zoom, and we can scale, so I'm
25:19 going to zoom by doing the up arrow. And now it becomes easier to tell the
25:25 data points apart. So, for instance, this one right here is
25:29 the 1985 Red Sox. They had average of 4.91 runs per game.
25:34 And they had a winning percent of 4.97. Almost broke even that year.
25:38 What's kind of neat is if I scroll in really a lot, is that the cursor color
25:42 has changed to be complementary. There's the '87 Oakland Days, who had
25:46 exactly 500. I'm going to reset for a moment, by
25:49 hitting the Space bar. going to scroll back in a little bit,
25:53 zoom in. But I want you to see that I can now drag
25:56 left and right. And this makes it easier to explore some
26:01 of the patterns in the data. There's the 1899 Cleveland Spiders, the
26:05 1952 Pittsburgh Pirates. And lets zoom in and, there's the 1945
26:13 Brooklyn Dodgers. I'm going to press the Space bar to reset.
26:17 It's a great way of exploring a large data set interactively.
26:22 We had to do a little bit of machinations in order to get the hovering to work with
26:26 the zooming and the panning. But, it pays off, and it's a very simple,
26:30 intuitive, and informative display. Hopefully, you came up with something
26:34 that was equally creative, equally informative, and fun for you to make, as well.
26:39
Collapse this transcript
2. Comprehensive Challenge
Comprehensive challenge: From a spreadsheet to the web
00:00 For the end project, we're going to go all the way from raw data on a
00:03 spreadsheet to a final presentation. Here's the scenario.
00:07 Imagine that you've been commissioned by the executive director of an opera
00:11 company to create a visualization that would allow them to interact with data.
00:16 And explore trends in Google searches for various opera composers over the last
00:20 several years. So, your job is to do the following.
00:24 First, use the spreadsheet of data for Google Correlate called composers.csv.
00:29 That's been claimed to have just the relative popularity of five searches from
00:33 January 2005 to December 2012. The search terms that I looked for were
00:39 Puccini opera, Verdi opera, Mozart opera, Wagner opera and Bizet opera.
00:46 Let me show you what that file looks like.
00:49 I'm going to go to a file browser and show you what we have here.
00:53 If we go into Files, that's a folder I've created with several things in there.
00:58 Right now, we're going to look at the composers.csv file.
01:02 Now, please note there is something important here.
01:04 I've changed my computer system Preferences or options to show the
01:08 extensions of all file formats. This is important because we're going to
01:13 be modifying one, and if you don't have that, you can accidentally double up on
01:16 the extensions, and it can create some system errors.
01:19 So, make sure you have that first. I'm going to then double-click on composers.csv.
01:24 And here's what I have, there are 6 columns.
01:30 The first one is the week for which it's reporting the data.
01:34 The second through six columns are the composers.
01:36 Now right here I have just their last name listed Puccini, Verdi et cetera.
01:41 But, when I was searching in Google trends, I did Puccini, opera, Verdi,
01:44 opera, Mozart, opera, etc. The numbers underneath each one, are
01:50 percentages of the maximum search value for any of these five during the time period.
01:57 And so, we have a lot of rows here. In fact, if I scroll all the way down, we
02:03 have 419 rows right now including the header.
02:08 Now, we're going to save this in a special format to use in processing right
02:11 now, and the one thing we need to do aside from taking it into a special text
02:14 format is we need to remove the header. It's one of the reasons I keep a CSV in
02:19 here separately, is because I need to be able to refer back to what it is.
02:24 So, I'm going to do two things. First, is I'm going to come over, and I'm
02:26 going to select the Header and Delete that row.
02:33 Then I'm going to go to File, and Save As.
02:35 Then I'm going to come to Save As Type and select Tab, Delimited.
02:45 So, it's Text, Tab, Delimited and press Save.
02:51 And it's true, it's going to have fewer features, because it's a simpler format.
02:55 So, I press Save and now I need to close this before I can modify it elsewhere.
03:00 So, I'm going to click on the X to shut, and I'm going to get a couple more
03:02 thing's asking me if I really want to save it, and the answer is, yes.
03:06 I'm going to go back to my file browser now, and you can see I have another file here.
03:11 It's composers.txt, that's a text document.
03:15 Now, I need a different kind of text document.
03:18 They're both tab delimited text, but I need it to specifically have the
03:22 extension TSV. And remember, I changed my system
03:25 preferences or options so I would see all of the file extensions.
03:30 I come to this one and I just change the last two letters to TSV.
03:35 And it's true I want to change it, and now you can double check, because over
03:38 here under type it now says TSV file, and that's what I need.
03:42 Let's go back to the instructions for this assignment.
03:46 Our first thing is to get the spreadsheet ready.
03:49 Our second thing is to create an interactive bar chart with one bar for
03:53 each composer on a scale of 0 to 100, because that's the scale that Google
03:57 trends gives us. Third, create a slider that allows a user
04:04 to choose the time period to be displayed by the bars, that corresponds to the rows
04:09 in the data sheet. Label the dates for the ends of the
04:13 sliders range, and put the current date over the slider button itself.
04:18 Fourth include portraits of the five composers as part of the visualization.
04:22 These images are included in the project files, let me show you where those are.
04:26 You can go back to the file browser, and you see a folder in here called Images.
04:30 Click on that and I have five JPEG images.
04:33 Each one is 100 by 100 pixels of the five composers.
04:38 Let's go back to the processing file, and the fifth part of the instructions is to
04:41 save the visualization as a stand alone desktop application for Windows and Mac,
04:45 which is actually a very simple procedure.
04:49 At the bottom I have written instructions here on how we saved the file.
04:54 And don't forget to delete the first row that has the header names, in order to be
04:58 able to read it properly. So, those are our instructions, those are
05:03 our orders for what we need to do right now.
05:06 Take some time and try to come up with a creative, aesthetically pleasing and
05:10 informative solution to these particular constraints.
05:14 You should give yourself and hour or possibly more to work on this.
05:17 I'll see you when you're finished.
05:18
Collapse this transcript
Comprehensive solution: From a spreadsheet to the web
00:00 Our assignment for this end project is to create an interactive visualization of
00:05 Google Trends data about searches for various opera composers.
00:11 Now, my solution for this begins with picking the colors.
00:15 I went to Adobe's Kuler, that's kuler. I went to kuler.adobe.com.
00:21 And I found a palette that I thought worked well for the visualization.
00:24 And coped the hex codes down into this. Above that, I have a comment that doesn't
00:28 say what the colors are, but it says what their purposes or their roles are so I
00:30 know which one to use. The next thing, is I have two fonts that
00:34 I'm going to be using. I'm going to be using a large, thick font
00:38 for the title, and a smaller thinner font for the labels on the grid.
00:44 In processing, you actually need to go through a process to create each one of
00:47 these fonts, and that's what I'm going to do right now.
00:49 We go up to Tools to create font. And the first one we're going to get, I'm
00:57 going to move this off to the side, is Arial Black 32 pt.
01:01 Now, by the way, Macintoshes, Linux computers, and Windows PCs don't
01:04 necessarily have the same font lists. I intentionally chose two very widely
01:10 available fonts. I know that Macs have these and Windows
01:13 have these. And so, you can change them if you need
01:16 to, you're just going to have to change the reference in the code later.
01:20 So, I'm going to go to Arial Black, and then I'm going to chose 32 point.
01:28 And press OK. Then I'm going to save the second font,
01:32 which is Arial Narrow 14 point. Go to Tools, Create Font, come to Arial
01:41 Narrow 14 point. By the way, what I'm doing is I'm also
01:47 going to be saving these as what's called P-font.
01:50 That's actually a class here, and I'm creating an object with the font in it.
01:54 And so these are basically a very complex variable.
01:58 But I have to create these, so I declare it as pfont, and then the name that I'm
02:01 giving it is Title Font. And then Y- font for the y-axis on the
02:05 bar chart grid. Let's take a quick look at where those are.
02:08 I'm going to go to the File browser. And you see my end_solution.pde file.
02:15 That's the Processing file. And the Files folder that came with this
02:20 but when I created the fonts I got an automatic Data folder.
02:24 Am going to go up to that, and there you see I have the two fonts that I just created.
02:31 That's great and so I'm going to go back to the main, here we go and go back to
02:35 processing now. I also have an object here for composers
02:41 that's in the class of table. So, I say table and, don't forget
02:45 capitalization is, is specific and you need to get it the right way.
02:49 And I call the composers that's going to be creating the data that I worked with.
02:55 Now let's just go back and get that thing ready cause you remember it needs to be a
02:58 TSV file. So, I'm going to go to my file browser,
03:02 and I'm going to go into files. I'm going to open up this CSV file.
03:12 Make that a little bit bigger. I need to do two things here, number 1 is
03:16 I need to delete the top row headers. Now when processing 2.0 the full version
03:23 comes out. It will have a built in table class, and
03:25 among other things, you won't need to delete the headers, you can simply say
03:29 that you have them. But for right now this is the simplest
03:32 way to make it work, so I'm going to come through there and I'm going to delete that.
03:37 And go to File and Save As. I'm going to Save As the type is "Text
03:43 Tab Delimited", and I press Save. It's going to tell me I'm losing some
03:49 information, that's just about formatting, that's the only information
03:54 I'm losing. Then we close the file because I'm going
03:59 to modify its name manually, that's okay, I want to save it, and it's alright to
04:02 lose some of those features. Now I'm going to go back to the File browser.
04:08 And now you can see I have a new file here called Composers.txt, and if you
04:12 look over to the right under Type, it says it's a text document.
04:16 Now again, I've changed my system options so I can always see the extensions on files.
04:22 This is important here 'cuz otherwise, you'll think you changed it, but you
04:25 won't have. And you'll get horrible errors when you
04:27 try to run your processing sketch. What I'm going to do is I'm going to
04:32 click on composers.txt twice slowly so I can modify the file name.
04:37 And I'm just going to go change the txt to tsv.
04:42 When I hit enter, it's going to ask me if I want to really do it, I do.
04:45 And you see that the file type, in the third column here, changed from text file
04:49 to tsv file. That's exactly what I need.
04:53 Now, I'm going to add this file to my sketch.
04:56 Let me show the easy way to do that. I'm going to take this window and just
05:00 get it off to one half of the screen. Then I'm going to bring up my processing
05:04 window, and put that on one half of the screen.
05:08 I come back in here, and I grab my data file, the TSV format.
05:12 And I just drag it on top of the processing window.
05:15 And you see I have a message at the bottom that says one file added to sketch.
05:20 In fact, in the file browser. If I come right here I go into data
05:24 that's where the fonts are. You see I now have the TSV file on there
05:28 that's where it needs to be. Okay going back to the processing sketch
05:33 let me make this bigger right now. Now, I'm going to create a series of
05:38 variables that I use and create in the drawing.
05:41 I'm creating these as global variables so I can declare and initialize them up here.
05:45 And I can call on them in several different blocks or code or possibly
05:49 modify then dynamically. The first one is LM, that's the left
05:53 margin of the grid. That's how far the grid needs to be from
05:56 the left edge of window and I've made it 100 pixels.
05:59 After that is BM for bottom margin, also 100 pixels.
06:04 The next one and by the way, these are all integer variables or so, int.
06:08 The third one is GW, for grid width and the grid I'm going to make the bars on is
06:12 going to be 800 pixels wide. GH is for grid height, that's 300 pixels.
06:19 Then, I have a couple of variables that set ranges for things.
06:23 I have min X is zero, that's a minimum of value of x for the slider, and the max X
06:28 is 418. I got that number because that's how many
06:33 rows there are in the TSV data file once I remove the header.
06:37 Then I have two variables that specify the lower and upper limits of the grid
06:40 that I'm going to draw the bars on. Min Y is zero, max Y is 100, because it's
06:44 a zero to 100 range in the Google data. And then I have another one, BW for bar
06:50 width, that's how thick I want each bar to be.
06:53 Scroll down a little bit. Then I have a variable called Row that
07:00 acutally use as a way of reading through the data file, and I initalize it as 0.
07:07 I have Row Count that I went through the file, I know there's 418 rows, so I put
07:11 that in there. Then I'm going to be creating a slider,
07:15 and I need a variable that indicates the exposition of the slider.
07:19 And there needs to be global one, so I can modify it.
07:22 Up here, I'm using a float variable, so I can take fractional values and I'm
07:26 calling it slider X and I'm initializing it at zero.
07:31 Then I have another integer variable that simply indicates how many bars I'm going
07:34 to draw. So, the N, the sample size is five.
07:38 After that I have three arrays, the first one is a String array that I'm calling Names.
07:43 And in that array I'm putting the five names of the composers the way that I
07:46 want them to appear as labels on the chart, so they are capitalized in this case.
07:52 The second one is a P image or a processing image array and I'm going to
07:55 call it Portraits. And at this moment, I'm not putting
07:59 things in it, I'm creating an empty array that I'm going to fill in a little bit later.
08:03 And so, when you create an empty array, you put new and then you put the type
08:06 again, p image. And then in square brackets, how many
08:10 spaces you need. And I'm going to have five.
08:12 I use that variable n5 just a moment ago. Then I'm going to create a String array
08:17 called Image Names. And these are the actual names of the
08:20 image files that I'm going to be adding. Puccini.jpeg and Verdi.jpeg and so on in
08:25 fact I am going to add those files right now.
08:29 Let me make this window after the left now and I am going to come back here to
08:35 my File browser to Files and here I have images.
08:47 I've got my five images here, and I just drag them on top.
08:51 And now you see it says five files added to the sketch.
08:55 Once I've dragged my images onto the window, and I get the message that says
08:59 five files are added to the sketch. You can confirm that in the File browser
09:04 by going back to the Data folder. And you see that in addition to the two
09:08 fonts in the data sheet for Composer CSV, I now have the five JPEG files.
09:15 There's one more important thing. I also need to add the Table class, the
09:19 actual code that runs it. Now, I've already done this here.
09:23 But as a reminder, the way that works is I go to Files and I take this Table.
09:29 And like the others, I just drag it on top of the Processing window.
09:32 I've already done that, so I'm not going to do it again.
09:35 But when I do that, you see that I have this tab right here, Table and it also
09:39 shows up right here. Now that I've got those files added, I
09:44 can get into the actual code for the sketch itself.
09:47 Let me maximize this again. Now, I've created some really big
09:54 comments that separate my blog. So, I could find them easier when I'm
09:58 scrolling through that's why I have the two slashes.
10:01 Then set up then a whole lot of slashes because I can see those as I'm scrolling
10:03 up and down the code. I've done those for each of the blocks
10:06 that I have. The first block is setup, void setup,
10:09 again void because it doesn't return a data type and then within the curly
10:13 bracket I put in my arguments. The 1st one is this size of the window.
10:18 I make a 1000 pixels wide, 600 pixels tall.
10:22 Then I turn on anti-aliasing with smooth. Then I'm going to load my two fonts.
10:28 The title font I use the function load font, and then I put in the specific name
10:34 of the font: Arial-black-32.vlw. Then I give a similar thing for Y font.
10:41 It's easiest by the way to simply copy the names of those fonts from your Data
10:44 folder and paste them in here. And please note they need to be in
10:48 quotation marks in the parenthesis. Next I am going to read the Data file to
10:52 make it available. I now have Composers, that's the name of
10:56 the object of the Table object that I am creating.
11:00 So, Composers equals new and then Table with a capital T.
11:04 And then in parenthesis and quotations. The name of the TSV file exactly as it
11:09 appears Composers.tsv. Finally in set up, I'm going to load the
11:13 images into the array. You want to make sure you do this here
11:16 because if you were to load images in the draw loop iIt try to be doing the 60
11:19 frames per second. You'd quickly run out of memory.
11:22 So, here I have a very short loop that loads the images into the array.
11:27 'Cuz remember there's five images and I created an empty array with five spots.
11:32 So, I create a for loop for and I equals zero I less than n, n is five.
11:38 And then I increment one at a time. And then it goes through starting at 0,
11:42 1, 2, 3, 4, and then because arrays begin with the index number zero, this works.
11:47 I have the portraits array. And it's going to load the image and it's
11:51 going to go to the array of image names and pull down the appropriate image.
11:56 You can actually see it there at the top of the screen.
11:59 So, the first one is going to be, Puccini.jpeg, the second will be Verdi.jpeg.
12:03 It's actually index numbers here, one, two, three and four.
12:06 And that finished my set up block. Next, I'm going to scroll down to draw.
12:12 Now, I've created a relatively complicated drawing.
12:16 But I want to make the code a little simpler to follow, an so what I've done
12:20 here, is within Draw, I only use one standard function, an that is the Background.
12:26 I use the Background function an I am actually referring to a color from the palette.
12:31 I have an array earlier called Palette, an I'm taking the first item in it which
12:34 is index number zero, an that's going to be the background that refreshes every time.
12:39 When you have a dynamic drawing and you want to make sure you do that, so you
12:42 don't have trails left all over the drawing.
12:45 Then what I did is I created four custom functions for this drawing.
12:48 The reason I did that is because it makes it easier to separate the code into
12:51 blocks and its easier to follow each one of them.
12:54 The first one is simply to create the title, main title and then it has one
12:58 argument and that's the text for the title.
13:02 The second function is called Grid Lines and that I have to specify a number of arguments.
13:08 I have to specify the left margin the bottom margin, the grid width, the grid
13:11 height, the minimum value of y, the maximum value of y.
13:16 And then I also have to specify how many divisions there are in it.
13:20 And I want to break it into four pieces. So, it goes, actually, 0 to 25 or 10 to
13:25 50, 75 to 100%. And because I declared these variables
13:29 early at the top, I gave them all values, I can just use the variables names here,
13:33 it makes it easier. The third custom function is called Slider.
13:38 And now that one, I actually need to have a title for this slider that I called
13:42 Weak I need to specify the left margin. I need to specify how far it is from the
13:47 bottom and I just entered that manually with 50.
13:50 And then I need to give the grid width, and then I need to give the minimum and
13:54 maximum values for x, that goes from 0 to 418.
13:58 Then I give the labels for the two ends of the sliders as text here.
14:03 The last function actually goes through a for loop and what that is is this is the
14:06 one that actually draws the bars. It's a function I created called Bar,
14:11 and, because I have five bars, this lets me write it just once, and it works for
14:14 all five of them. So, I've created a function called Bar,
14:20 and what it does is I have to specify the left margin, the width of the grid that's
14:24 GW, the bottom margin, the bar width that's BW.
14:29 I is the current number that it's working on.
14:33 So, it's going to be zero, one, two, three, four.
14:35 Then I have another that says names, length.
14:38 And that's just an indicator of how many bars there are going to be total in this
14:41 case it's going to be five. Then I have names I which goes back and
14:46 says what the persons last name is, Verdi and Puccini etc.
14:50 And then I have in this complicated one that comes back from the Table class and
14:54 it says Composers that's the name of the Table object.
14:59 And then dot get end so I'm pointing out integer variables.
15:03 And Row it is going to go through one row at a time and I initialized a variable
15:07 row earlier but you'll see that this slide of this one had actually controls
15:11 the row. And then I do this one I plus one and the
15:15 reason for that is the person their index number puccini is zero.
15:20 But they're the second column in the data sheet, so I just need to move things over
15:24 by adding one. Okay, so that is the Draw loop that's all
15:28 that's in there, because I've taken the action and put it into separate functions
15:31 beneath that. And we'll go through each of those next.
15:35 The first function's an easy one, It's the main title.
15:41 And what I do is I specify void because it's asking about the return type of the data.
15:46 It doesn't return any data it returns a title.
15:49 And that's a main title, and then I have to specify the arguments that are going
15:51 to come into the function. This takes only one argument and that is
15:55 the actual text of the title so it's a string variable.
15:59 And that's one that I specified up earlier.
16:00 Then, I say that I'm going to center it on the left and right and I'm going to
16:04 center it top to bottom when I position it.
16:08 Then I say the font that I'm going to use.
16:10 Text font is the function, and then I'm going to refer to the title font that I created.
16:15 Then the fill is what colors the font. I'm going to use the palette index number
16:19 three, which is actually the fourth item in the array.
16:24 And then I place the text with the text function, so it titled text, and then I
16:27 put it in the middle with width divided by 2, and I put it 20 pixels down from
16:30 the top. The next function is Grid Lines.
16:35 This is the one that actually draws a grid for the bar chart.
16:39 This one takes several arguments. It's void because it doesn't return a
16:42 data type, it's called Grid Lines. It's going to take the left margin which
16:45 I've said could be a float variable, a floating point.
16:49 The bottom margin. How wide is the grid?
16:52 How high is the grid or how tall is it? What are the minimum and maximum values
16:56 for y? And how many divisions do I need for
16:59 drawing the in between lines? Now one thing I'm going to be doing.
17:03 Is I'm going to be doing translation here moving the origin to make it a little
17:07 easier to deal with. But before I do that, I don't want to
17:10 mess up anything else that's using the original system where 00 is the top left
17:14 of the grid. so, I push the matrix that take the
17:18 existing matrix transformation or to the standard one at the moment.
17:22 Save it off to the side and then I can translate.
17:26 So, by translating, what I'm doing is I'm actually moving the 00 origin to the
17:30 bottom left of the grid. And LM is the left margine, so I move it
17:34 over to distance of the left margin, it's 100 pixels in this case.
17:38 And then I drop it down to the bottom by going to the height number.
17:42 That means starting at the top of the window and going all the way to the bottom.
17:45 An then subtracting the size of the bottom margin.
17:48 Then I say what color I'm going to use. The stroke is, cause I'm drawing in lines
17:53 here, is going to be palette index one. So, palettes an array of colors that I
17:57 defined up above, I'm going to be using index number one as the second item in it.
18:02 An then, I'm actually going to also specify stroke cap.
18:05 I want these lines to end very sharp with squares.
18:08 Now if I were to draw them really thick that be obvious, but even now.
18:11 So, I'm specifying stroke cap square then I have a little bit of code that's grayed out.
18:17 I had originally written a code to create a vertical line on the left side for the
18:21 y axis. I decided that it wasn't absolutely
18:25 necessary and so I commented out those two lines of code.
18:29 But if you wanted them you could just uncomment them like this.
18:32 We just select them and uncomment them. It'll draw the line now, and I'm going to
18:37 comment them back out, then I have reference lines that go across the grid.
18:42 Those are going to be very narrow stroke weight of one pixel.
18:45 And then because I have several of them, I'm going to use a for loop.
18:49 Now because I'm doing division in here, I acutally need to use I as floating point
18:52 variable, even though it's normally an int.
18:56 So, I do float I equals zero. So, I start at zero.
19:00 And then I is less than or equals to the divisions of y.
19:04 And that's a variable I created they said four.
19:06 I want to split that into four pieces. Please not that I said equals to because
19:10 I want to be able to go all the way to the end and then I increment one step at
19:13 a time. Now, one of the reasons it's really
19:17 important to use a float here is because I and the div y are integer variables.
19:22 And if I try to divide integers by each other, it's not possible to get a
19:25 floating point variable. It will either give zero or a whole
19:29 number, and can be excruciatingly frustrating.
19:32 But by setting I as a float variable, this works naturally.
19:36 So, I'm going to create a variable called Y, it's called Float, and this is
19:39 going to be for the vertical position of the reference lines.
19:42 Y is equal to I divided by div Y. So, when I is 0, that division is 0 over
19:50 4 is going to be 0 It's going to go to the top of the grid.
19:55 And that's what happens when I multiply times minus i.
19:59 So, the first one, line zero, is going to go to the top.
20:02 And then I actually draw the line itself, that one was just to get the Y value.
20:05 And then I do zero, so it starts at the left margin in which, because I translate
20:09 it as the edge of the grid. And Y that goes all the way across.
20:15 Next, I have some axis numbers. What I've done here, is I'm using the Y
20:20 font that I've created up above. So, text font is Y font, I'm going to
20:23 give it a fill, and then I specify how I wanted the line.
20:27 I want these ones flush right, and I want them so the bottom of the text is next to
20:31 where the line would be. And then I run through a for loop again
20:36 using I as a floating point, because I want these to line up with the lines that
20:39 I had above. So, I simply copied the one I have here,
20:43 but I'm using it to then place text. Now, when I do the division of I divided
20:48 by zero times the negative of i, I end up with numbers with decimal places, so it'd
20:53 be like 25.000. I don't want the zeros on there and so I
20:57 use a special function here called NFS and I've got a comment here that explains it.
21:03 What it does is it takes a value and it converts it from a floating point number
21:07 to a string. And by setting it with zeros the first
21:11 zero says how many numbers do I want to add to the left.
21:15 So, if I want it to read as 0025 I could add that on.
21:19 I don't want to add any so I put it at zero.
21:21 The second zero is how many decimal places I want.
21:24 I don't want any and so by doing that it will cut off all of the decimals and just
21:28 print it as a natural looking percentage number.
21:34 And then I place it, negative 10 means to move it slightly to the left of the grid.
21:38 And the Y is following the lines that I drew across.
21:42 Finally, I finish this with Pop matrix, because this was all done on a translated
21:46 grid, where I moved it over. The origin, the zero zero origin to the
21:51 bottom left of the grid. This restores it back to where it was
21:54 before for all of the other functions. Now we have a slightly more complicated one.
22:00 Oh, by the way, I uncommented and then recommented some text.
22:03 So I just need to save it. I haven't changed anything really.
22:07 The slider that goes across the bottom takes a lot of information here.
22:11 First, the function takes several arguments.
22:13 I need to give it a title, the left margin, the bottom margin, how wide it
22:17 its, it's minimum and maximum values on x.
22:22 I need to give it a label for the bottom end and a label for the top end.
22:26 And I explain those in a comment. I have a variable in here.
22:29 A floating point variable called d. That's for the diameter of the Slider
22:33 button that you click on. I draw a line for this lighter, I specify
22:37 the stroke color from the palate that I used above.
22:40 I make it square end and I make it five pixels thick.
22:44 Then I draw the line from the one end to the other near the bottom.
22:50 And then I created a button that you can actually click on with your mouse to drag across.
22:55 I did this by simply drawing two circles, I wanted it to be two different colors.
22:59 I turned off the strokes so there's no outline, I give the first circle it's
23:03 fill and then I have a function that tells if a person is dragging the slider.
23:09 And it's whether the distance of the mouse is less than, for instance one
23:12 diameter away from the current center of the circle for this lighter.
23:17 Now it actually means that the distance is bigger than the button itself.
23:22 If you make it exactly the size of the button it's really easy to get off of it
23:25 and it stops scrolling. So, you give people a little of wiggle room.
23:30 So, if they scroll a little faster they don't loose the scroll.
23:34 And so I have that distance as long as that distance between the mouse and the
23:38 Slider button is beneath a certian amount.
23:42 And the mouse is pressed, then the variable Slider X takes on the current
23:46 mouse value for the X variable. So, it will slide with it.
23:51 On the other hand, I don't want it to go anywhere that the mouse goes.
23:55 And so I constrain it so it won't go off the end of the slider.
23:59 So, I use slider X and I constrain itself, and I limit it to the range of
24:03 the line that I drew. Also, at the end here, you see that I
24:07 have this minus one. I actually am stopping the slider one
24:11 pixel early on the right. The reason for that is if I run it all
24:15 the way to the edge on (INAUDIBLE), because the slider controls the row that
24:18 we're dealing with. The slider actually goes off the edge of
24:22 the data sheet and we get error messages. So, by subtracting one, I prevent that
24:26 array error from happening. Then I draw one circle, and then I draw a
24:32 smaller circle that is a different color on top, so it's a two color circle.
24:38 Then what I have, is I have a title above the slider, that simply says it's in the
24:42 center, and I gave it a color, and I positioned it down where I want it to be.
24:48 That's going to say Weeks. Then I have the minimum and maximum labels.
24:53 Those are going to be January 2005 and December 2012.
24:57 Those are each positioned at the end of the slider line.
25:00 Then I have the slider set data value. This is the important one right here,
25:04 where the row that we're currently reading on the data sheet Is a function
25:08 of the sliders. So, let's take a look at this for a second.
25:13 I have slider X there, that's where it's positioned and what I do, is I subtract
25:17 the left margin. So, I'm finding how far away from the
25:21 left margin is it, right? And then I divide that distance by the
25:26 width of the grid, GW is Grid Width. So, it's given me, what proportion of the
25:31 width, the slider has gone across. So, I first get the difference and I
25:35 divide it by the total range and that gives me a proportion anywhere from zero
25:38 to one. So, zero is when it's totally on the left
25:42 side, one is when it's all the way over on the right.
25:45 And then what I do is, I take that proportion and I multiply it times at the
25:48 row count. Remember the row count is 418.
25:52 So, I'm taking a number that's like .27 or .705, or whatever, and I'm multiplying
25:55 it times the row count. And then what I have to do, because that
26:00 could very easily give me a decimal value, and the row indexes have to be
26:04 whole numbers. I then wrap all of that in parenthesis,
26:08 and I put int in the front. And what that means is I'm taking the
26:12 result of that calculation and I'm casting it as an integer variable so it
26:15 has to be a whole number. And that way I can use the slider to
26:19 specify the row. Finally, the next line has the command
26:23 for some text that will appear above the slider, to say what the current row is,
26:28 based on the date labels, within the data sheet.
26:33 So, I have text, that's whenever I want to have something appear.
26:37 And then this long one, Composers, is the name of the data object.
26:41 And then .getstring means going into that object, go into that data sheet, and get
26:45 a string variable. And I want you to use the row that's the
26:49 up and down that has to do with the slider determining that.
26:53 And then use column 0, that's the first column in the data sheet that has the
26:57 dates listed. And then position it directly above the
27:01 slider, give it the same exposition as the slider, and put it just a little bit
27:04 above it. That's what the height of the window
27:08 minus the bottom margin, minus 25 pixels. Something I had to take a little bit of
27:12 trial and error with to get it a good height above the slider.
27:16 And that finishes the Slider function. The next part of this is the actual bar
27:21 graph itself. This is the one that actually shows the data.
27:25 I've created a function called Bar. And then it takes the arguments of the
27:29 left margin. The grid width, the bottom margin, the
27:34 bar width, the current number of the bar that it's drawing.
27:38 The total number of bars, that's bar n, the name of that bar that is the
27:42 composer's name, that's coming from an array.
27:46 And then the bar height, and that's going to be based off the data in the spreadsheet.
27:53 So, the first thing I do is I pick a color for the bars.
27:56 I've picked it from the Palette array that I have up earlier, and then I need
28:00 to create several variables that go into sort intermediate calculations.
28:05 The first one is bar H. That calculates the actual height of the
28:08 bar, and what it is is I use this one that's called bar height.
28:13 And, that's a variable that's going to be from zero to 100, and it's going to
28:16 appear in the, data sheet. And then I multiply that times, the grid
28:22 height by 100. Now the reason is, the grid is actually
28:25 300 pixels high. And if I took the bar heights, nothing
28:29 would get above 100 pixels. So, it would look like nobody ever went
28:33 about 33 percent. I need so that 100 in the data sheet goes
28:36 all the way to the top. So, by taking the bar height, which is
28:39 the number in the data sheet. And multiplying it times this value,
28:43 which is 300 pixels divided by 100, I triple it.
28:46 And it makes it so that 100 goes all the way to the top.
28:49 Next is a relatively long equation that I used to get the x coordinates, the left
28:53 right coordinates, for spacing the bars evenly.
28:57 This is called bar x and it's a floating point variable, and what I do is start
29:00 with the left margin. And then I take the number of the current
29:04 bar that goes from zero to four and then I add one so it converts it to one to
29:08 five and then I multiply that times a ratio.
29:13 The ratio is the grid width and then I'm dividing that grid width by the number of
29:17 bars plus one. So, if I want to split something in for
29:22 instance three equal pieces, I need to have two dividing lines.
29:26 Well, I'm going to have to actually instead of just having two dividing lines.
29:30 I have to divide the whole thing by three and put it into thirds so I can put those
29:33 two lines in the middle. That's why you have that add one onto it.
29:38 So, what do you have again, is the left margin and to that I add the product of
29:42 the bar index plus one. So, that converts into a one to five scale.
29:48 And then I multiply that times this ratio of the total grid with, divided by the
29:53 number of bars I want plus one. That gets me the even split points.
29:59 The next line after that is bar underscore, by.
30:02 And that is the y position for the bottom of the bar.
30:07 And again, part of this is because it's drawing the things upside down from what
30:10 you want. You think of zero on a graph as being at
30:13 the bottom. And then, as numbers get bigger, it goes up.
30:17 Well, in computer graphics, 0's at the top and a positive number goes down, and
30:21 so you sometimes have to go through these little machinations.
30:25 i get the total height of the window and I subtract the bottom margin, and that
30:28 tell some where all of them are supposed to be at the bottom.
30:32 That's the zero line on the grid. Then what I have is a variable called
30:36 Bar, and then TY for the top of the bar, the Y position.
30:41 And that's the one I get by subtracting bar h, that's the total height of the bar
30:44 that I got a few lines above, and subtracting that from the bottom position.
30:50 Again, it's because the numbers get smaller as you go up, and this is what
30:53 makes that transition. Finally, I have one that says, where do I
30:57 want the labels for the bar labels? That's the name of the composers, and
31:01 trial and error, I've found the number is 65 pixels.
31:04 So, that's 65 pixels from the top of the window.
31:06 The next part of the function actually draws the bar.
31:09 They're rectangles and what you do in a rectangle is specify by the top left
31:13 coordinates, the x and the y for the top left, and then how wide it is and how
31:17 tall it is. There are other ways to specify it, but
31:21 this one worked well for this. And so I do bar x, that gets me to the
31:24 middle of the bar, and then I subtract half the width of the bar to get to the
31:27 left edge. And bar t y is the y position of the top
31:32 of the bar. So, that gets me the coordinates for the
31:35 top left corner of the bar. BW is Bar Width, I set that as 100 pixels
31:39 earlier on. And then Bar H is the height of the bar
31:42 that gets derived from the data sheet. And that's how far it has to go to reach
31:46 the zero line at the bottom. Next, beneath that, and the last lines of
31:50 code in this whole thing, are the code to put the pictures of the composers above
31:54 the labels. So, I use image.
31:57 That's how you place pictures, and then I refer to the portraits.
32:01 That's an array that I created of the images, so I use portraits.
32:05 And then bar I means which index number, and that's 01234.
32:11 So, that tells me which image to place, and then I get the X and Y positions.
32:15 The bar underscore x minus BW2, that's how I positioned the bars themselves a
32:20 moment ago. And then I give them a vertical position
32:24 80 pixels down. That I got through trial and error, and
32:28 because the images are 100 pixels wide, and the bars are 100 pixels wide, this
32:31 will align them. Then I put labels on and I use Text Align
32:35 to center it, the left and right, that's the first one, and center top to bottom.
32:41 Then I pick a color that I want for this, that comes from the color array that I
32:44 called Palette. And then I actually put the name of the
32:48 composer that's text that appears, and that completes the entire code.
32:52 So, let me scroll back up to the top. And, when I run the sketch this is what
32:57 it looks like. At the top, Google Searches For Opera Composers.
33:03 Then the name and pictures of each of the composers.
33:06 Then I have five lines: zero, 25, 50, 75, 100.
33:11 And then I have bars at the bottom. And then the slider at the very bottom.
33:15 You see it currently is at January 2005. And, if I come down, and I click on that,
33:21 and I drag it across. We see the values changing for the
33:25 relative popularity of each composer's name as a search term during that week.
33:32 So, this is one week's data at a time. You see, what's interesting is that
33:35 things actually jump around a fair amount.
33:38 I got too far off the button. Although we see Verdi is generally very
33:44 popular, Mozart is generally very popular.
33:47 Now what we have is this breakout couple of years for Mozart, if I get about right
33:52 there we go. This is the highest search term for any
33:56 of these and again it's for Mozart opera. And so, December 2009, something
34:00 immensely popular for Mozart, have to go back and read Opera News to see what was
34:04 happening back then. And we see that others as we scroll
34:08 through, become more popular over time. Bizet had a breakout time in May of 2011.
34:15 He basically is only known for Carmen, so something significant was happening there.
34:21 Always scroll through to the end. Anyhow, that's where my particular
34:25 visualization looks like. And they will ask people to look at the
34:28 relative popularity of each of these composers across a several years span.
34:33 Now there is one more step to this project, and that is to save this as a
34:36 stand alone application. Let me show you how that works.
34:40 It's actually really, really easy to do in processing.
34:44 I'm going to close this window. And then you see how in the top right
34:51 corner of the window it says java in a small box?
34:55 We have some choices here. It is actually able to save things as
34:59 android applications and Javascript, although that one is still being fully
35:02 developed in the Beta. So, this particular sketch does not
35:06 convert cleanly to Javascript yet, but that will change.
35:10 And then there's an experimental mode, which means you'll be able to add other
35:12 modes as well. But I'm going to just leave it in Java
35:15 for right now. Then I'm going to come across to this
35:19 button with a right arrow on it. It says Export Application.
35:23 If I click that button, it's going to ask me what platforms do I want.
35:29 Windows, Mac, and Linux, I'll just save all three of them.
35:33 Then I have a couple of options. False screen is nice because it puts a
35:36 background to cover up other things. And a Stop button is also a good thing,
35:40 although you actually can stop by just hitting escape.
35:43 I'm going to hit Export, and it shows me that in the File browser, I now have five
35:48 new folders. The Windows 64 bit application, 32 bit
35:54 application, the Mac OSX and 64 and 32 bit Linux versions.
36:00 I'm on a Windows computer right now, so let me open up the application Windows 64.
36:06 And you see I've got this thing right down here.
36:08 If I double click on this one this Batch file, it's going to open up that window,
36:13 and now I've got the composers themselves.
36:17 This is a standalone application that could hide the other ones, and now this
36:20 is one that functions right here. A person doesn't have to have processing
36:25 on their computer to be able to run this. And if you're delivering a product to a
36:30 client, this can be a very convenient way for them to be able to use it.
36:36 Any time they have on their machines with or without an internet connection.
36:41 And so that is how I ultimately solved this end challenge project of creating an
36:46 interactive bar chart. To look at the Google Trends for opera
36:51 composers over a several year period. Hopefully you came up with something that
36:56 was interesting, exciting, and informative as well.
36:58 Thanks for working with me, and best of luck in your own work.
37:01
Collapse this transcript


Suggested courses to watch next:

Foundations of Programming: Fundamentals (4h 47m)
Simon Allardice


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,069 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,024 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked