D3.js 산포도(Scatter Plot) 그리기

D3에서 기본 그래프, 산포도(Scatter Plot) 그리는 방법을 설명한다.

예제 프로그램

코드 확인

예제 코드

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>D3 Scatter Plot</title>
  <script src="https://d3js.org/d3.v7.min.js"></script>
</head>

<body>
  <script>
  // 1. 데이터 준비
  var dataset = [
    [5, 20],
    [480, 90],
    [250, 50],
    [100, 33],
    [330, 95],
    [410, 12],
    [475, 44],
    [25, 67],
    [85, 21],
    [220, 88]
  ];

  var width = 400; // 그래프 넓이
  var height = 300; // 그래프 높이
  var margin = { "top": 30, "bottom": 60, "right": 30, "left": 60 };

  // 2. SVG 영역 설정
  var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);

  // 3. 축 스케일(눈금) 설정
  var xScale = d3.scaleLinear()
    .domain([0, d3.max(dataset, function(d) { return d[0]; })])
    .range([margin.left, width - margin.right]);

  var yScale = d3.scaleLinear()
    .domain([0, d3.max(dataset, function(d) { return d[1]; })])
    .range([height - margin.bottom, margin.top]);

  // 4. 축 표시
  var axisx = d3.axisBottom(xScale).ticks(5);
  var axisy = d3.axisLeft(yScale).ticks(5);

  svg.append("g")
    .attr("transform", "translate(" + 0 + "," + (height - margin.bottom) + ")")
    .call(axisx)
    .append("text")
    .attr("fill", "black")
    .attr("x", (width - margin.left - margin.right) / 2 + margin.left)
    .attr("y", 35)
    .attr("text-anchor", "middle")
    .attr("font-size", "10pt")
    .attr("font-weight", "bold")
    .text("X Label");

  svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + 0 + ")")
    .call(axisy)
    .append("text")
    .attr("fill", "black")
    .attr("x", -(height - margin.top - margin.bottom) / 2 - margin.top)
    .attr("y", -35)
    .attr("transform", "rotate(-90)")
    .attr("text-anchor", "middle")
    .attr("font-weight", "bold")
    .attr("font-size", "10pt")
    .text("Y Label");

  // 5. Plot 표시
  svg.append("g")
    .selectAll("circle")
    .data(dataset)
    .enter()
    .append("circle")
    .attr("cx", function(d) { return xScale(d[0]); })
    .attr("cy", function(d) { return yScale(d[1]); })
    .attr("fill", "steelblue")
    .attr("r", 4);
  </script>
</body>

</html>

예제 코드 설명

산포도 그래프를 단계별 그리며 설명 페이지에서는 산포도를 작성하는 방법을 자세히 소개한다. 이 예제은 튜토리얼 외에도 상하좌우 margin의 각 설정과 Lable을 추가하고 있다.

1. 데이터 준비

여백을 설정하기 위해 객체를 선언하였다.

var margin = { "top": 30, "bottom": 60, "right": 30, "left": 60 };

하단과 왼쪽은 축을 표시하기 때문에 마진을 크게 설정한다.

2. SVG 영역 설정

SVG의 표시 영역을 설정한다.

3. 축 스케일 설정

축 스케일을 설정한다.

d3.scaleLinear()

위 코드는 domain(..)으로 설정한 범위를 range(..)로 설정한 범위로 변환하는 함수를 설정한다. 산포도의 좌표를 화면의 픽셀 값으로 변환하는 함수를 만든다.

4. 축 표시

D3의 함수 d3.axisBottom()d3.axisLeft()를 사용하여 축 요소를 설정한다. 인수를 축 스케일의 설정으로 설정한 함수로 하여, call로 호출하는 것으로 SVG 요소가 자동적으로 추가된다.

var axisx = d3.axisBottom(xScale).ticks(5);
var axisy = d3.axisLeft(yScale).ticks(5);

svg.append("g")
  .attr("transform", "translate(" + 0 + "," + (height - margin.bottom) + ")")
  .call(axisx)

svg.append("g")
  .attr("transform", "translate(" + margin.left + "," + 0 + ")")
  .call(axisy)

.ticks()는 메모리의 수를 제어하는 ​​메소드이다. 정수로 설정한다.

축을 호출하고, text 요소로 축 레이블을 추가한다.

.append("text")
.attr("fill", "black")
.attr("x", (width - margin.left - margin.right) / 2 + margin.left)
.attr("y", 35)
.attr("text-anchor", "middle")
.attr("font-size", "10pt")
.attr("font-weight", "bold")
.text("X Label");

.append("text")
.attr("fill", "black")
.attr("x", -(height - margin.top - margin.bottom) / 2 - margin.top)
.attr("y", -35)
.attr("transform", "rotate(-90)")
.attr("text-anchor", "middle")
.attr("font-weight", "bold")
.attr("font-size", "10pt")
.text("Y Label");

"text-anchor"는 텍스트의 위치 맞춤을 위한 속성으로, "middle"로 중앙 정렬을 설정하고 있다. 각각 축에 쓰이지 않도록 35px씩 이동하고 있다.

5. 플롯 표시

플롯을 circle 요소로 표시한다.

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

마무리

산포도는 가장 많이 사용하는 그래프 중 하나이다. 자세한 만드는 방법은 산포도 그래프를 단계별 그리며 설명에서 설명하고 있으므로, 이쪽도 참조하면 도움이 될것이다.




최종 수정 : 2024-01-18