gpt4 book ai didi

javascript - D3 vs Scipy(Voronoi 图实现)

转载 作者:行者123 更新时间:2023-11-30 16:35:39 24 4
gpt4 key购买 nike

背景

我正在处理 csv 文件中包含的一组 8000 个地理点。一方面,我创建了使用这些点构建的 Voronoi 图的可视化 - 它是使用 D3 库完成的。另一方面,我使用 Scipy 在 Python 中计算了这些 Voronoi 图。

我的工作逻辑很简单——我在 Python 端处理我的数据,制作热图、分析等等,然后我使用 D3 可视化效果。但是今天无意间发现Scipy和D3做的Voronoi图不一样。我注意到在使用 geojson.io 绘制用 Python 制作的 Voronois 的 GeoJson 之后,我只是想看看我是否可以将那里的所有内容可视化。

正如我所说,Voronois 是不同的 - 其中一些有不同的 Angular ,有些甚至有额外的顶点。

问题:

为什么会这样?为什么这两个库(D3 和 Scipy)计算出的 Voronoi 图不同?

进一步说明

如何在 D3 端完成:基于 Chris Zetter 示例 http://chriszetter.com/blog/2014/06/15/building-a-voronoi-map-with-d3-and-leaflet/我将纬度和经度转换为自定义投影,以便在 mapbox map 上将其可视化。

var voronoi = d3.geom.voronoi()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.clipExtent([[N_W.x , N_W.y],[S_E.x, S_E.y]])

我根据 map 边界内可见的点 + 一些填充 (filteredPoints) 创建 Voronoi

  filteredPoints = points.filter(function(d) {
var latlng = new L.LatLng(d.latitude, d.longitude);
if (!drawLimit.contains(latlng)) { return false };
// this translates points from coordinates to pixels
var point = map.latLngToLayerPoint(latlng);
key = point.toString();
if (existing.has(key)) { return false };
existing.add(key);
d.x = point.x;
d.y = point.y;
return true;
});

voronoi(filteredPoints).forEach(function(d) { d.point.cell = d});

如何在 Python 端完成:我使用 scipy.spatial.Voronoi。

from scipy.spatial import Voronoi

def create_voronois():
points = numpy.array(points_list)
vor = Voronoi(points)

其中“points_list”是我的 8000 个地理点的列表。

编辑:

我的可视化屏幕截图 - 黑色边框是用 D3 制作的 Voronois,白色边框是由 scipy.spatial.Voronoi 制作的。我们可以看到 scipy 是错误的。有人比较过这两个库吗?

http://imgur.com/b1ndx0F

要运行的代码。它使用计算错误的 Voronois 打印 GeoJson。

import numpy
from scipy.spatial import Voronoi
from geojson import FeatureCollection, Feature, Polygon

points = [
[22.7433333333000, 53.4869444444000],
[23.2530555556000, 53.5683333333000],
[23.1066666667000, 53.7200000000000],
[22.8452777778000, 53.7758333333000],
[23.0952777778000, 53.4413888889000],
[23.4152777778000, 53.5233333333000],
[22.9175000000000, 53.5322222222000],
[22.7197222222000 ,53.7322222222000],
[22.9586111111000, 53.4594444444000],
[23.3425000000000, 53.6541666667000],
[23.0900000000000, 53.5777777778000],
[23.2283333333000, 53.4713888889000],
[23.3488888889000, 53.5072222222000],
[23.3647222222000 ,53.6447222222000]]

def create_voronois(points_list):
points = numpy.array(points_list)
vor = Voronoi(points)
point_voronoi_list = []
feature_list = []
for region in range(len(vor.regions) - 1):
vertice_list = []
for x in vor.regions[region]:
vertice = vor.vertices[x]
vertice = (vertice[1], vertice[0])
vertice_list.append(vertice)
polygon = Polygon([vertice_list])
feature = Feature(geometry=polygon, properties={})
feature_list.append(feature)

feature_collection = FeatureCollection(feature_list)
print feature_collection

create_voronois(points)

最佳答案

显然,您的 JavaScript 代码在计算 Voronoi 图之前对数据应用了转换。此转换不会保留点的相对距离,因此不会生成与您的 scipy 代码相同的结果。请注意,我并不是说您的 d3 版本不正确。鉴于数据是纬度和经度,您在 javascript 代码中所做的可能是正确的。但是要将它与 scipy 代码进行比较,如果您希望获得相同的 Voronoi 图,则必须进行相同的转换。

下面的脚本表明,如果您保留输入点的相对距离,scipy 的 Voronoi 函数和 d3.geom.voronoi 会生成相同的图表。

这是一个使用 scipy 的 Voronoi 代码的脚本:

import numpy
from scipy.spatial import Voronoi, voronoi_plot_2d
import matplotlib.pyplot as plt


points = [
[22.7433333333000, 53.4869444444000],
[23.2530555556000, 53.5683333333000],
[23.1066666667000, 53.7200000000000],
[22.8452777778000, 53.7758333333000],
[23.0952777778000, 53.4413888889000],
[23.4152777778000, 53.5233333333000],
[22.9175000000000, 53.5322222222000],
[22.7197222222000, 53.7322222222000],
[22.9586111111000, 53.4594444444000],
[23.3425000000000, 53.6541666667000],
[23.0900000000000, 53.5777777778000],
[23.2283333333000, 53.4713888889000],
[23.3488888889000, 53.5072222222000],
[23.3647222222000, 53.6447222222000]]


vor = Voronoi(points)

voronoi_plot_2d(vor)
plt.axis('equal')
plt.xlim(22.65, 23.50)
plt.ylim(53.35, 53.85)
plt.show()

它生成这个图:

plot

现在这是一个使用 d3.geom.voronoi 的 javascript 程序:

<html>
<head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.js"></script>
</head>
<body>
<div id="chart">
</div>
<script type="text/javascript">

// This code is a hacked up version of http://bl.ocks.org/njvack/1405439

var w = 800,
h = 400;

var data = [
[22.7433333333000, 53.4869444444000],
[23.2530555556000, 53.5683333333000],
[23.1066666667000, 53.7200000000000],
[22.8452777778000, 53.7758333333000],
[23.0952777778000, 53.4413888889000],
[23.4152777778000, 53.5233333333000],
[22.9175000000000, 53.5322222222000],
[22.7197222222000, 53.7322222222000],
[22.9586111111000, 53.4594444444000],
[23.3425000000000, 53.6541666667000],
[23.0900000000000, 53.5777777778000],
[23.2283333333000, 53.4713888889000],
[23.3488888889000, 53.5072222222000],
[23.3647222222000, 53.6447222222000]
];

// Translate and scale the points. The same scaling factor (2*h) must be used
// on x and y to preserve the relative distances among the points.
// The y coordinates are also flipped.
var vertices = data.map(function(point) {return [2*h*(point[0]-22.5), h - 2*h*(point[1]-53.4)]})

var svg = d3.select("#chart")
.append("svg:svg")
.attr("width", w)
.attr("height", h);
var paths, points;

points = svg.append("svg:g").attr("id", "points");
paths = svg.append("svg:g").attr("id", "point-paths");

paths.selectAll("path")
.data(d3.geom.voronoi(vertices))
.enter().append("svg:path")
.attr("d", function(d) { return "M" + d.join(",") + "Z"; })
.attr("id", function(d,i) {
return "path-"+i; })
.attr("clip-path", function(d,i) { return "url(#clip-"+i+")"; })
.style("fill", d3.rgb(230, 230, 230))
.style('fill-opacity', 0.4)
.style("stroke", d3.rgb(50,50,50));

points.selectAll("circle")
.data(vertices)
.enter().append("svg:circle")
.attr("id", function(d, i) {
return "point-"+i; })
.attr("transform", function(d) { return "translate(" + d + ")"; })
.attr("r", 2)
.attr('stroke', d3.rgb(0, 50, 200));

</script>
</body>
</html>

它产生:

voronoi screenshot

根据对结果的目视检查,我认为它们生成了相同的 Voronoi 图。

关于javascript - D3 vs Scipy(Voronoi 图实现),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32739772/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com