17、数据可视化:地理数据与流式数据的探索

数据可视化:地理数据与流式数据的探索

地理数据可视化

在地理数据可视化方面,有许多不同的投影方式,D3支持从标准的墨卡托投影到像阿尔伯斯美国投影这样非常特殊的投影。下面是一个简单的表格展示部分投影类型:
| 投影类型 | 描述 |
| ---- | ---- |
| 墨卡托投影 | 标准的投影方式,常用于世界地图 |
| 阿尔伯斯美国投影 | 针对美国地区的特殊投影 |

我们可以轻松地将不同数据源结合起来,快速创建选举地图。并且可以在地图上添加自定义形状,如圆形,来增强标准投影效果。还能提供一个简单的下拉菜单,用于探索不同的支持投影。甚至可以通过创建旋转地球来对投影进行动画处理,同样也是将各种数据源结合在一起创建最终的可视化效果。

流式数据可视化

流式数据可视化可以创建多种类型的图表,下面是要创建的可视化图表类型:
1. 简单流式线图:使用鼠标数据绘制两条水平线条,线条从屏幕右侧向左侧移动,每个点代表鼠标在x轴或y轴上的总移动距离,图表底部有一个显示当前时间的轴,会与线图一起移动。
2. 心率和呼吸监测图:可视化从后端服务器通过WebSocket推送的心率和呼吸数据。
3. 流图:创建一个流图来可视化通过WebSocket接收的数据。
4. 实时活动信息地图:在D3渲染的地图上显示Meetup.com上公共会议的实时RSVP信息。

简单流式线图

要实现简单流式线图,需要按照以下步骤进行:
1. 设置比例尺 :定义用于渲染底部刻度和确定每个图形元素x和y位置的各种比例尺。

var duration = 500;
var nPoints = 120;
// the array that will keep our data
var data = d3.range(0, nPoints - 1).map(function () {
    return { x: 0, y: 0 }
});
// setup the scales. The domain is the x-axis, containing 400 points
// the y axis is based on the min and max values of the data
var x = d3.scaleLinear().domain([0, nPoints - 2]).range([0, width]);
var y = d3.scaleLinear().domain([0, 500]).range([height, 0]);
// scale to use for rendering the time axis
var now = new Date(Date.now() - duration);
var xTime = d3.scaleTime()
  .domain([now - ((nPoints - 2) * duration), now])
  .range([0, width]);

这里使用了三个比例尺:
- x :用于确定线图中各点的x位置,是一个简单的线性比例尺,根据总点数( nPoints )划分宽度,不使用从0到 nPoints 的定义域,而是到 nPoints - 2 ,避免渲染最新的两个点。
- y :用于确定图中每个点的y位置,是一个简单的比例尺,将最大值设置为任意值(这里是500)。
- xTime :用于时间的比例尺,使用日期定义其定义域,创建一个与x轴定义域镜像的定义域。

  1. 收集鼠标数据 :使用鼠标作为输入,通过监听鼠标移动事件,计算鼠标在x轴和y轴上的移动距离。
var previousEvent;
var totalX = 0;
var totalY = 0;
d3.select("body").on("mousemove", function () {
    if (previousEvent) {
        totalX += Math.abs(previousEvent.x - d3.event.screenX);
        totalY += Math.abs(previousEvent.y - d3.event.screenY);
        d3.select(".xText").transition().text("X-Movement:" + totalX);
        d3.select(".yText").transition().text("Y-Movement:" + totalY);
    }
    previousEvent = { x: d3.event.screenX, y: d3.event.screenY };
});
  1. 设置动画和图形 :使用 d3.line 函数绘制线条,这里使用 d3.curveBasis 绘制流畅的曲线。
var lineMx = d3.line()
  .curve(d3.curveBasis)
  .x(function (d, i) { return x(i) })
  .y(function (d) { return y(d.x); });
var lineMy = d3.line()
  .curve(d3.curveBasis)
  .x(function (d, i) { return x(i) })
  .y(function (d) { return y(d.y); });

