在Plotly.js中获取X、Y和Z参考平面。

huangapple go评论90阅读模式
英文:

Getting X, Y and Z reference planes in plotly.js

问题

我正在学习一些plotly,将它与HTML/JavaScript混合使用,所以我正在使用plotly.js CDN。

我打算在XYZ坐标空间中绘制一组随机生成的点,我已成功生成了所有的点,但在尝试将所有三个坐标轴作为参考平面显示在同一图中时遇到了问题...

我已成功显示了**XY**平面和点:

在Plotly.js中获取X、Y和Z参考平面。

但我仍然无法显示**XZYZ**参考平面,就像我在这里使用线条一样:

在Plotly.js中获取X、Y和Z参考平面。

我甚至尝试使用chatGPT,但它完全迷失在尝试解决这个问题...

在这里分享我正在使用的整个JS脚本代码,希望能找到可以帮助我的人!!!!

<script>
    // 用于存储生成的点的数组
    const dots = [];

    // 生成具有随机x、y、z坐标的100个点
    for (let i = 0; i < 100; i++) {
      const x = Math.random() * 20 - 10;
      const y = Math.random() * 20 - 10;
      const z = Math.random() * 20 - 10;
      dots.push({ x, y, z });
    }

    // 单独提取x、y和z坐标以用于图表
    const xData = dots.map(point => point.x);
    const yData = dots.map(point => point.y);
    const zData = dots.map(point => point.z);

    // 配置3D图表的追踪
    const trace = {
      x: xData,
      y: yData,
      z: zData,
      mode: 'markers',
      marker: {
        size: 5,
        color: 'rgb(75, 192, 192)',
      },
      type: 'scatter3d',
    };

    // XY平面 (z = 0)
    const dataPlaneXY = {
        x: [-10, 10, 10, -10], 
        y: [-10, -10, 10, 10], 
        z: [0, 0, 0, 0], 
        type: 'mesh3d',
        colorscale: 'Viridis', 
        opacity: 0.5, 
        lighting: {
            specular: 0.2,
            ambient: 0.8,
            diffuse: 0.5,
            fresnel: 0.2,
        },
    };

    // XZ平面 (y = 0)
    const dataPlaneXZ = {
        x: [-10, 10, 10, -10], 
        y: [0, 0, 0, 0], 
        z: [-10, -10, 10, 10], 
        type: 'mesh3d',
        colorscale: 'Viridis', 
        opacity: 0.5, 
        lighting: {
            specular: 0.2,
            ambient: 0.8,
            diffuse: 0.5,
            fresnel: 0.2,
        },
    };

    // YZ平面 (x = 0)
    const dataPlaneYZ = {
        x: [0, 0, 0, 0], 
        y: [-10, 10, 10, -10], 
        z: [-10, -10, 10, 10], 
        type: 'mesh3d',
        colorscale: 'Viridis', 
        opacity: 0.5, 
        lighting: {
            specular: 0.2,
            ambient: 0.8,
            diffuse: 0.5,
            fresnel: 0.2,
        },
    };

    // 图表的数据,包括参考平面的线条
    const data = [trace, dataPlaneXY, dataPlaneXZ, dataPlaneYZ];

    // 配置3D图表的布局
    const layout = {
      scene: {
        xaxis: { title: 'X坐标', range: [-10, 10], showaxeslines: true },
        yaxis: { title: 'Y坐标', range: [-10, 10], showaxeslines: true },
        zaxis: { title: 'Z坐标', range: [-10, 10], showaxeslines: true },
        aspectmode: 'cube', // 保证轴具有相同的比例
        showaxeslines: true, // 显示轴线
      },
    };
    // 绘制3D图表
    Plotly.newPlot('coordinateChart', data, layout);
  </script>

感谢**@kikon**的回答(请阅读它!!!)

如果有人感兴趣,这里是他的答案的结果

在Plotly.js中获取X、Y和Z参考平面。

英文:

I'm learning a bit of plotly mixing it with HTML/JavaScript, so I'm using the plotly.js CDN

I pretend to draw a set of randomly generated dots into a X, Y, and Z coordinate space, I have successfully generated all the dots but I'm facing an issues trying to show in the same drawing all three coordinates axis as a reference planes...

