I have a dataset like:
df = pd.DataFrame(np.random.rand(10,2),columns=['A','B'])
df['group'] = np.random.choice(4,size=10)
df['category'] = np.random.choice(['CC','DD'],size=10)
df['sizes'] = np.random.randint(10,50,size=10)
and I want a scatter plot of A vs B with the markers colored by the 'group' column, and with markers' type based on the 'category' column, marker size based on the 'sizes' column.
The following...
scatter = df.hvplot.scatter(x='A',y='B',color='group',padding=0.1,cmap='Set1',size='sizes')
scatter
...gets me the correct coloring, and while I get a "Cannot declare mapping for 'size' option" (any idea why?), I actually get the correct marker sizing.
However, I can't seem to get marker types based on 'category' column.
I have tried...
markers=['x' if zone=='DD' else 'o' for zone in df['category']]
scatter = df.hvplot.scatter(x='A',y='B',color='group',padding=0.1,cmap='Set1',size='sizes',marker=markers)
scatter
... but it convert ALL points to crosses(x) and none to circles(o).
I also tried adding a column:
df['markers'] = np.random.choice(['x','o'],size=10)
and then...
scatter = df.hvplot.scatter(x='A',y='B',color='group',padding=0.1,cmap='Set1',size='sizes',marker='markers')
scatter
... but this throws an error and doesn't work at all.
What is the right way to customize markers by variable using hvplot?
Appreciate your suggestions.
EDIT 1: Now I've also tried to use holoviews.dim, 1. with holoviews:
hvd = hv.Dataset(df,['A'],['B','markers'])
markers_custom = hv.dim('markers').apply(hvd)
hvd.to.scatter().opts(marker=marker)
and then 2. again with hvplot:
scatter = df.hvplot.scatter(x='A',y='B',marker=markers_custom)
I get:
TypeError [Call holoviews.ipython.show_traceback() for details] unhashable type: 'numpy.ndarray'
...in both cases.
The above works but we very much recommend not transforming your actual data unless you really need to which is why we introduced so called dim
expressions, which you can read about here. These let you express complex transform without having to touch your data, e.g. in your example you could do:
import holoviews as hv
df = pd.DataFrame(np.random.rand(10,2),columns=['A','B'])
df['group'] = np.random.choice(4,size=10)
df['category'] = np.random.choice(['CC','DD'],size=10)
df['sizes'] = np.random.randint(10,50,size=10)
marker = hv.dim("category").categorize({'DD': 'x'}, default='circle')
df.hvplot.scatter(x='A',y='B', color="group", size="sizes", marker=marker)
The transform here basically takes the category column and transforms it by mapping all 'DD' values to 'x' and all other values to 'circle'.