# Make 3D surface plot from 2D data

I have 2 dimensional data on two planes, the x-y and x-z plane. I was wondering if it was feasible to project them into a surface plot kind of like in the picture below I understand with only 2 planes of data my 3D surface would not be a completely accurate rendering of what the 3D surface would look like. If it is possible, how would I go about doing this?
The data on these planes is in the form of a matrix with the z data representing intensity. I was able to successfully make a heatmap of the data but not a contour plot. My idea now is to write an algorithm that will go through the data to find the points in common and produce a 3D structure from that.
Some problems I anticipate is that I would have to first have to group the data into bundles of intensities intensities and I have a lot of data so I don’t want to unnecessary slow the process.

Hi @Nin,

If you’re able to associate your 2D datasets into a single 3D dataset of densities, then an isosurface trace may be what you want to visualize this in 3D. You can think of isosurface as a 3D extension of a 2D contour plot. See https://plot.ly/python/3d-isosurface-plots/ for some examples.

-Jon

@jmmease Thank you very much for your reply. I have written some code that gives me the x,y and z spacial coordinates for ranges of intensities which I think is what you mean by 'associate into a single 3D data set of densities. I had to group ranges of intensities into discreet values before I could implement my method.

``````mPoints = pd.DataFrame(columns = ['X','Y','Z'])

for m in list(newH_transposed.columns.values):
for n in list(newV_transposed.columns.values):
if (m == n):
ymatches = newV_transposed.loc[newV_transposed[m] == 2]
zmatches = newH_transposed.loc[newH_transposed[m] == 2]
ys = ymatches.index.values
zs = zmatches.index.values
for y in ys:
for z in zs:
mPoints = mPoints.append({'X': m, 'Y': y, 'Z': z}, ignore_index=True)
``````

In the above code I am obtaining the x, y and z’s for all intensities in the two plots that equal 2. I did this for another intensity and went ahead and plotted these groups as a 3D scatter plot with different opacity.

``````fig = go.Figure(data=[itrace, mtrace], layout=layout)
``````

I got something close to the desired result (I have posted a screenshot below) but obviously these are not the smooth meshes I want. Another issue was that the effect of the opacity was not clear when I zoom out or if I view from the wrong angle as you can see from the points further away. I’m looking into the isosurfaces link you sent and it looks like I need to combine my two data sets and include the parameter specifying the intensity. Am I correct?

Hi @Nin,

I’m looking into the isosurfaces link you sent and it looks like I need to combine my two data sets and include the parameter specifying the intensity. Am I correct?

Yes, for `isosurface` you would need to compute the density at each location in space yourself.

I’m not following the description of your method enough to understand whether you already have a grid of spatial locations with density values, or whether you have a collection of 3D points that you still need to compute the density of. If the former, then I think you should have everything you need to create an isosurface (`x`, `y`, `z`, and `value`). If the latter, then I think you could use numpy’s histogramdd to bin the dataset in 3D to get the `value` array.

-Jon