Search code examples
pythonpython-3.xjupyter-notebookgoogle-colaboratoryplotly-python

How to add Planes in a 3D Scatter Plot


Using Blender created this model

Blender octant cube

that can be seen in A-frame in this link

A-frame cctant cube

This model is great and it gives an overview of what I'm trying to accomplish here. Basically, instead of having the names, I'd have dots that symbolize one specific platform.

The best way to achieve it with current state of the art, at my sight, is through Plotly 3D Scatter Plots. I've got the following scatterplot

3D scatterplot

import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/tiago-peres/immersion/master/Platforms_dataset.csv')
fig = px.scatter_3d(df, x='Functionality ', y='Accessibility', z='Immersion', color='Platforms')
fig.show()

that by going to this link you'll be able to click a button and open it in Colab

GitHub open in Colab

This nearly looks like the model. Yet, still in need to add three planes to the plot in specific locations. More precisely, in x=?, y=? and z=? (I'm using question mark because the value can be anything stablished).

In other words, want to add three planes to that scatterplot

  • x = 10
  • y = 30
  • z = 40

In the documentation, what closely resembles what I want was 3D Surface Plots.

I've done research and found two similar questions with R


Solution

  • I think you might be looking for the add_trace function in plotly so you can just create the surfaces and then add them to the figure:

    Also, note, there's definitely ways to simplify this code, but for a general idea:

    import plotly.express as px
    import pandas as pd
    import plotly.graph_objects as go
    import numpy as np
    
    
    fig = px.scatter_3d(df, x='Functionality ', y='Accessibility', z='Immersion', color='Platforms')
    
    bright_blue = [[0, '#7DF9FF'], [1, '#7DF9FF']]
    bright_pink = [[0, '#FF007F'], [1, '#FF007F']]
    light_yellow = [[0, '#FFDB58'], [1, '#FFDB58']]
    
    # need to add starting point of 0 to each dimension so the plane extends all the way out
    zero_pt = pd.Series([0])
    z = zero_pt.append(df['Immersion'], ignore_index = True).reset_index(drop = True)
    y = zero_pt.append(df['Accessibility'], ignore_index = True).reset_index(drop = True)
    x = zero_pt.append(df['Functionality '], ignore_index = True).reset_index(drop = True)
    
    length_data = len(z)
    z_plane_pos = 40*np.ones((length_data,length_data))
    
    fig.add_trace(go.Surface(x=x, y=y, z=z_plane_pos, colorscale=light_yellow,  showscale=False))
    fig.add_trace(go.Surface(x=x.apply(lambda x: 10), y=y, z = np.array([z]*length_data), colorscale= bright_blue, showscale=False))
    fig.add_trace(go.Surface(x=x, y= y.apply(lambda x: 30), z =  np.array([z]*length_data).transpose(), colorscale=bright_pink, showscale=False))
    

    enter image description here