Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I plot positive and negative values for both axes in a scatter plot with d3?

Tags:

d3.js

I'm using d3 to build a scatter plot and the set of values I have for the x and y axes both have positive and negative values. This is my first attempt at using d3 and I've gathered from introductory tutorials such as On the tenth day of Xmas, get dirty with data using d3.js, that the key is setting up the x and y scales correctly.

Next, I found this tutorial: Bar Chart with Negative Values, which has almost helped me get it right (I think). My data set is too hefty to place here, but here is the code I have a sample of my data to work with:

<div id="compareAll"></div>
<script>
window.onload = function() {

var dataSet = [ [4,4], [-4,4], [-4,-4], [4,-4], ];
var x0 = Math.max(-d3.min(dataSet[0]), d3.max(dataSet[0]));
var xScale = d3.scale.ordinal()
             .domain([-x0,x0])
             .range([0,10]);
var yScale = d3.scale.ordinal()
             .domain(d3.range(dataSet[1])
             .rangeRoundBands([0,10]);

var svg = d3.select("#compareAll")
.append("svg")
.attr("width", 10)
.attr("height",10)

svg.selectAll("circle")
.data(dataSet)
.enter()
.append("circle")
.attr("cx", function(d) {
      return xScale(d[0]); 
})
.attr("cy", function(d) {
      return yScale(d[1]); 
})
.attr("r",4); 

var xAxis = d3.svg.axis()
.scale(xScale)
.tickSize(1);

var yAxis = d3.svg.axis()
.scale(yScale)
.tickSize(1);

svg.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0,10)")
.call(xAxis);

svg.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(10,0)")
.call(yAxis);

}

</script>

Frankly, I don't understand the use of the ordinal scale in the Bar Chart example, however I got seemly worse results when I took it out and made the yScale with the same syntax as the xScale.

Any explanation of the best way to go about working with positive and negative values for both axes would be appreciated. Let me know if I'm missing something obvious. I through together this example from a much larger project as to make it as specific and easy to read as possible.

Thanks!

like image 854
eyount Avatar asked May 01 '12 18:05

eyount


People also ask

Can scatter plots have negative numbers?

A scatter plot can show a positive relationship, a negative relationship, or no relationship. If the points on the scatter plot seem to form a line that slants up from left to right, there is a positive relationship or positive correlation between the variables.


1 Answers

There's nothing special about using negative values for your axes - you should simply be using linear scales for your axes, and setting the domain to [min, max], where min might well be negative.

See a working version of your code here: http://jsfiddle.net/nrabinowitz/qN5Sa/

A few notes on this:

  • You should definitely use linear scales for a scatterplot, unless you want more of a matrix. A standard x-scale might look like this:

    var xScale = d3.scale.linear()
         .domain([-5, 5])
         .range([0,w]);
    
  • The d3.svg.axis() component includes an .orient() setting - by default, this is "bottom", i.e. a horizontal axis with numbers below the line. To make a correctly oriented y-axis, use .orient('left').

  • I didn't include the code to determine the min/max domain for each axis based on your data, because I figured it would complicate the example. But you can do this fairly easily if you don't know the bounds of your data:

    // assuming data like [[x0,y0], [x1,y1]]
    var xmin = d3.min(data, function(d) { return d[0] }),
        xmax = d3.max(data, function(d) { return d[0] }),
        ymin = d3.min(data, function(d) { return d[1] }),
        ymax = d3.max(data, function(d) { return d[1] });
    
like image 139
nrabinowitz Avatar answered Oct 27 '22 16:10

nrabinowitz