-
Notifications
You must be signed in to change notification settings - Fork 287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exp scale #48
Conversation
Interesting. Do you have an example of where an exponential scale is useful? |
This came up for me while working on computing and rendering kernel density estimates in log-space. Imagine a histogram-type data structure, with buckets spaced at logarithmic intervals. One way to represent this is explicitly in a big array: var h = [
{'bucket': 1e0, 'count': 100},
{'bucket': 1e1, 'count': 200},
{'bucket': 1e2, 'count': 250},
{'bucket': 1e3, 'count': 120}
]; This is simple in the case of the four elements 1e0, 1e1, 1e2, and 1e3. But it gets much more tough when you want to (say) evenly-space the buckets in some other range, like [60, 15000], and you want 60 buckets. You could work on it yourself, but the var n = 60,
exp = d3.scale.exp().domain([0, n]).range([60, 15000]),
h = [];
for (var i = 0; i < n; i++) {
h.push({'bucket': exp(i), 'count': 0});
} It's also much nicer for things like rescaling, which came up for me in writing a streaming log-space histogram. |
The latest test fails - there is something wrong in my interpolation. Sorry for the premature PR! |
Okay, things are back - I missed a variable which needed to update when rescaling. |
That makes sense, though in your example you can easily replace the exp scale with log.invert: var n = 60,
log = d3.scaleLog().domain([60, 15000]).range([0, n]),
h = [];
for (var i = 0; i < n; i++) {
h.push({'bucket': log.invert(i), 'count': 0});
} (And it feels slightly more natural to call [60, 15000] the domain, since it’s a dimension of abstract data.) Can you expand this example, or provide another one, so that I can see how you’d use the exp scale as “a full scale object” as you suggested in the opening comment? So far, it seems like you could use log.invert to construct the histogram, and then maybe use a linear scale to display the histogram if you didn’t want to show the log transform. |
You know, I think you're right. Originally, I had been under the impression that I could then pass the Well, at least I learned stuff by trying to write a scale. Thanks for thinking this through, @mbostock! |
Thanks for your patience, and glad I could help. Plus, we’ll have a headstart if someone else discovers a use for an exp scale. :) |
I've added an exponential scale. This is the inverse of the logarithmic scale. It's not sufficient to merely use
scaleLog().invert
because that's just a method, not a full scale object, so it doesn't work happily with many other APIs like axis generators.I've neglected to write any documentation in this first commit because I want to get feedback first. I've also not written quite so many tests as perhaps I should, and much of the code elsewhere in this repo shows scars of having dealt with wacky inputs; I haven't tried very hard to anticipate all the possible wackiness out there and have left things pretty simple.