创建包含线条的组和底部的轴:

var group = svg.append("g").attr("class", "group");
group.append("path").datum(data).attr("class", "lineX line");
group.append("path").datum(data).attr("class", "lineY line");
var axis = d3.axisBottom(xTime);
var axisGroup = svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(0 " + (height) + ")")
  .call(axis);

为了实现线条从右到左的流畅移动,采取以下步骤:

graph LR
    A[推送新数据点到数组] --> B[用新点绘制线条(在屏幕外绘制)]
    B --> C[开始过渡以将组向左移动]
    C --> D[同时开始过渡以移动轴]
    D --> E[过渡完成后,移除数组的第一个元素并重新开始过程]

代码实现如下:

group.transition().on("start", render)
  .ease(d3.easeLinear).duration(duration);
function render() {
    // add new point to the array and reset the data
    data.push({ x: totalX, y: totalY });
    totalX = 0; totalY = 0;
    // select current element
    d3.select(this).attr("transform", "");
    // redraw the lines
    d3.select(".lineX").attr("d", lineMy);
    d3.select(".lineY").attr("d", lineMx);
    // redefine the timescale, so we can move the axis
    var now = new Date(Date.now() - duration);
    xTime.domain([now - (nPoints - 2) * duration, now]);
    // for the duration, move the axis
    axisGroup.transition().duration(duration)
      .ease(d3.easeLinear).call(axis);
    // Move the lines
    d3.active(this).transition().on("start", renderX)
      .attr("transform", "translate(" + x(-1) + ",0)");
    // remove element from the array
    data.shift();
}
  1. 添加裁剪路径和额外信息 :为了隐藏线图最右侧的两个波动点,使用裁剪路径。
svg.append("defs").append("clipPath")
  .attr("id", "clip")
  .append("rect")
  .attr("width", "width")
  .attr("height", height + margin.bottom + margin.top);
svg.attr("clip-path", "url(#clip)");

在图表的左上角添加两个简单的计数器:

svg.append("text").attr("class", "xText").attr("transform", "translate(0 20)")
  .attr("stroke", "steelblue").text("X-Movement: ");
svg.append("text").attr("class", "yText").attr("transform", "translate(0 40)")
  .attr("stroke", "red").text("Y-Movement: ");

在鼠标移动事件监听器中更新计数器的值,在 render 函数中重置计数器的值。

心率和呼吸监测

要实现心率和呼吸监测可视化,需要按照以下步骤进行:
1. 获取样本数据 :从PhysioNet的Fantasia数据库下载呼吸和ECG数据,该数据库提供了2小时的40个人的呼吸和ECG信息。每个记录由三个文件组成,需要将其从MIT信号文件格式转换为简单的文本格式。

graph LR
    A[下载Fantasia数据库文件] --> B[安装PhysioNet转换软件]
    B --> C[使用rdsamp工具转换文件]
    C --> D[保存转换后的文本文件]

使用以下命令进行转换:

rdsamp -r f1y01 | head -n 15000 > yng.csv

转换后的文件内容示例如下:
| 序号 | 呼吸信息 | ECG |
| ---- | ---- | ---- |
| 0 | 16000 | 15904 |
| 1 | 16088 | 15872 |
| 2 | 16000 | 16008 |
| 3 | 16104 | 16128 |
| 4 | 16024 | 15960 |
| 5 | 16128 | 15912 |
| 6 | 16056 | 15968 |
| 7 | 16120 | 16144 |
| 8 | 16056 | 15992 |
| 9 | 16168 | 15856 |

  1. 创建WebSocket服务器 :创建一个简单的WebSocket服务器,将转换后的数据推送给前端。
  2. 创建D3可视化 :创建一个D3可视化,对服务器推送的信息做出响应,更新绘制的线条。

通过以上步骤,可以实现流式数据的可视化,包括简单流式线图和心率呼吸监测图等。不同的可视化类型可以根据具体需求进行调整和扩展,为数据展示提供更丰富的方式。

