Alex Rivera | Logout

Can d3.js draw two scatterplots on the same graph using data from the same source?

Asked 2012-07-26T15:11:44.287
13

All of the d3 tutorials I've found use data arranged in arrays of objects from which they graph one point for each object in the array. Given data in the following structure:

data = [
     {id: 1, x: 4, y: 10, type: 1},
     {id: 2, x: 5, y: 20, type: 2}
     ...
]

The x and y values are used to make a scatterplot. The type parameter is used to change the color of each point. See this jsfiddle for an example: http://jsfiddle.net/uxbHv/

Unfortuately, I have a different data structure and I can't figure out how to create the same graph by drawing two data points for each object. Here is some example data:

dataSet = [
     {xVar: 5, yVar1: 90, yVar2: 22},
     {xVar: 25, yVar1: 30, yVar2: 25},
     {xVar: 45, yVar1: 50, yVar2: 80},
     {xVar: 65, yVar1: 55, yVar2: 9},
     {xVar: 85, yVar1: 25, yVar2: 95}
]

I can graph xVar individually against yVar1 or yVar2, but I can not figure out how to get both on the same graph: http://jsfiddle.net/634QG/

Edit
Report

1 Answer

31

The general rule when using a data-join is that you want a one-to-one mapping from data to elements. So, if you have two series in your scatterplot, you’ll want two container elements (such as G elements) to represent the series. Since you currently have only one data array, you’ll also want to use array.map to convert the data representation into two parallel arrays with the same representation. This way, you don’t have to duplicate code for each series.

Say your data was represented in a CSV file with one column for the x-values, and multiple other columns for the y-values of each series:

x,y1,y2
5,90,22
25,30,25
45,50,80
65,55,9
85,25,95

If you want the code to be completely generic, you first need to compute the series’ names, such as ["y1", "y2"]. (If you added a third column to the CSV file, it might be ["y1", "y2", "y3"].) You can compute the names using d3.keys, which extracts the named properties from an object. For example, d3.keys({foo: 1, bar: 2}) returns ["foo", "bar"].

// Compute the series names ("y1", "y2", etc.) from the loaded CSV.
var seriesNames = d3.keys(data[0])
    .filter(function(d) { return d !== "x"; })
    .sort();

Now that you have the series names, you can create an array of arrays of points. The outer array represents the series (of which there are two) and the inner arrays store the data points. You can simultaneously convert the points to a consistent representation (objects with x and y properties), all

answered 2012-07-26T17:48:25.060

Your Answer