灏天阁

数据可视化从入门到精通:JavaScript、D3.js、Plotly 等可视化库的实战应用

· Yin灏

一、数据可视化的基础知识

在学习任何可视化库之前,我们需要掌握一些基本概念,其中包括:

  1. 编程语言:JavaScript 是最常用的编程语言之一,用于编写许多数据可视化库。如果您已经熟悉 JavaScript,则可以跳过这一步骤。
  2. 数据分析和统计学:了解基本的数据分析和统计学概念,如数据类型、均值、中位数、标准差、相关性等。
  3. 图表类型:了解数据可视化中的不同图表类型及其应用场景,如直方图、散点图、折线图、条形图、饼图等。
  4. 数据可视化框架:了解一些常用的可视化框架,如 D3.js、Plotly 等。这些框架提供了大量的图表类型和交互功能,使我们可以轻松地创建交互式可视化。

二、什么是 JavaScript

JavaScript 是一种常用的编程语言,能够处理各种数据类型、创建动态效果,这些都是数据可视化中的重要组成部分。在学习数据可视化之前,您需要学习 JavaScript 的语法、基本数据结构和 DOM 操作。

您可以通过以下途径学习 JavaScript:

  1. 在线编程平台:例如 Codecademy、FreeCodeCamp、W3Schools 等平台提供免费的 JavaScript 课程和实践项目,可以加强您的实践。
  2. 书籍和教程:JavaScript 语言由 Douglas Crockford、Eloquent JavaScript 等著名作者写过令人信服的书籍和教程。
  3. 练习项目:起初,您可以从简单的练习项目开始,例如制作一个简单的 To-do List 应用程序,然后尝试编写更复杂的应用程序。

三、什么是 D3.js

D3.js 是一种常用的数据可视化库,它是 Data-Driven Documents 的缩写,开发人员可以使用它创建各种图表类型。

04022.jpg

您可以通过以下途径学习 D3.js:

  1. 官方文档:D3.js 官网提供了完整的文档和示例,可以帮助您了解 D3.js 的各种特性和用法。
  2. 书籍和教程:D3.js 有一些非常好的书籍和在线教程,如 Data Visualization with D3.js、D3.js Tips and Tricks,等等。
  3. 练习项目:创建一个简单的数据可视化项目,如制作一个散点图或折线图。一旦您掌握了基础知识,就可以挑战更复杂的图表类型,如力导向图或地图。

四、什么是 Plotly

Plotly 是另一个常用的数据可视化库,它提供了许多可视化功能,包括交互式图表、地图和 Dash 仪表板等。Plotly 具有跨平台性,支持 Python、R、JavaScript 和 MATLAB 等多种语言。

您可以使用以下途径学习 Plotly:

  1. 官方文档:Plotly 官网提供了完整的文档和示例,可以帮助您了解 Plotly 的各种特性和用法。
  2. 书籍和教程:Plotly 有一些非常好的书籍和在线教程,如 Plotly Fundamentals、Plotly Dash and Flask Tutorials 等。
  3. 练习项目:创建一个简单的数据可视化项目,如制作一个散点图或折线图。一旦您掌握了基础知识,就可以挑战更复杂的图表类型,如地图、3D 图表或交互式仪表板。

五、JavaScript 的实战应用

5.1 创建一个简单的散点图

散点图是一种用于显示两个数值变量之间关系的常用图表类型。下面是一个用 JavaScript 创建散点图的示例代码:

<!DOCTYPE html>
<html>
  <head>
    <title>Scatter Plot Example</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
  </head>
  <body>
    <div id="scatterplot"></div>
    <script>
      // 定义数据
      var data = [
        { x: 10, y: 20 },
        { x: 20, y: 30 },
        { x: 30, y: 40 },
        { x: 40, y: 50 },
        { x: 50, y: 60 },
      ];

      // 创建画布
      var margin = { top: 20, right: 20, bottom: 20, left: 20 };
      var width = 500 - margin.left - margin.right;
      var height = 400 - margin.top - margin.bottom;

      var svg = d3
        .select("#scatterplot")
        .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 + ")");

      // 创建比例尺
      var xScale = d3.scaleLinear().domain([0, 50]).range([0, width]);

      var yScale = d3.scaleLinear().domain([0, 80]).range([height, 0]);

      // 绘制散点图
      svg
        .selectAll(".dot")
        .data(data)
        .enter()
        .append("circle")
        .attr("class", "dot")
        .attr("cx", function (d) {
          return xScale(d.x);
        })
        .attr("cy", function (d) {
          return yScale(d.y);
        })
        .attr("r", 5);
    </script>
  </body>
