Search code examples
d3.jsscalingscatter-plot

X and Y axis are getting cut from edge in d3js


I have some dummy data in the data array and I want to make scatter plot from it. The rank is plotted on the y-axis and admit_probability on the x-axis. I am able to locate all the 5 points that I have but th axes are incomplete from edges. The script I have is shown below:

var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;

var data = [{"admit_probability":54,"rank":20},
            {"admit_probability":79,"rank":111},
            {"admit_probability":70,"rank":68},
            {"admit_probability":12,"rank":1},
            {"admit_probability":197,"rank":87}];

var xscale = d3.scaleLinear()
              .domain(d3.extent(data, function(d) { return +d.admit_probability; }))  
              .range([0, width]);

var yscale = d3.scaleLinear()
              .domain(d3.extent(data, function(d) { return +d.rank; }))
              .range([height, 0]);

var xAxis = d3.axisBottom().scale(xscale);

var yAxis = d3.axisLeft().scale(yscale);

var svg = d3.select("#content-box")
    .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
    .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.selectAll("dot")
    .data(data)
    .enter().append("circle")
    .attr("r", 3.5)
    .attr("cx", function(d) { return xscale(+d.admit_probability); })
    .attr("cy", function(d) { return yscale(+d.rank); });

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


svg.append("text")
    .attr("transform", "translate(" + (width / 2) + " ," + (height + margin.bottom) + ")")
    .style("text-anchor", "middle")
    .text("Average Acceptance");

svg.append("g")        
    .attr("class", "y axis")
    .call(yAxis);

// Add the text label for the Y axis
svg.append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 0 - margin.left)
    .attr("x",0 - (height / 2))
    .attr("dy", "1em")
    .style("text-anchor", "middle")
    .text("Rank");

What I am getting from this is as shown in the link scatter plot . The axes are getting cut from the end. Kindly someone help. I am not able to understand the issue.


Solution

  • You can try .nice() on your scale's domains which tries to generate nicer extents on your domain, by rounding up/down the min/max values to round numbers, for example

    var xscale = d3.scaleLinear()
                  .domain(d3.extent(data, function(d) { return +d.admit_probability; })).nice()
                  .range([0, width]);
    
    var yscale = d3.scaleLinear()
                  .domain(d3.extent(data, function(d) { return +d.rank; })).nice()
                  .range([height, 0]);
    

    enter image description here