[live code here – each time you click run, you’ll get a new random walk as the dataset]
One of the cool side-effects of creating graphs from scratch is having to really think about what defines a particular graph or function. Today was about the histogram!
Ignore the terrible color choices and lack of labels. Better things will come in time. The left chart are the values of the random walk. Red highlights areas of significant change. On the right is a histogram of the values. Pink is negative bins and grey are positive. I’m currently using a bin width of 7. There are 1000 values, with a start point of zero and a maximum step between points of 5.
I actually wrote three slightly different functions for binning, all based on the suggestion here. The main challenge was what I wanted to do with the bin & value information once I had it. Put it in an array? In an object? In an array of objects? If you click on the super tiny picture below, you can see the three ways I was considering storing the data. While it made the histogram function a little less elegant, I eventually opted for the array of objects in order to make it easy to create the chart (test2 in the picture). Deciding how to store the data was a great exercise in getting to know arrays vs objects more intimately. Sending out a thank you to my colleague Cesar for helping me think through the options!
If you look closely, you’ll also notice an interesting javascript oddity. The “test” array seems to have fewer elements than the others. This is because each object was created as array[bin] = value. When the bin is positive, the array treats it as an index which it assumes start at 0. The methods on this array also assume that it start as zero, so array.length only counts the number of positive bins. Interestingly, you can actually access the negative ones by array[-1], etc. They’re still there, sort-of. Mostly, javascript didn’t mind that I created an array with negative indices so didn’t stop me, it’s my problem to figure out if that’s what I actually wanted to do or not :).
Three versions below (click to enlarge):
Re arr[-1] — what you’re seeing here is Javascript’s “everything is an object” behavior, and you can always add an arbitrarily named property to an object. So you’ve just added a property to your array named “-1″… and in the same way as you can do “arr[-1] = ‘helloworld’; console.log(arr[-1])” you can also do “arr[‘foo’] = ‘helloworld’; console.log(arr[‘foo’])”.
For a really exciting time, try
var arr = [0, 1, 2];
arr[-1] = -1;
// contrast the outputs of…
arr.forEach(function(a){console.log(a)}) // use the array-specific iteration method
for (a in arr) { console.log(arr[a])} // iterate over all object properties
Thanks Alison!
I just ran into forEach for the first time yesterday. This nicely reinforces the fact that the forEach method is specific to arrays, so it will treat the array as an array. Looking back, that makes sense, as forEach failed when I tried it on a non-array object. Now it’s much more clear to me 🙂
And, I’m glad that there is a way to use a ‘for loop’ to treat the array as an object and access the other parts of it. I was struggling to find any way to get at those parts of the object as they just seemed invisible unless called one by one. But, I guess that in essence is what the for loop is doing. That said, I imagine it’s probably better to avoid doing things like arr[-1] = -1 even if I can get to it via a for loop, in order to keep things simple & avoid unexpected results if I use an array method on the array.
var arr = [0,1,2];
undefined
arr[-1] = -1;
-1
arr.forEach(function(a){console.log(a)})
0
1
2
undefined
for (a in arr) { console.log(arr[a])};
0
1
2
-1
undefined