D3 is an interactive JavaScript library for data visualization. It uses Scalar Vector Graphics (SVG) coupled with HTML and CSS to display charts and figures illustrating the numeric data. You can also use D3 to make scatter plots. Here is a step-by-step guide on how to make a scatter plot using D3.
Before even starting to code, we need a data set to base our chart on. For this example, we will take a basic 2D array of random numbers. Our array is:
var dataset1 = [[90, 20], [20, 100], [66, 44], [53, 80], [24, 182], [80, 72], [10, 76], [33, 150], [100, 15]];
We need to import the D3 script using the src
attribute and then initialize our SVG container with the appropriate width and height:
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="400"></svg>
To make the chart look more centered and clear, we need to set a margin for our SVG. We are making 4 variables; svg
, margin
, width
, and height
. svg
is initialized with the 500px width and 400px height. These widths and heights are then adjusted according to the 200px margin:
var svg = d3.select("svg"),
margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin
For discrete data visualization on the x-axis, we construct a Linear Scale or scaleLinear()
. scaleLinear()
uses the linear equation (y = mx + c) to interpolate domain and range across the axis:
var xScale = d3.scaleLinear().domain([0, 100]).range([0, width]),
yScale = d3.scaleLinear().domain([0, 200]).range([height, 0]);
We need to add title, x-axis label, and y-axis label to our plot. For this purpose, we will first append text
to our svg
, then set the position, style, and actual text attribute. To rotate our text for the y-axis, we will use transform and specify the angle of rotation:
// Step 5
// Title
svg.append('text')
.attr('x', width/2 + 100)
.attr('y', 100)
.attr('text-anchor', 'middle')
.style('font-family', 'Helvetica')
.style('font-size', 20)
.text('Scatter Plot');
// X label
svg.append('text')
.attr('x', width/2 + 100)
.attr('y', height - 15 + 150)
.attr('text-anchor', 'middle')
.style('font-family', 'Helvetica')
.style('font-size', 12)
.text('Independant');
// Y label
svg.append('text')
.attr('text-anchor', 'middle')
.attr('transform', 'translate(60,' + height + ')rotate(-90)')
.style('font-family', 'Helvetica')
.style('font-size', 12)
.text('Dependant');
Now, we need to add both of the axes. For the x-axis, we call d3.axisBottom
because we need to align it at the bottom of the canvas. For the y-axis, we call d3.axisLeft
because we want to align it to the left of the canvas.
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScale));
g.append("g")
.call(d3.axisLeft(yScale));
This is where the magic happens. We need to add a dot for every coordinate in our dataset1
. We supply dataset1
to the data
attribute and then make a circle for each coordinate. The cx
specifies the horizontal position of the circle, while cy
specifies the vertical position of the circle. Moreover, the r
specifies the radius of the circle. Then, we translate all the data points to match the translation of our axes. Finally, we color the data points red by giving the #CC0000
hex-code:
svg.append('g')
.selectAll("dot")
.data(dataset1)
.enter()
.append("circle")
.attr("cx", function (d) { return xScale(d[0]); } )
.attr("cy", function (d) { return yScale(d[1]); } )
.attr("r", 2)
.attr("transform", "translate(" + 100 + "," + 100 + ")")
.style("fill", "#CC0000");
Free Resources