Make 4D Scatter plot using colors for 4th Dimension and go.Scatter3d

Hello everyone :slight_smile:

I want to plot a three dimensional function using colors as representation of the 4th dimension (i.e. the function value).
I am orienting my code on a surface plot as described here: Creating 4D Surface Graph - #2 by empet

Since I want a scatterplot I use go.Scatter3d(…) instead of go.Surface(…). In the surface plot I used an array surf color which indicates the color the points should have.
When transferring that to the scatterplot I get the following error:

Invalid value of type 'numpy.ndarray' received for the 'surfacecolor' property of scatter3d

followed by my surfsolo array with the shape of z.

Do you have an idea how to plot this scatterplot properly? With the documentation I did not manage to do it.

Here is the code to reproduce :slight_smile: Thank you already for your help :slight_smile:

import numpy as np
import torch
import gpytorch
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib.colors as mcolors
import statistics # from Python library
from scipy.stats import norm
import plotly.graph_objects as go
import pandas as pd
import seaborn as sns


def Hartmann3_fun(x1,x2,x3) :

    x = np.array([x1,x2,x3])
    hartmann_value =0 

    P = 1e-4 * np.array([
        [3689, 1170, 2673],
        [4699,4387,7470],
        [1091,8732,5547],
        [381,5743,8828]
    ])

    alpha= [1.0,1.2,3.0,3.2]

    A = np.array([
        [3.0,10,30],
        [0.1,10,35],
        [3.0,10,30],
        [0.1,10,35]
    ])


    for i in range(4):
         inner_val = 0
         for j in range(3):
             inner_val += A[i,j]*(x[j] - P[i,j])**2.
    hartmann_value += alpha[i]*np.exp(-1.*inner_val)


    return  hartmann_value

x_steps = np.linspace(0,1,101)
d1,d2,d3 = np.meshgrid(x_steps,x_steps,x_steps)
x_in = [[d1,d2,d3] for d1,d2,d3 in zip(d1.ravel(),d2.ravel(),d3.ravel())]

hartmann3_data = pd.DataFrame(x_in)
hartmann3_data.rename(columns={0:"x1",1:"x2",2:"x3"}, inplace= True)
hartmann3_data["value"] = Hartmann3_fun(hartmann3_data["x1"],hartmann3_data["x2"],hartmann3_data["x3"])

surfcolor = hartmann3_data["value"].to_numpy().reshape(*d3.shape)
fig = go.Figure(data=[go.Scatter3d(x=d1, y=d2, z = d3,surfacecolor= surfcolor, opacity=0.8)])
fig.update_layout(margin=dict(l=20, r=20, t=20, b=20),
    height = 600, width =500, scene_aspectmode="cube")

fig.show()

Hey @robl01, it’s very late but since I’m working on 4D surface and scatter plots I’ll post my answer anyway, hopefully will be useful for others.

Have you tried using Plotly Express’ px.scatter_3d and passing hartmann3_data["value"] in the color parameter?

No need to create mesh grids:

px.scatter_3d(x, y, z, color = <your_4th_dimension>)

1 Like