</html>

5.2 创建一个简单的条形图

条形图是用于比较多个类别数据之间差异的一种图表类型。下面是一个用 JavaScript 创建条形图的示例代码:

<!DOCTYPE html>
<html>
  <head>
    <title>Bar Chart Example</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
  </head>
  <body>
    <div id="barchart"></div>
    <script>
      // 定义数据
      var data = [
        { category: "A", value: 10 },
        { category: "B", value: 20 },
        { category: "C", value: 30 },
        { category: "D", value: 40 },
        { category: "E", value: 50 },
      ];

      // 创建画布
      var margin = { top: 20, right: 20, bottom: 20, left: 20 };
      var width = 500 - margin.left - margin.right;
      var height = 400 - margin.top - margin.bottom;

      var svg = d3
        .select("#barchart")
        .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 + ")");

      // 创建比例尺
      var xScale = d3
        .scaleBand()
        .domain(
          data.map(function (d) {
            return d.category;
          })
        )
        .range([0, width])
        .padding(0.1);

      var yScale = d3.scaleLinear().domain([0, 50]).range([height, 0]);

      // 绘制条形图
      svg
        .selectAll(".bar")
        .data(data)
        .enter()
        .append("rect")
        .attr("class", "bar")
        .attr("x", function (d) {
          return xScale(d.category);
        })
        .attr("y", function (d) {
          return yScale(d.value);
        })
        .attr("width", xScale.bandwidth())
        .attr("height", function (d) {
          return height - yScale(d.value);
        });
    </script>
  </body>
</html>

六、D3.js 的实战应用

6.1 创建一个力导向图

力导向图是用于显示图形之间的连通性的一种图表类型。下面是一个用 D3.js 创建力导向图的示例代码:

<!DOCTYPE html>
<html>
  <head>
    <title>Force-directed Graph Example</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
  </head>
  <body>
    <div id="forcedirected"></div>
    <script>
      // 定义数据
      var nodes = [
        { id: "A", group: 1 },
        { id: "B", group: 1 },
        { id: "C", group: 2 },
        { id: "D", group: 2 },
        { id: "E", group: 3 },
        { id: "F", group: 3 },
      ];

      var links = [
        { source: "A", target: "B" },
        { source: "B", target: "C" },
        { source: "C", target: "D" },
        { source: "D", target: "E" },
        { source: "E", target: "F" },
      ];

      // 创建画布
      var width = 500;
      var height = 400;

      var svg = d3
        .select("#forcedirected")
        .append("svg")
        .attr("width", width)
        .attr("height", height);

      // 创建力导向布局
      var simulation = d3
        .forceSimulation(nodes)
        .force("link", d3.forceLink(links))
        .force("charge", d3.forceManyBody().strength(-100))
        .force("center", d3.forceCenter(width / 2, height / 2))
        .on("tick", ticked);

      // 绘制连线
      var link = svg
        .selectAll(".link")
        .data(links)
        .enter()
        .append("line")
        .attr("class", "link");

      // 绘制节点
      var node = svg
        .selectAll(".node")
        .data(nodes)
        .enter()
        .append("circle")
        .attr("class", "node")
        .attr("r", 10)
        .attr("fill", function (d) {
          return d.group === 1 ? "red" : d.group === 2 ? "blue" : "green";
        })
        .call(drag(simulation));

      // 节点拖动事件
      function drag(simulation) {
        function dragstarted(d) {
          if (!d3.event.active) simulation.alphaTarget(0.3).restart();
          d.fx = d.x;
          d.fy = d.y;
        }

        function dragged(d) {
          d.fx = d3.event.x;
          d.fy = d3.event.y;
        }

        function dragended(d) {
          if (!d3.event.active) simulation.alphaTarget(0);
          d.fx = null;
          d.fy = null;
        }

        return d3
          .drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended);
      }

      // 动态更新节点位置
      function ticked() {
        link
          .attr("x1", function (d) {
            return d.source.x;
          })
          .attr("y1", function (d) {
            return d.source.y;
          })
          .attr("x2", function (d) {
            return d.target.x;
          })
          .attr("y2", function (d) {
            return d.target.y;
          });

        node
          .attr("cx", function (d) {
            return d.x;
          })
          .attr("cy", function (d) {
            return d.y;
          });
      }
    </script>
  </body>