数据可视化:地理数据与流式数据的探索

流图可视化

流图是D3提供的一种替代区域可视化方式。在这个例子中,我们将创建一个流图来可视化通过WebSocket接收的数据。虽然文中未详细给出流图实现的具体代码,但基本思路和前面的例子类似,大致步骤如下:
1. 设置比例尺 :和前面的例子一样,需要设置合适的比例尺来确定流图中元素的位置和大小。
2. 连接WebSocket :建立与提供数据的WebSocket的连接。
3. 更新流图 :每当WebSocket推送新的数据时,更新流图的绘制。

Meetup实时信息地图可视化

Meetup.com是一个可以轻松组织本地聚会的网站。对于公共会议,它提供了一个开放的WebSocket API,每当收到RSVP(回复是否参加)时会发送更新。我们可以利用这些信息在D3渲染的地图上显示实时信息。具体步骤如下:
1. 渲染地图 :使用D3的地理数据可视化功能渲染地图,这里可以参考前面地理数据可视化部分提到的投影方式和地图绘制方法。
2. 连接WebSocket :建立与Meetup.com的WebSocket API的连接。
3. 更新地图信息 :当收到WebSocket推送的RSVP更新时,在地图上相应位置更新实时信息。

总结

本文主要介绍了地理数据可视化和流式数据可视化的相关内容。下面通过一个表格总结不同可视化类型及其关键步骤:
| 可视化类型 | 关键步骤 |
| ---- | ---- |
| 地理数据可视化 | 1. 选择合适的投影方式;2. 结合不同数据源创建地图;3. 添加自定义形状;4. 提供投影选择下拉菜单;5. 对投影进行动画处理 |
| 简单流式线图 | 1. 设置比例尺;2. 收集鼠标数据;3. 设置动画和图形;4. 添加裁剪路径和额外信息 |
| 心率和呼吸监测 | 1. 获取样本数据;2. 创建WebSocket服务器;3. 创建D3可视化 |
| 流图可视化 | 1. 设置比例尺;2. 连接WebSocket;3. 更新流图 |
| Meetup实时信息地图可视化 | 1. 渲染地图;2. 连接WebSocket;3. 更新地图信息 |

不同可视化类型的对比

为了更清晰地对比不同可视化类型,我们可以用一个mermaid格式的流程图来展示它们的主要区别和联系:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A([开始]):::startend --> B(地理数据可视化):::process
    A --> C(流式数据可视化):::process
    C --> D(简单流式线图):::process
    C --> E(心率和呼吸监测):::process
    C --> F(流图可视化):::process
    C --> G(Meetup实时信息地图可视化):::process
    B --> H(选择投影方式):::process
    B --> I(结合数据源):::process
    D --> J(设置比例尺):::process
    D --> K(收集鼠标数据):::process
    E --> L(获取样本数据):::process
    E --> M(创建WebSocket服务器):::process
    F --> N(连接WebSocket):::process
    G --> O(渲染地图):::process
    G --> P(连接WebSocket):::process

拓展与应用

这些可视化技术在很多领域都有广泛的应用:
- 地理数据可视化 :可以用于展示人口分布、商业活动分布等地理相关的数据,帮助决策者更好地了解地理区域的情况。
- 流式数据可视化
- 简单流式线图可以用于实时监测鼠标活动等用户行为数据。
- 心率和呼吸监测图可以应用于医疗领域,实时监测患者的生命体征。
- 流图可视化可以用于展示随时间变化的多变量数据,如股票市场的不同板块的资金流向。
- Meetup实时信息地图可视化可以帮助活动组织者实时了解参与者的响应情况,优化活动安排。

通过掌握这些可视化技术,我们可以更好地处理和展示各种类型的数据,为数据分析和决策提供有力支持。在实际应用中,可以根据具体需求对这些技术进行调整和扩展,创造出更符合实际场景的可视化效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值