Search code examples
pythonpandasdataframeplotly

Formatting plotly surface plot correctly given 3 lists


I have 3 lists, an xs, ys, and zs; xs and ys are arbitrary points I created for the purposes of visualization and zs are probabilities [0,1] that I would like to graph on this surface plot. All three of these lists are matched via their indices. I tried plotting them using pandas dataframes like this,

df = pd.DataFrame({'xdata': xs, 'ydata': ys, 'zdata': zs})
fig = go.Figure(data=[go.Surface(z=df.values)])

which results in this graph: 3D plot with incorrect axes As you can see, none of the axes reflect the [0-1] probability I'm expecting, but I assume it's going on the x-axis based on how close it is to correct. Additionally, the other two axes should only be [-12,12], which is reflected with the z-axis, but not the y-axis. So I tried being explicit with the axes by doing this:

df = pd.DataFrame({'xdata': xs, 'ydata': ys, 'zdata': zs})
fig = go.Figure(data=[go.Surface(
   x=df['xdata'].values,
   y=df['ydata'].values,
   z=df[['xdata', 'ydata', 'zdata']].values)])
fig.update_layout(title="Probabilities")

However, this results in this graph: A slightly different incorrect graph In this graph, the x axis correctly reflects the probability axis and the z and y axis both correctly reflect the domain of the remaining axes, however this isn't helpful for me unless the x and z axis are switched. I've tried every combination of switching values in the go.Surface line and the line where I initialize the dataframe, however nothing seems to work. Does anyone know how I might fix this issue?


Solution

  • I was able to get my plot working with tri-surface plot. Any other method I could think of didn't seem to work. Here is the method I used where x and y are lists of euclidean points and z is a list of probabilities [0,1]:

    import plotly
    import numpy as np
    import plotly.express as px
    import plotly.graph_objs as go
    import plotly.figure_factory as ff
    from scipy.spatial import Delaunay
    
    x, y, z = format_prob_data()
    
    points2D = np.vstack([x, y]).T
    tri = Delaunay(points2D)
    
    fig = ff.create_trisurf(x=x, y=y, z=z, simplices=tri.simplices)
    fig.update_layout(title="Probabilities")
    fig.write_html("file.html")