</html>

6.2 创建一个堆叠条形图

堆叠条形图是一种用于比较多个类别数据之间差异的一种图表类型,以及多个类别数据在整体中的比例。下面是一个用 D3.js 创建堆叠条形图的示例代码:

<!DOCTYPE html>
<html>
  <head>
    <title>Stacked Bar Chart Example</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
  </head>
  <body>
    <div id="stackedbarchart"></div>
    <script>
      // 定义数据
      var data = [
        { category: "A", value1: 10, value2: 20, value3: 30 },
        { category: "B", value1: 20, value2: 30, value3: 40 },
        { category: "C", value1: 30, value2: 40, value3: 50 },
        { category: "D", value1: 40, value2: 50, value3: 60 },
        { category: "E", value1: 50, value2: 60, value3: 70 },
      ];

      // 创建画布
      var width = 500;
      var height = 400;

      var svg = d3
        .select("#stackedbarchart")
        .append("svg")
        .attr("width", width)
        .attr("height", height);

      // 创建比例尺和堆叠布局
      var xScale = d3
        .scaleBand()
        .domain(
          data.map(function (d) {
            return d.category;
          })
        )
        .range([0, width])
        .padding(0.1);

      var yScale = d3.scaleLinear().domain([0, 150]).range([height, 0]);

      var stack = d3
        .stack()
        .keys(["value1", "value2", "value3"])
        .order(d3.stackOrderNone)
        .offset(d3.stackOffsetNone);

      // 绘制条形图
      var series = stack(data);

      svg
        .selectAll(".serie")
        .data(series)
        .enter()
        .append("g")
        .attr("class", "serie")
        .attr("fill", function (d) {
          return d.key === "value1"
            ? "#e41a1c"
            : d.key === "value2"
            ? "#377eb8"
            : "#4daf4a";
        })
        .selectAll("rect")
        .data(function (d) {
          return d;
        })
        .enter()
        .append("rect")
        .attr("x", function (d) {
          return xScale(d.data.category);
        })
        .attr("y", function (d) {
          return yScale(d[1]);
        })
        .attr("height", function (d) {
          return yScale(d[0]) - yScale(d[1]);
        })
        .attr("width", xScale.bandwidth());
    </script>
  </body>
</html>

七、Plotly 的实战应用

7.1 创建一个交互式散点图

交互式散点图可以让用户接触数据背后的细节,并探索与特定数据点相关的详细信息。下面是一个使用 Plotly 创建交互式散点图的示例代码:

<!DOCTYPE html>
<html>
  <head>
    <title>Scatter Plot Example</title>
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
  </head>
  <body>
    <div id="scatterplot"></div>
    <script>
      // 定义数据
      var data = [
        {
          x: [1, 2, 3, 4, 5],
          y: [10, 20, 30, 40, 50],
          text: ["A", "B", "C", "D", "E"],
        },
      ];

      // 定义布局和选项
      var layout = {
        title: "Scatter Plot Example",
        xaxis: { title: "X-axis" },
        yaxis: { title: "Y-axis" },
        hovermode: "closest",
      };

      var options = {
        modeBarButtonsToRemove: [
          "toImage",
          "toggleSpikelines",
          "sendDataToCloud",
        ],
      };
    </script>
  </body>
</html>

八、总结

掌握数据可视化需要多方面的努力和实践,但这些库提供了许多强大的工具,可以帮助您快速地创建交互式可视化。从基础开始,逐步学习 JavaScript、D3.js 和 Plotly,并通过练习项目来提高自己的技能。

- Book Lists -