Color scatterplot based on third variable

822 views
Skip to first unread message

Dylan Burkhardt

unread,
Sep 5, 2014, 11:09:45 AM9/5/14
to dc-js-us...@googlegroups.com
I am attempting to color a scatterplot based on a third variable and was wondering what the best approach to accomplish this would be in DC-JS. Currently when I add in the third variable to my scatterplot, it ruins the filtering of the other related graphs. Has anyone accomplished this and what would be the ideal way to achieve a scatterplot with x,y coordinates that are colored based on a z-value.

Thanks

Dylan Burkhardt

unread,
Sep 5, 2014, 9:48:06 PM9/5/14
to dc-js-us...@googlegroups.com
Here's some more info to make things more clear.

I was able to use this code on the scatterplot to get the coloring to work:
.colors(d3.scale.ordinal().domain(["yes", "no"])
                                    .range(["green", "red"]))
            .colorAccessor(function (d) {
                if (d.key[2] == 1) {
                    return "yes";
                } else {
                    return "no";
                }

After I added 'd.z' to my dimension:

        var ndx = crossfilter(data.value),
            runDimension = ndx.dimension(function (d) { return [d.x, d.y, d.z]; }),
            speedSumGroup = runDimension.group();

However... whenever I try to filter/brush my scatterplot in this scenario all of my other charts go blank/infinity. 

Thanks for your help,
Dylan

Dylan Burkhardt

unread,
Sep 12, 2014, 11:46:03 AM9/12/14
to dc-js-us...@googlegroups.com
Any suggestions here? Having trouble figuring out what I'm doing wrong. Thanks!

Gordon Woodhull

unread,
Sep 12, 2014, 12:24:25 PM9/12/14
to Dylan Burkhardt, dc.js user group
Hi Dylan,

You probably want to reduce the variable that is going to control the color into the value, not the key.  (Or you could add a key accessor, but color is more value-like.)

Usually when you have multiple values in a reduction, you'll have to specify a custom reduce function, because the default reduction just adds a single numeric value. Ethan Jewett's reductio library can help with this: 


Cheers,
Gordon

Gordon Woodhull

unread,
Sep 12, 2014, 12:35:53 PM9/12/14
to Dylan Burkhardt, dc.js user group
Hmm, I guess I misunderstood reductio, it does multiple aggregations but only on a single variable. Instead, maybe take a look at the annotated source of the stock example:

http://dc-js.github.io/dc.js/docs/stock.html

The yearlyPerformanceGroup shows reducing multiple values in a single group.

(Now I'm thinking about whether reductio could support multiple values. ;)

Dylan Burkhardt

unread,
Sep 12, 2014, 1:55:11 PM9/12/14
to dc-js-us...@googlegroups.com, umh...@gmail.com
Thanks... I think that's my problem. Will keep playing around with it.

I've also seen polybrushing (http://bl.ocks.org/gtb104/3667340) mentioned around here, but I'm unclear if it was ever added into the code. Is this possible?

Thanks!

Dylan Burkhardt

unread,
Sep 12, 2014, 4:20:58 PM9/12/14
to dc-js-us...@googlegroups.com, umh...@gmail.com
So I mostly got the coloring right and it updates other graphs, but I'm having trouble re-filtering the scatterplot... The following reduce function is able to remove items when they are filtered by some other graph, but they never come back. What am I missing in my first callback?

Group = runDimension.group().reduce(
                function(p, v) {
                    p.COUNT+= v.COUNT;
                    p.Z+= v.Z;
                    p.X+= v.X;
                    p.Y+= v.Y;
                    return p;
                },
                /* callback for when data is removed from the current filter results */
                function(p, v) {
                    p.COUNT-= v.COUNT;
                    p.Z-= v.Z;
                    p.X-= v.X;
                    p.Y-= v.Y;
                    p--;
                    return p;
                },
                /* initialize p */
                function() {
                    return { Z: 0, COUNT: 0, X:0, Y: 0 };
            });

Gordon Woodhull

unread,
Sep 12, 2014, 4:53:59 PM9/12/14
to Dylan Burkhardt, dc.js user group
p-- is probably not a good idea ;-) but I'm surprised if removal works at all with that there.

If that's not the problem, could you post a jsfiddle demonstrating it?

Dylan Burkhardt

unread,
Sep 12, 2014, 4:55:03 PM9/12/14
to dc-js-us...@googlegroups.com, umh...@gmail.com
I will work on setting up a JSFiddle... Without the p--, it was just changing the colored data when another graph was filtered. With the p--, it removed it on filter. Will add JSFiddle shortly.

Gordon Woodhull

unread,
Sep 12, 2014, 5:10:01 PM9/12/14
to Dylan Burkhardt, dc.js user group
Ah, okay, I think I understand what you're doing then.  No need to post a fiddle.

So when you do --p on an object, it just sets it to NaN, and there is no way of getting the object back.  The NaN causes the dots to go transparent, but it's not really zero.

Unfortunately, since the scatter plot is directly accessing the d.value in a couple of places to determine whether to show a symbol or not, and it's overloading the valueAccessor to mean Y, I don't think there is a way around this just yet.

Sorry, I thought that the scatterplot works like the other charts, but the valueAccessor override is just strange.  You might try the bubble chart, which IMHO was a little better thought-out.  (It doesn't have symbols and it has a sometimes-unwanted minimum radius, though).

Dylan Burkhardt

unread,
Sep 12, 2014, 5:40:05 PM9/12/14
to dc-js-us...@googlegroups.com, umh...@gmail.com
Thanks.. Will play around with the bubble chart.. If I understand correctly though, the bubble chart doesn't allow brushing. So not sure that's my best bet either.

Thanks again.

Gordon Woodhull

unread,
Sep 12, 2014, 5:48:16 PM9/12/14
to Dylan Burkhardt, dc.js user group
Alright, I was annoyed enough by this that I put in a partial fix.  (This particular problem was my fault, too.)

Please try the latest on master.  I added a completely non-breaking change that adds an existenceAccessor, so that at least you can reduce multiple values.  By default it will just use d.value as now, but you should now be able to specify

chart.existenceAccessor(function(d) { return d.COUNT; })

and have any other values you need in there.

I also filed a ticket to rethink the way keys and values are accessed in the scatter plot

Dylan Burkhardt

unread,
Sep 12, 2014, 6:00:16 PM9/12/14
to dc-js-us...@googlegroups.com, umh...@gmail.com
Testing this out and it looks perfect. Thank you for the help!

Nico Hofmeester

unread,
Mar 6, 2015, 3:17:10 PM3/6/15
to dc-js-us...@googlegroups.com, umh...@gmail.com
I am trying to accomplish the same thing, see this fiddle: http://jsfiddle.net/za8ksj45/8/
If you uncomment line 210, you have working selection in the right most scatter plot but no colors
If (re)comment line 210, you have the colors but the original issue described in this post.

I could not get it to work using Gordon's .existenceAccessor function.
Any help to allow colors as well as selection would be great.

Thanks,


Dylan Burkhardt

unread,
Mar 22, 2016, 2:51:27 PM3/22/16
to dc-js user group, umh...@gmail.com
Re-upping this old topic, any idea how to do something similar to colorAccessor by changing the symbol instead? So a symbolAccessor? 

Thanks

Gordon Woodhull

unread,
Mar 22, 2016, 4:17:50 PM3/22/16
to dc.js user group, umh...@gmail.com
Hi Dylan,

Although it's not explicitly named an accessor, it looks like chart.symbol() will take an accessor function which takes the key/value data and returns one of the symbol type names.


Cheers,
Gordon


-- 
You received this message because you are subscribed to the Google Groups "dc-js user group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dc-js-user-gro...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dc-js-user-group/188ca001-e313-4168-8706-5171739bf23b%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages