d3:来自不规则/散点数据的轮廓或曲面图

sh3*_*211 5 javascript svg data-visualization d3.js

我可以采取一组三胞胎[X,Y,Z]的和立即使用Python生成(平滑)等高线图以及带matplotlib单个呼叫tricontour() 。也可以使用plot.ly '轻松'生成轮廓,但我发现它慢得令人无法接受。(另外,我对MATLAB 解决方案不感兴趣,它类似于 Python)

我正在寻找使用 d3.js 的类似功能。 我会接受“表面图”而不是等高线,或者没有等高线的“热图”。

我可以看到如何生成彩色 Delaunay 三角剖分和/或彩色 Voronoi Tesselation,但如何从不规则数据点生成 d3 中的等高线图的问题似乎仍然是一个开放的问题(即使关于这个问题的问题还为时过早关闭!)。

到目前为止,我所看到的都是“手工”方法,使用径向基函数(高斯模糊)或使用重心插值的网格插值

我什至愿意在 Delaunay 三角剖分上使用 Gouraud 着色或 Coon 梯度,但显然像 Gourand 或 Coon 梯度这样的“高级着色方法”不在“常规”SVG 中,而是建议用于 SVG2 ......不知道这给我留下了 d3 和(常规)SVG。似乎手动执行此 SVG 渐变着色将是一个主要的痛苦。

有没有“更好”的打包方式来做到这一点,即不需要这么多“自定义”代码的东西? (也许通过一些我还没有找到的多维贝塞尔例程?)

我将发布一个带有我的起点的小提琴:一个彩色的 Voronoi 镶嵌:https ://jsfiddle.net/k2v2jy7s/1/ 。你能帮我把它从“块状”变成“光滑”(甚至可能显示轮廓线)?

<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
    var svg = d3.select("svg"),
        width = +svg.attr("width"),
        height = +svg.attr("height");

    var npoints = 1000;
    var sites = d3.range(npoints)
        .map(function(d) { return [Math.random() * width, Math.random() * height]; });


    // values  at data points / colors being mapped = "zvals"
    var kx = 3.14159/(width*0.5);
    var ky = 3.14159/(height*0.5);
    var zvals = d3.range(npoints)
    for (i = 0; i < npoints; i++) { 
        zvals[i] = (1.0 + Math.cos(kx*sites[i][0]) * Math.cos(ky*sites[i][1]))/2.0;
        zvals[i] *= zvals[i];
    }

    var g = svg.append("g")
        .attr("transform", "translate(" + 0+ "," + 0 + ")");

    var voronoi = d3.voronoi()
        .extent([[-1, -1], [width + 1, height + 1]]);

    var polygon = svg.append("g")
        .attr("class", "polygons")
        .selectAll("path")
        .data(voronoi.polygons(sites))
        .enter().append("path")
        .style('fill', function(d,i){ return d3.hsl( zvals[i]*310,        1, .5); })
        .call(redrawPolygon);

    function redrawPolygon(polygon) {
      polygon
          .attr("d", function(d) { return d ? "M" + d.join("L") + "Z" : null; });
    }
</script>
Run Code Online (Sandbox Code Playgroud)

更新:还在“Gradient Heatmaps 上找到了这个 blocks.org 帖子,正如我所提到的,这是我愿意接受的那种结果,但同样是大量的自定义代码。真的更喜欢紧凑的“库存”解决方案,一个 la tricontour()。

Sim*_*ast 0

5 \xc2\xbd 年了,这个问题还没有答案!

\n

嗯,我也一直在研究如何从 Javascript 中的一系列[X,Y,Z]点生成轮廓,但尚未找到最好或最完整的解决方案。我通过谷歌搜索找到的许多解决方案(例如d3-contour)都是为均匀分布的值网格而设计的,而不是像您可能从土地调查中获得的不规则的一系列点。

\n

d3-三角轮廓

\n

不过, d3 -tricontour库看起来可能是最有前途的,所以我可能会尝试一下。

\n

这是它可以生成的示例:

\n

d3-tricontour 库示例

\n

(标签是可选的。)

\n

显然,它使用delaunay蜿蜒三角形算法将任意点转换为三角形,然后转换为轮廓几何。该算法的工作时间为 O(n),其中 n 是边数,这意味着它非常快并且可扩展性非常好。

\n

要了解更多信息,您可以访问他们的:

\n\n

备择方案

\n

否则,可能还有其他方法可以做到这一点。如果使用基于网格的库之一,我认为一般过程是:

\n
    \n
  1. 将任意[X,Y,Z]点转换为网格 \xe2\x80\x94 Delaunay 算法可能是一个很好的起点(请参阅d3-delaunay其他 delaunay 库
  2. \n
  3. 使用某种插值法找到网格中每个点的 Z 值(我不确定数学)
  4. \n
  5. 然后将该结果输入到基于网格的轮廓库之一
  6. \n
\n

约束轮廓

\n

另请注意,从现实世界地形创建轮廓还需要“约束”一些边缘,以便轮廓不会跨越不应交叉的山脊线。

\n

CDT-JS是一个Web 应用程序(尚未提供单独的库),用于计算约束Delaunay 三角剖分,这对于本例可能有用。

\n

否则,理论上,您可以通过[X,Y,Z]在渲染之前沿着约束线注入附加点来创建此类功能。但我还没有测试过这种方法。

\n