英文:
Getting X, Y and Z reference planes in plotly.js
问题
我正在学习一些plotly,将它与HTML/JavaScript混合使用,所以我正在使用plotly.js CDN。
我打算在X
、Y
和Z
坐标空间中绘制一组随机生成的点,我已成功生成了所有的点,但在尝试将所有三个坐标轴作为参考平面显示在同一图中时遇到了问题...
我已成功显示了**XY
**平面和点:
但我仍然无法显示**XZ
和YZ
**参考平面,就像我在这里使用线条一样:
我甚至尝试使用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**的回答(请阅读它!!!)
如果有人感兴趣,这里是他的答案的结果
英文:
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
But I'm still failing to shows the XZ
and YZ
references planes as I'm doing in here but with lines
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!!!!
<script>
// Array to store the generated points
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],
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],
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],
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);
</script>
Thanks a lot for @kikon for they answer ( please read it!!! )
If someone is interested here the result of his answer
答案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 < 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);
<!-- language: lang-html -->
<div id='coordinateChart' style="height:450px; width:100%"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.24.3/plotly.min.js" integrity="sha512-OB3KqMv8ZelkEhNOv1J6PB0aYRkn8oota0+LoGXIVD3hv1Pu9ebxFJXBopRlGkYLTLEUM7aX9zBepBzGcZzH5A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- 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 < 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: 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: 'y',
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],
delaunayaxis: 'x',
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);
<!-- language: lang-html -->
<div id='coordinateChart' style="height:450px"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.24.3/plotly.min.js" integrity="sha512-OB3KqMv8ZelkEhNOv1J6PB0aYRkn8oota0+LoGXIVD3hv1Pu9ebxFJXBopRlGkYLTLEUM7aX9zBepBzGcZzH5A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论