0

I have a set of 3D data (X,Y,Z) and an array of values (let's call it C). X,Y,Z and C have the same length.
My goal is to plot a surface by creating a 3D mesh with X,Y,Z points and to color each point (thus the surface) according to the value of C.

I managed to this using plotly library after asking for help here. It works perfectly fine in most cases. However it's not able to draw a closed surface (e.g. a sphere), but it only plots the lower half of it.

import plotly.graph_objects as go
import numpy as np

DATA = np.loadtxt(open("surface.dat", "rb"))
Xs = DATA[:,0]
Ys = DATA[:,1]
Zs = DATA[:,2]

value = np.loadtxt(open("0.dat", "rb"))

fig = go.Figure(data=[
    go.Mesh3d(
        x=Xs,
        y=Ys,
        z=Zs,
        colorbar_title='value',
        colorscale="hot",
        # Intensity of each vertex, which will be interpolated and color-coded
        intensity=value,
        showscale=True
    )
])

fig.show()

Plotly mesh3d shows only half of a sphere

I understand that this happen because plotly's mesh3d can't take multiple values of Z for a X,Y couple, so I even try to plot 2 half-shapes, one for the bottom and one for the upper part, but this results in a hole in the middle of the 2 halves.

Here is the code and the result:

import plotly.graph_objects as go
import numpy as np

DATA = np.loadtxt(open("surface.dat", "rb"))
Xs = DATA[:,0]
Ys = DATA[:,1]
Zs = DATA[:,2]
value = np.loadtxt(open("0.dat", "rb"))

#find the permutation that put Z in ascending order
p = Zs.argsort()

#sort the arrays with that permutation and invert them ('pos' stands for 'positive')
Xpos = Xs[p][::-1]
Ypos = Ys[p][::-1]
Zpos = Zs[p][::-1]
Vpos = value[p][::-1]


top = go.Mesh3d(
    x=Xpos,
    y=Ypos,
    z=Zpos,
    colorbar_title='value',
    colorscale="hot",
    intensity=Vpos,
    showscale=True
)


bottom = go.Mesh3d(
    x=Xs,
    y=Ys,
    z=Zs,
    colorbar_title='value',
    colorscale="hot",
    intensity=value,
    showscale=True
)

fig = go.Figure(data=[top,bottom])
fig.show()

2 half-spheres that doesn't match up in the middle

Is there a way to achieve what I need? Some solutions could be:

  • filling the holes connecting the 2 halves somehow
  • using a different library (e.g. matplotlib, Open3D)
  • using a complete different method that I can't come up with
  • drawing the sphere first and then color it. I don't favor this last solution because the shape should be somewhat arbitrary (not a function), but if no other solutions exist, I can get the coordinates of C and color the sphere with them.

The result should look something like the following: What I need to obtain

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
puccj
  • 121
  • 5

1 Answers1

0

What you want is a surface mesh from a point cloud.

You could try using CGal, see section 5 of this page or see all modules in category Shape Reconstruction. You could try Poisson reconstruction. It requires normals at the points. This is easily done in your case by taking P-M where M is the middle (average of all points) and P is any given point.

In Python, I find this package and this package which seem to offer what you want. The case of a sphere is very elementary so I should expect all of these to work.

Sardine
  • 153
  • 5