I have successfully been able to show the XY plane and dots

在Plotly.js中获取X、Y和Z参考平面。

But I'm still failing to shows the XZ and YZ references planes as I'm doing in here but with lines

在Plotly.js中获取X、Y和Z参考平面。

I have even attempt to use chatGPT but it's totally lost trying to resolve the issue...

Here share the whole JS script code I'm using , hope I get someone that can help!!!!

&lt;script&gt;
    // Array to store the generated points
    const dots = [];

    // Generate 100 points with random x, y, z coordinates
    for (let i = 0; i &lt; 100; i++) {
      const x = Math.random() * 20 - 10;
      const y = Math.random() * 20 - 10;
      const z = Math.random() * 20 - 10;
      dots.push({ x, y, z });
    }

    // Extract x, y, and z coordinates separately for the chart
    const xData = dots.map(point =&gt; point.x);
    const yData = dots.map(point =&gt; point.y);
    const zData = dots.map(point =&gt; point.z);

    // Configure the 3D chart trace
    const trace = {
      x: xData,
      y: yData,
      z: zData,
      mode: &#39;markers&#39;,
      marker: {
        size: 5,
        color: &#39;rgb(75, 192, 192)&#39;,
      },
      type: &#39;scatter3d&#39;,
    };

    // Plane x-y (z = 0)
    const dataPlaneXY = {
        x: [-10, 10, 10, -10], 
        y: [-10, -10, 10, 10], 
        z: [0, 0, 0, 0], 
        type: &#39;mesh3d&#39;,
        colorscale: &#39;Viridis&#39;, 
        opacity: 0.5, 
        lighting: {
            specular: 0.2,
            ambient: 0.8,
            diffuse: 0.5,
            fresnel: 0.2,
        },
    };

    // Plane x-z (y = 0)
    const dataPlaneXZ = {
        x: [-10, 10, 10, -10], 
        y: [0, 0, 0, 0], 
        z: [-10, -10, 10, 10], 
        type: &#39;mesh3d&#39;,
        colorscale: &#39;Viridis&#39;, 
        opacity: 0.5, 
        lighting: {
            specular: 0.2,
            ambient: 0.8,
            diffuse: 0.5,
            fresnel: 0.2,
        },
    };

    // Plane y-z (x = 0)
    const dataPlaneYZ = {
        x: [0, 0, 0, 0], 
        y: [-10, 10, 10, -10], 
        z: [-10, -10, 10, 10], 
        type: &#39;mesh3d&#39;,
        colorscale: &#39;Viridis&#39;, 
        opacity: 0.5, 
        lighting: {
            specular: 0.2,
            ambient: 0.8,
            diffuse: 0.5,
            fresnel: 0.2,
        },
    };

    // Data for the chart, including the lines for the reference planes
    const data = [trace, dataPlaneXY, dataPlaneXZ, dataPlaneYZ];

    // Configure the layout of the 3D chart
    const layout = {
      scene: {
        xaxis: { title: &#39;X Coordinate&#39;, range: [-10, 10], showaxeslines: true },
        yaxis: { title: &#39;Y Coordinate&#39;, range: [-10, 10], showaxeslines: true },
        zaxis: { title: &#39;Z Coordinate&#39;, range: [-10, 10], showaxeslines: true },
        aspectmode: &#39;cube&#39;, //  ensures the axes have the same scale
        showaxeslines: true, // Show axis lines
      },
    };
    // Draw the 3D chart
    Plotly.newPlot(&#39;coordinateChart&#39;, data, layout);
  &lt;/script&gt;

Thanks a lot for @kikon for they answer ( please read it!!! )

If someone is interested here the result of his answer

在Plotly.js中获取X、Y和Z参考平面。

答案1

得分: 2

A mesh3d is a set of triangles; the properties x, y, and z specify a set of points; one has also to specify how these points are to be grouped in triangles.

The safest and clearest way to do that is to set the properties i, j, and k.
If one sets:

i: [0, 1],
j: [1, 2],
k: [2, 3],

there will be two triangles: the first formed by the points 0, 1, 2 and the second by points 1, 2, 3 - coordinates taken from the x, y, z arrays.

Here's a solution, based on that (note that I changed the order of two coordinates also):

const dots = [];
// Generate 100 points with random x, y, z coordinates
for (let i = 0; i < 100; i++) {
const x = Math.random() * 20 - 10;
const y = Math.random() * 20 - 10;
const z = Math.random() * 20 - 10;
dots.push({ x, y, z });
}
// Extract x, y, and z coordinates separately for the chart
const xData = dots.map(point => point.x);
const yData = dots.map(point => point.y);
const zData = dots.map(point => point.z);
// Configure the 3D chart trace
const trace = {
x: xData,
y: yData,
z: zData,
mode: 'markers',
marker: {
size: 5,
color: 'rgb(75, 192, 192)',
},
type: 'scatter3d',
};
// Plane x-y (z = 0)
const dataPlaneXY = {
x: [-10, 10, -10, 10],
y: [-10, -10, 10, 10],
z: [0, 0, 0, 0],
i: [0, 1],
j: [1, 2],
k: [2, 3],
type: 'mesh3d',
colorscale: 'Viridis',
opacity: 0.5,
lighting: {
specular: 0.2,
ambient: 0.8,
diffuse: 0.5,
fresnel: 0.2,
},
};
// Plane x-z (y = 0)
const dataPlaneXZ = {
x: [-10, 10, -10, 10],
y: [0, 0, 0, 0],
z: [-10, -10, 10, 10],
i: [0, 1],
j: [1, 2],
k: [2, 3],
type: 'mesh3d',
colorscale: 'Viridis',
opacity: 0.5,
lighting: {
specular: 0.2,
ambient: 0.8,
diffuse: 0.5,
fresnel: 0.2,
},
};
// Plane y-z (x = 0)
const dataPlaneYZ = {
x: [0, 0, 0, 0],
y: [-10, 10, -10, 10],
z: [-10, -10, 10, 10],
i: [0, 1],
j: [1, 2],
k: [2, 3],
type: 'mesh3d',
colorscale: 'Viridis',
opacity: 0.5,
lighting: {
specular: 0.2,
ambient: 0.8,
diffuse: 0.5,
fresnel: 0.2,
},
};
// Data for the chart, including the lines for the reference planes
const data = [trace, dataPlaneXY, dataPlaneXZ, dataPlaneYZ];
// Configure the layout of the 3D chart
const layout = {
scene: {
xaxis: { title: 'X Coordinate', range: [-10, 10], showaxeslines: true },
yaxis: { title: 'Y Coordinate', range: [-10, 10], showaxeslines: true },
zaxis: { title: 'Z Coordinate', range: [-10, 10], showaxeslines: true },
aspectmode: 'cube', //  ensures the axes have the same scale
showaxeslines: true, // Show axis lines
},
};
// Draw the 3D chart
Plotly.newPlot('coordinateChart', data, layout);

Now, for an alternative solution, and an explanation of why did the xy plane work without the i, j, k: if they are not specified, then the Delaunay triangulation is used - see the docs on alphahull and delaunayaxis properties.

So, it turns out that at least for the 4 coplanar points that you have Delaunay triangulation works fine, but you have to set the delaunayaxis to the axis perpendicular to their plane. And yes, the default is z and that's why it worked with no addition for the xy plane:

const dots = [];
// Generate 100 points with random x, y, z coordinates
for (let i = 0; i < 100; i++) {
const x = Math.random() * 20 - 10;
const y = Math.random() * 20 - 10;
const z = Math.random() * 20 - 10;
dots.push({ x, y, z });
}
// Extract x, y, and z coordinates separately for the chart
const xData = dots.map(point => point.x);
const yData = dots.map(point => point.y);
const zData = dots.map(point => point.z);
// Configure the 3D chart trace
const trace = {
x: xData,
y: yData,
z: zData,
mode: 'markers',
marker: {
size: 5,
color: 'rgb(75, 192, 192)',
},
type: 'scatter3d',
};
// Plane x-y (z = 0)
const dataPlaneXY = {
x: [-10, 10, 10, -10],
y: [-10, -10, 10, 10],
z: [0, 0, 0, 0],
delaunayaxis: 'z', // default
type: 'mesh3d',
colorscale: 'Viridis',
opacity: 0.5,
lighting: {
specular: 0.2,
ambient:
<details>
<summary>英文:</summary>
A `mesh3d` is a set of triangles; the properties `x`, `y` and `z` specify a set of points; one has also to specify how these points are to be grouped in triangles.
The safest and clearest way to do that is to set the properties [`i`](https://plotly.com/javascript/reference/mesh3d/#mesh3d-i), `j` and `k`.
If one sets: 
```lang-js
i: [0, 1],
j: [1, 2],
k: [2, 3],

there will be two triangles: the first formed by the points 0,1,2 and the second by points 1,2,3 - coordinates taken from the x,y,z arrays.

Here's a solution, based on that (note that I changed the order of two coordinates also):

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const dots = [];
// Generate 100 points with random x, y, z coordinates
for (let i = 0; i &lt; 100; i++) {
const x = Math.random() * 20 - 10;
const y = Math.random() * 20 - 10;
const z = Math.random() * 20 - 10;
dots.push({ x, y, z });
}
// Extract x, y, and z coordinates separately for the chart
const xData = dots.map(point =&gt; point.x);
const yData = dots.map(point =&gt; point.y);
const zData = dots.map(point =&gt; point.z);
// Configure the 3D chart trace
const trace = {
x: xData,
y: yData,
z: zData,
mode: &#39;markers&#39;,
marker: {
size: 5,
color: &#39;rgb(75, 192, 192)&#39;,
},
type: &#39;scatter3d&#39;,
};
// Plane x-y (z = 0)
const dataPlaneXY = {
x: [-10, 10, -10, 10],
y: [-10, -10, 10, 10],
z: [0, 0, 0, 0],
i: [0, 1],
j: [1, 2],
k: [2, 3],
type: &#39;mesh3d&#39;,
colorscale: &#39;Viridis&#39;,
opacity: 0.5,
lighting: {
specular: 0.2,
ambient: 0.8,
diffuse: 0.5,
fresnel: 0.2,
},
};
// Plane x-z (y = 0)
const dataPlaneXZ = {
x: [-10, 10, -10, 10],
y: [0, 0, 0, 0],
z: [-10, -10, 10, 10],
i: [0, 1],
j: [1, 2],
k: [2, 3],
type: &#39;mesh3d&#39;,
colorscale: &#39;Viridis&#39;,
opacity: 0.5,
lighting: {
specular: 0.2,
ambient: 0.8,
diffuse: 0.5,
fresnel: 0.2,
},
};
// Plane y-z (x = 0)
const dataPlaneYZ = {
x: [0, 0, 0, 0],
y: [-10, 10, -10, 10],
z: [-10, -10, 10, 10],
i: [0, 1],
j: [1, 2],
k: [2, 3],
type: &#39;mesh3d&#39;,
colorscale: &#39;Viridis&#39;,
opacity: 0.5,
lighting: {
specular: 0.2,
ambient: 0.8,
diffuse: 0.5,
fresnel: 0.2,
},
};
// Data for the chart, including the lines for the reference planes
const data = [trace, dataPlaneXY, dataPlaneXZ, dataPlaneYZ];
// Configure the layout of the 3D chart
const layout = {
scene: {
xaxis: { title: &#39;X Coordinate&#39;, range: [-10, 10], showaxeslines: true },
yaxis: { title: &#39;Y Coordinate&#39;, range: [-10, 10], showaxeslines: true },
zaxis: { title: &#39;Z Coordinate&#39;, range: [-10, 10], showaxeslines: true },
aspectmode: &#39;cube&#39;, //  ensures the axes have the same scale
showaxeslines: true, // Show axis lines
},
};
// Draw the 3D chart
Plotly.newPlot(&#39;coordinateChart&#39;, data, layout);

<!-- language: lang-html -->

&lt;div id=&#39;coordinateChart&#39; style=&quot;height:450px; width:100%&quot;&gt;&lt;/div&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.24.3/plotly.min.js&quot; integrity=&quot;sha512-OB3KqMv8ZelkEhNOv1J6PB0aYRkn8oota0+LoGXIVD3hv1Pu9ebxFJXBopRlGkYLTLEUM7aX9zBepBzGcZzH5A==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

Now, for an alternative solution, and an explanation of why did the xy plane work without the i, j, k: if they are not specified, then the Delaunay triangulation is used - see the docs on alphahull and delaunayaxis properties.

So, it turns out that at least for the 4 coplanar points that you have Delaunay triangulation works fine, but you have to set the delaunayaxis to the axis perpendicular to their plane. And yes, the default is z and that's why it worked with no addition for the xy plane:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const dots = [];
// Generate 100 points with random x, y, z coordinates
for (let i = 0; i &lt; 100; i++) {
const x = Math.random() * 20 - 10;
const y = Math.random() * 20 - 10;
const z = Math.random() * 20 - 10;
dots.push({ x, y, z });
}
// Extract x, y, and z coordinates separately for the chart
const xData = dots.map(point =&gt; point.x);
const yData = dots.map(point =&gt; point.y);
const zData = dots.map(point =&gt; point.z);
// Configure the 3D chart trace
const trace = {
x: xData,
y: yData,
z: zData,
mode: &#39;markers&#39;,
marker: {
size: 5,
color: &#39;rgb(75, 192, 192)&#39;,
},
type: &#39;scatter3d&#39;,
};
// Plane x-y (z = 0)
const dataPlaneXY = {
x: [-10, 10, 10, -10],
y: [-10, -10, 10, 10],
z: [0, 0, 0, 0],
delaunayaxis: &#39;z&#39;, //default
type: &#39;mesh3d&#39;,
colorscale: &#39;Viridis&#39;,
opacity: 0.5,
lighting: {
specular: 0.2,
ambient: 0.8,
diffuse: 0.5,
fresnel: 0.2,
},
};
// Plane x-z (y = 0)
const dataPlaneXZ = {
x: [-10, 10, 10, -10],
y: [0, 0, 0, 0],
z: [-10, -10, 10, 10],
delaunayaxis: &#39;y&#39;,
type: &#39;mesh3d&#39;,
colorscale: &#39;Viridis&#39;,
opacity: 0.5,
lighting: {
specular: 0.2,
ambient: 0.8,
diffuse: 0.5,
fresnel: 0.2,
},
};
// Plane y-z (x = 0)
const dataPlaneYZ = {
x: [0, 0, 0, 0],
y: [-10, 10, 10, -10],
z: [-10, -10, 10, 10],
delaunayaxis: &#39;x&#39;,
type: &#39;mesh3d&#39;,
colorscale: &#39;Viridis&#39;,
opacity: 0.5,
lighting: {
specular: 0.2,
ambient: 0.8,
diffuse: 0.5,
fresnel: 0.2,
},
};
// Data for the chart, including the lines for the reference planes
const data = [trace, dataPlaneXY, dataPlaneXZ, dataPlaneYZ];
// Configure the layout of the 3D chart
const layout = {
scene: {
xaxis: { title: &#39;X Coordinate&#39;, range: [-10, 10], showaxeslines: true },
yaxis: { title: &#39;Y Coordinate&#39;, range: [-10, 10], showaxeslines: true },
zaxis: { title: &#39;Z Coordinate&#39;, range: [-10, 10], showaxeslines: true },
aspectmode: &#39;cube&#39;, //  ensures the axes have the same scale
showaxeslines: true, // Show axis lines
},
};
// Draw the 3D chart
Plotly.newPlot(&#39;coordinateChart&#39;, data, layout);

<!-- language: lang-html -->

&lt;div id=&#39;coordinateChart&#39; style=&quot;height:450px&quot;&gt;&lt;/div&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.24.3/plotly.min.js&quot; integrity=&quot;sha512-OB3KqMv8ZelkEhNOv1J6PB0aYRkn8oota0+LoGXIVD3hv1Pu9ebxFJXBopRlGkYLTLEUM7aX9zBepBzGcZzH5A==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年7月23日 23:21:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76749011.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定