hv.Scatter3D coloring

Hello,

I am using hv.Scatter3D with extension plotly. I have a 3D data set with an additional categorical dimension. I want to plot the data and color it by the categories given in the data. The only way I am able to do that is to have an additional column that assigns a color with a given value. An example is given below.

data = np.random.randn(10, 3).cumsum(axis=0)
df = pd.DataFrame(data,columns=['x','y','z'])
df['type'] = ['A','A','B','C','A','C','C','B','C','A']
color_key = {'A':'red', 'B':'blue','C':'green'}
for i,idx in enumerate(df.index):
    df.loc[idx,'color'] = color_key[df.loc[idx,'type']]

Then to plot the data with the correct coloring I do this,

hv.Scatter3D(df, kdims=['x','y','z'], vdims=['type','color']).opts(color='color', show_legend=True, size=3)

However, the legend does not display correctly. I assume because there is no way for the plot to know what color corresponds to what ‘type’ value, but, I am unsure how to do that. If anyone has any ideas or can give any help I would greatly appreciate it.

You can try to create an NdOverlay from a dict of scatter3d where the keys are your types.

import numpy as np
import pandas as pd
import holoviews as hv
hv.extension('plotly')

data = np.random.randn(10, 3).cumsum(axis=0)
df = pd.DataFrame(data,columns=['x','y','z'])
df['type'] = ['A','A','B','C','A','C','C','B','C','A']
color_key = {'A':'red', 'B':'blue','C':'green'}
for i,idx in enumerate(df.index):
    df.loc[idx,'color'] = color_key[df.loc[idx,'type']]
dict_plot={t:hv.Scatter3D(df.query(f'type=="{t}"'),kdims=['x','y','z'],vdims=['type','color']).opts(show_legend=True,color='color',size=3) for t in df.type.unique()}
h=hv.NdOverlay(dict_plot)
h.get_dimension('Element').label='type '
h

Unfortunately I can’t get rid off the colon in the legend so I changed Element by type.

Thank you!

You could also use hv.dim:

import numpy as np
import pandas as pd
import holoviews as hv
hv.extension('plotly')
import hvplot.pandas

data       = np.random.randn(10, 3).cumsum(axis=0)
df         = pd.DataFrame(data,columns=['x','y','z'])
df['type'] = ['A','A','B','C','A','C','C','B','C','A']

hv.Scatter3D( hv.Dataset(df), vdims='type' ).opts( color = hv.dim('type').categorize({'A':'red', 'B':'green', 'C':'blue'}))

See https://holoviews.org/user_guide/Style_Mapping.html