Add datashaded version of interactive plot
@@ -11,6 +11,8 @@ import matplotlib.colors
import bokeh.plotting as bpl
import bokeh.transform as btr
+import holoviews as hv
+import holoviews.operation.datashader as hd
import sklearn.decomposition
import sklearn.cluster
@@ -520,9 +522,6 @@ def interactive(
if points.shape[1] != 2:
raise ValueError('Plotting is currently only implemented for 2D embeddings')
- if points.shape[0] <= width * height // 10:
-
- bpl.output_notebook(hide_banner=True)
point_size = 100.0 / np.sqrt(points.shape[0])
data = pd.DataFrame(umap_object.embedding_, columns=('x', 'y'))
@@ -555,6 +554,8 @@ def interactive(
else:
colors = matplotlib.colors.rgb2hex(plt.get_cmap(cmap)(0.5))
+ if points.shape[0] <= width * height // 10:
+
if hover_data is not None:
tooltip_dict = {}
for col_name in hover_data:
@@ -564,6 +565,7 @@ def interactive(
else:
tooltips = None
+ bpl.output_notebook(hide_banner=True)
data_source = bpl.ColumnDataSource(data)
plot = bpl.figure(width=width,
@@ -577,4 +579,35 @@ def interactive(
bpl.show(plot)
else:
- raise ValueError('Too many points for interactive plotting')
+ hv.extension('bokeh')
+ hv.output(size=300)
+ hv.opts('RGB [bgcolor="{}", xaxis=None, yaxis=None]'.format(background))
+ if labels is not None:
+ point_plot = hv.Points(data, kdims=['x', 'y'], vdims=['color'])
+ plot = hd.datashade(point_plot,
+ aggregator=ds.count_cat('color'),
+ cmap=plt.get_cmap(cmap),
+ width=width,
+ height=height)
+ elif values is not None:
+ min_val = data.values.min()
+ val_range = data.values.max() - min_val
+ data['val_cat'] = pd.Categorical((data.values - min_val) //
+ (val_range // 256))
+ point_plot = hv.Points(data, kdims=['x', 'y'], vdims=['val_cat'])
+ plot = hd.datashade(point_plot,
+ aggregator=ds.count_cat('val_cat'),
+ cmap=plt.get_cmap(cmap),
+ width=width,
+ height=height)
+ else:
+ point_plot = hv.Points(data, kdims=['x', 'y'])
+ plot = hd.datashade(point_plot,
+ aggregator=ds.count(),
+ cmap=plt.get_cmap(cmap),
+ width=width,
+ height=height)
+
+ return plot
+
+
