Basic plotting tools¶
hv resources
Gallery: https://holoviews.org/reference/
https://holoviews.org/user_guide/Customizing_Plots.html
https://holoviews.org/user_guide/Style_Mapping.html
https://holoviews.org/user_guide/Colormaps.html
https://holoviews.org/user_guide/Plotting_with_Bokeh.html
%load_ext autoreload
%autoreload 2
import holoviews as hv
import hv_anndata
from hv_anndata import A, register
from hv_anndata import scanpy as hv_sc
register()
hv.extension("bokeh")
import numpy as np
import scanpy as sc
rng = np.random.default_rng()
adata = sc.datasets.pbmc68k_reduced()
adata.layers["counts"] = adata.raw.X
del adata.raw
sc.tl.umap(adata)
adata
AnnData object with n_obs × n_vars = 700 × 765
obs: 'bulk_labels', 'n_genes', 'percent_mito', 'n_counts', 'S_score', 'G2M_score', 'phase', 'louvain'
var: 'n_counts', 'means', 'dispersions', 'dispersions_norm', 'highly_variable'
uns: 'bulk_labels_colors', 'louvain', 'louvain_colors', 'neighbors', 'pca', 'rank_genes_groups', 'umap'
obsm: 'X_pca', 'X_umap'
varm: 'PCs'
obsp: 'connectivities', 'distances'
layers: None, 'counts'
missing features:
use_raw(deprecated!)na_color(not super important)color=dimensionin plotly backend: holoviz/holoviews#5222
missing convenience:
basisfor easy X&Y
(
hv_sc.scatter(adata, A.X[:, ["PSAP", "C1QA"]], color=A.obs["bulk_labels"]).opts(
cmap="tab10", show_legend=False
)
+ hv_sc.scatter(
adata, A.layers["counts"][:, ["PSAP", "C1QA"]], color=A.obs["bulk_labels"]
).opts(cmap="tab10")
)
# add NAs to check how missing values look
adata_scatter = adata.copy()
adata_scatter.obs.loc[
(
(adata_scatter.obs["bulk_labels"] == "Dendritic")
& rng.choice([True, False], size=len(adata_scatter))
),
"bulk_labels",
] = np.nan
hv_sc.umap(adata_scatter) + hv_sc.umap(adata_scatter, color=A.obs["bulk_labels"]).opts(
cmap="tab10"
)
missing:
groupby/ TickBarstandard_scale(see implemantation inhv_anndata.Dotmap)maybe done using
dimexpressions?
dendrogram doesn’t work on heatmap (again ndim problem: dendrogram should tread
(n, 1)as 1D)
markers = ["C1QA", "PSAP", "CD79A", "CD79B", "CST3", "LYZ"]
(
hv_sc.heatmap(adata[:, markers], A.X, [A.obs["n_counts"]], add_dendrogram="obs")
+ hv_sc.heatmap(adata[:, markers], A.layers["counts"], [A.obs["n_counts"]])
).cols(1).opts(hv.opts.HeatMap(xticks=0, width=800, height=300)).opts(shared_axes=False)
/home/docs/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/operation/element.py:1365: FutureWarning: Probably comparing to a dimension created from `Dimension.name`. This will not be supported in the future, please report as an issue.
if d not in self.p.adjoint_dims:
/home/docs/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/dimension.py:1033: FutureWarning: Probably comparing to a dimension created from `Dimension.name`. This will not be supported in the future, please report as an issue.
dims = [d for d in all_dims if dimension == d]
/home/docs/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/operation/element.py:1406: FutureWarning: Probably comparing to a dimension created from `Dimension.name`. This will not be supported in the future, please report as an issue.
if dim not in self.p.adjoint_dims:
/home/docs/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/data/xarray.py:183: FutureWarning: Probably comparing to a dimension created from `Dimension.name`. This will not be supported in the future, please report as an issue.
data = {d: np.asarray(values) if d in kdims else values
/home/docs/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/data/xarray.py:230: FutureWarning: Probably comparing to a dimension created from `Dimension.name`. This will not be supported in the future, please report as an issue.
if c in kdims or len(da[c].shape) != 1 or da[c].shape[0] <= 1:
/home/docs/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/data/xarray.py:387: FutureWarning: Probably comparing to a dimension created from `Dimension.name`. This will not be supported in the future, please report as an issue.
if dim in dataset.kdims:
/home/docs/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/dimension.py:1073: FutureWarning: Probably comparing to a dimension created from `Dimension.name`. This will not be supported in the future, please report as an issue.
return next(i for i, d in enumerate(dimensions) if d == dim)
/home/docs/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/data/xarray.py:387: FutureWarning: Probably comparing to a dimension created from `Dimension.name`. This will not be supported in the future, please report as an issue.
if dim in dataset.kdims:
/home/docs/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/dimension.py:1073: FutureWarning: Probably comparing to a dimension created from `Dimension.name`. This will not be supported in the future, please report as an issue.
return next(i for i, d in enumerate(dimensions) if d == dim)
/home/docs/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/data/grid.py:326: FutureWarning: Probably comparing to a dimension created from `Dimension.name`. This will not be supported in the future, please report as an issue.
if d not in dataset.kdims+virtual_coords]
TODO: support sparse data
hv_sc.heatmap(adata[:40], A.obsp["distances"]).opts(tools=["hover"])
missing:
var_group_*(highlight groups ofvar_namesby drawing brackets)
markers = ["C1QA", "PSAP", "CD79A", "CD79B", "CST3", "LYZ"]
dm = hv_anndata.Dotmap(adata=adata, marker_genes=markers, groupby="bulk_labels")
dm
WARNING:param.main: JSONEditor was not imported on instantiation and may not render in a notebook. Restart the notebook kernel and ensure you load it as part of the extension using:
pn.extension('jsoneditor')
hv.operation.dendrogram(
dm.plot(), adjoint_dims=["cluster"], main_dim="mean_expression", invert=True
)
missing:
shared_xaxis=Falsedoesn’t seem to work on GridSpaceGridSpace can only be 2D or row-only, not col-only
hv_sc.tracksplot(
adata,
A.X[:, ["C1QA", "PSAP", "CD79A", "CD79B", "CST3", "LYZ"]],
color=A.obs["bulk_labels"],
).opts(hv.opts.Curve(aspect=20))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/dimension.py:1381, in Dimensioned._repr_mimebundle_(self, include, exclude)
1374 def _repr_mimebundle_(self, include=None, exclude=None):
1375 """Resolves the class hierarchy for the class rendering the
1376 object using any display hooks registered on Store.display
1377 hooks. The output of all registered display_hooks is then
1378 combined and returned.
1379
1380 """
-> 1381 return Store.render(self)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/options.py:1433, in Store.render(cls, obj)
1431 data, metadata = {}, {}
1432 for hook in hooks:
-> 1433 ret = hook(obj)
1434 if ret is None:
1435 continue
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:340, in pprint_display(obj)
338 if not ip.display_formatter.formatters['text/plain'].pprint:
339 return None
--> 340 return display(obj, raw_output=True)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:311, in display(obj, raw_output, **kwargs)
309 elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
310 with option_state(obj):
--> 311 output = layout_display(obj)
312 elif isinstance(obj, (HoloMap, DynamicMap)):
313 with option_state(obj):
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:205, in display_hook.<locals>.wrapped(element)
203 try:
204 max_frames = OutputSettings.options['max_frames']
--> 205 mimebundle = fn(element, max_frames=max_frames)
206 if mimebundle is None:
207 return {}, {}
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:274, in layout_display(layout, max_frames)
271 max_frame_warning(max_frames)
272 return None
--> 274 return render(layout)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:76, in render(obj, **kwargs)
73 if renderer.fig == 'pdf':
74 renderer = renderer.instance(fig='png')
---> 76 return renderer.components(obj, **kwargs)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/renderer.py:396, in Renderer.components(self, obj, fmt, comm, **kwargs)
394 embed = (not (dynamic or streams or self.widget_mode == 'live') or config.embed)
395 if embed or config.comms == 'default':
--> 396 return self._render_panel(plot, embed, comm)
397 return self._render_ipywidget(plot)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/renderer.py:403, in Renderer._render_panel(self, plot, embed, comm)
401 doc = Document()
402 with config.set(embed=embed):
--> 403 model = plot.layout._render_model(doc, comm)
404 if embed:
405 return render_model(model, comm)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/viewable.py:775, in Viewable._render_model(self, doc, comm)
773 if comm is None:
774 comm = state._comm_manager.get_server_comm()
--> 775 model = self.get_root(doc, comm)
777 if self._design and self._design.theme.bokeh_theme:
778 doc.theme = self._design.theme.bokeh_theme
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/layout/base.py:332, in Panel.get_root(self, doc, comm, preprocess)
328 def get_root(
329 self, doc: Document | None = None, comm: Comm | None = None,
330 preprocess: bool = True
331 ) -> Model:
--> 332 root = super().get_root(doc, comm, preprocess)
333 # ALERT: Find a better way to handle this
334 if hasattr(root, 'styles') and 'overflow-x' in root.styles:
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/viewable.py:705, in Renderable.get_root(self, doc, comm, preprocess)
703 wrapper = self._design._wrapper(self)
704 if wrapper is self:
--> 705 root = self._get_model(doc, comm=comm)
706 if preprocess:
707 self._preprocess(root)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/layout/base.py:316, in Panel._get_model(self, doc, root, parent, comm)
314 root = root or model
315 self._models[root.ref['id']] = (model, parent)
--> 316 objects, _ = self._get_objects(model, [], doc, root, comm)
317 props = self._get_properties(doc)
318 props[self._property_mapping['objects']] = objects
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/layout/base.py:298, in Panel._get_objects(self, model, old_objects, doc, root, comm)
296 else:
297 try:
--> 298 child = pane._get_model(doc, root, model, comm)
299 except RerenderError as e:
300 if e.layout is not None and e.layout is not self:
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/pane/holoviews.py:494, in HoloViews._get_model(self, doc, root, parent, comm)
492 plot = self.object
493 else:
--> 494 plot = self._render(doc, comm, root)
496 plot.pane = self
497 backend = plot.renderer.backend
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/pane/holoviews.py:588, in HoloViews._render(self, doc, comm, root)
585 if comm:
586 kwargs['comm'] = comm
--> 588 return renderer.get_plot(self.object, **kwargs)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/renderer.py:70, in BokehRenderer.get_plot(self_or_cls, obj, doc, renderer, **kwargs)
63 @bothmethod
64 def get_plot(self_or_cls, obj, doc=None, renderer=None, **kwargs):
65 """Given a HoloViews Viewable return a corresponding plot instance.
66 Allows supplying a document attach the plot to, useful when
67 combining the bokeh model with another plot.
68
69 """
---> 70 plot = super().get_plot(obj, doc, renderer, **kwargs)
71 if plot.document is None:
72 plot.document = Document() if self_or_cls.notebook_context else curdoc()
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/renderer.py:234, in Renderer.get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
232 if isinstance(obj, AdjointLayout):
233 obj = Layout(obj)
--> 234 plot = self_or_cls.plotting_class(obj)(obj, renderer=renderer,
235 **plot_opts)
236 defaults = [kd.default for kd in plot.dimensions]
237 init_key = tuple(v if d is None else d for v, d in
238 zip(plot.keys[0], defaults, strict=None))
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/plot.py:748, in LayoutPlot.__init__(self, layout, keys, **params)
746 def __init__(self, layout, keys=None, **params):
747 super().__init__(layout, keys=keys, **params)
--> 748 self.layout, self.subplots, self.paths = self._init_layout(layout)
749 if self.top_level:
750 self.traverse(lambda x: attach_streams(self, x.hmap, 2),
751 [GenericElementPlot])
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/plot.py:801, in LayoutPlot._init_layout(self, layout)
799 layout_count += 1
800 num = 0 if empty else layout_count
--> 801 subplots, adjoint_layout = self._create_subplots(
802 view, positions, layout_dimensions, frame_ranges, num=num
803 )
805 # Generate the AdjointLayoutsPlot which will coordinate
806 # plotting of AdjointLayouts in the larger grid
807 plotopts = self.lookup_options(view, 'plot').options
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/plot.py:870, in LayoutPlot._create_subplots(self, layout, positions, layout_dimensions, ranges, num)
868 continue
869 num = num if len(self.coords) > 1 else 0
--> 870 subplot = plot_type(element, keys=self.keys,
871 dimensions=self.dimensions,
872 layout_dimensions=layout_dimensions,
873 ranges=ranges, subplot=True, root=self.root,
874 uniform=self.uniform, layout_num=num,
875 renderer=self.renderer,
876 **dict({'shared_axes': self.shared_axes},
877 **plotopts))
878 subplots[pos] = subplot
879 if isinstance(plot_type, type) and issubclass(plot_type, GenericCompositePlot):
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/element.py:3108, in OverlayPlot.__init__(self, overlay, **kwargs)
3106 def __init__(self, overlay, **kwargs):
3107 self._multi_y_propagation = self.lookup_options(overlay, 'plot').options.get('multi_y', False)
-> 3108 super().__init__(overlay, **kwargs)
3109 self.callbacks, self.source_streams = self._construct_callbacks()
3110 self._multi_y_propagation = False
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/plot.py:1755, in GenericOverlayPlot.__init__(self, overlay, ranges, batched, keys, group_counter, **params)
1752 if 'projection' not in params:
1753 params['projection'] = self._get_projection(overlay)
-> 1755 super().__init__(overlay, ranges=ranges, keys=keys,
1756 batched=batched, **params)
1758 if ('multi_y' in self.param) and self.multi_y:
1759 for s in self.streams:
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/element.py:364, in ElementPlot.__init__(self, element, plot, **params)
362 self._subcoord_standalone_ = None
363 self.current_ranges = None
--> 364 super().__init__(element, **params)
365 self.handles = {} if plot is None else self.handles['plot']
366 self.static = len(self.hmap) == 1 and len(self.keys) == len(self.hmap)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/plot.py:1264, in GenericElementPlot.__init__(self, element, keys, ranges, dimensions, batched, overlaid, cyclic_index, zorder, style, overlay_dims, stream_sources, streams, **params)
1262 if p in self.param and p in self._deprecations and pval is not None:
1263 self.param.warning(self._deprecations[p])
-> 1264 super().__init__(keys=keys, dimensions=dimensions,
1265 dynamic=dynamic, **applied_params)
1266 self.batched = batched
1267 self.streams = get_nested_streams(self.hmap) if streams is None else streams
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/plot.py:435, in DimensionedPlot.__init__(self, keys, dimensions, layout_dimensions, uniform, subplot, adjoined, layout_num, style, subplots, dynamic, **params)
433 self.ranges = {}
434 self._updated = False # Whether the plot should be marked as updated
--> 435 super().__init__(**params)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/plot.py:70, in Plot.__init__(self, renderer, root, **params)
67 def __init__(self, renderer=None, root=None, **params):
68 params = {k: v for k, v in params.items()
69 if k in self.param}
---> 70 super().__init__(**params)
71 self.renderer = renderer if renderer else Store.renderers[self.backend].instance()
72 self._force = False
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/param/parameterized.py:5879, in Parameterized.__init__(self, **params)
5877 if self.param.name.default == self.__class__.__name__:
5878 self.param._generate_name()
-> 5879 refs, deps = self.param._setup_params(**params)
5880 object_count += 1
5882 self._param__private.initialized = True
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/param/parameterized.py:2316, in as_uninitialized.<locals>.override_initialization(self_, *args, **kw)
2314 original_initialized = parameterized_instance._param__private.initialized
2315 parameterized_instance._param__private.initialized = False
-> 2316 ret = fn(self_, *args, **kw)
2317 parameterized_instance._param__private.initialized = original_initialized
2318 return ret
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/param/parameterized.py:2646, in Parameters._setup_params(self_, **params)
2634 if ref:
2635 warnings.warn(
2636 f"Parameter {name!r} on {pobj.owner} is being given a valid parameter "
2637 f"reference {val} but is implicitly allow_refs=False. "
(...) 2644 stacklevel=_find_stack_level(),
2645 )
-> 2646 setattr(self, name, val)
2647 continue
2649 # Resolve references
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/param/parameterized.py:679, in instance_descriptor.<locals>._f(self, obj, val)
677 instance_param.__set__(obj, val)
678 return
--> 679 return f(self, obj, val)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/param/parameterized.py:1992, in Parameter.__set__(self, obj, val)
1989 if is_async or val is Undefined:
1990 return
-> 1992 self._validate(val)
1994 _old = NotImplemented
1995 # obj can be None if __set__ is called for a Parameterized class
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/param/parameterized.py:2274, in String._validate(self, val)
2273 def _validate(self, val: t.Any):
-> 2274 self._validate_value(val, self.allow_None)
2275 self._validate_regex(val, self.regex)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/param/parameterized.py:2268, in String._validate_value(self, value, allow_None)
2266 return
2267 if not isinstance(value, str):
-> 2268 raise ValueError(
2269 f'{_validate_error_prefix(self)} only takes a string value, '
2270 f'not value of {type(value)}.'
2271 )
ValueError: String parameter 'GenericElementPlot.ylabel' only takes a string value, not value of <class 'hv_anndata._ref.AdDim'>.
:NdLayout [marker]
:NdOverlay [A.obs['bulk_labels']]
:Curve [A.obs.index] (PSAP,bulk_labels)
missing:
density_norm
hv_sc.violin(adata, A.obs[["percent_mito", "n_counts", "n_genes"]]).opts(
hv.opts.Violin(ylim=(0, None))
)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/dimension.py:1381, in Dimensioned._repr_mimebundle_(self, include, exclude)
1374 def _repr_mimebundle_(self, include=None, exclude=None):
1375 """Resolves the class hierarchy for the class rendering the
1376 object using any display hooks registered on Store.display
1377 hooks. The output of all registered display_hooks is then
1378 combined and returned.
1379
1380 """
-> 1381 return Store.render(self)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/options.py:1433, in Store.render(cls, obj)
1431 data, metadata = {}, {}
1432 for hook in hooks:
-> 1433 ret = hook(obj)
1434 if ret is None:
1435 continue
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:340, in pprint_display(obj)
338 if not ip.display_formatter.formatters['text/plain'].pprint:
339 return None
--> 340 return display(obj, raw_output=True)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:311, in display(obj, raw_output, **kwargs)
309 elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
310 with option_state(obj):
--> 311 output = layout_display(obj)
312 elif isinstance(obj, (HoloMap, DynamicMap)):
313 with option_state(obj):
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:205, in display_hook.<locals>.wrapped(element)
203 try:
204 max_frames = OutputSettings.options['max_frames']
--> 205 mimebundle = fn(element, max_frames=max_frames)
206 if mimebundle is None:
207 return {}, {}
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:274, in layout_display(layout, max_frames)
271 max_frame_warning(max_frames)
272 return None
--> 274 return render(layout)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:76, in render(obj, **kwargs)
73 if renderer.fig == 'pdf':
74 renderer = renderer.instance(fig='png')
---> 76 return renderer.components(obj, **kwargs)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/renderer.py:396, in Renderer.components(self, obj, fmt, comm, **kwargs)
394 embed = (not (dynamic or streams or self.widget_mode == 'live') or config.embed)
395 if embed or config.comms == 'default':
--> 396 return self._render_panel(plot, embed, comm)
397 return self._render_ipywidget(plot)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/renderer.py:403, in Renderer._render_panel(self, plot, embed, comm)
401 doc = Document()
402 with config.set(embed=embed):
--> 403 model = plot.layout._render_model(doc, comm)
404 if embed:
405 return render_model(model, comm)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/viewable.py:775, in Viewable._render_model(self, doc, comm)
773 if comm is None:
774 comm = state._comm_manager.get_server_comm()
--> 775 model = self.get_root(doc, comm)
777 if self._design and self._design.theme.bokeh_theme:
778 doc.theme = self._design.theme.bokeh_theme
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/layout/base.py:332, in Panel.get_root(self, doc, comm, preprocess)
328 def get_root(
329 self, doc: Document | None = None, comm: Comm | None = None,
330 preprocess: bool = True
331 ) -> Model:
--> 332 root = super().get_root(doc, comm, preprocess)
333 # ALERT: Find a better way to handle this
334 if hasattr(root, 'styles') and 'overflow-x' in root.styles:
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/viewable.py:705, in Renderable.get_root(self, doc, comm, preprocess)
703 wrapper = self._design._wrapper(self)
704 if wrapper is self:
--> 705 root = self._get_model(doc, comm=comm)
706 if preprocess:
707 self._preprocess(root)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/layout/base.py:316, in Panel._get_model(self, doc, root, parent, comm)
314 root = root or model
315 self._models[root.ref['id']] = (model, parent)
--> 316 objects, _ = self._get_objects(model, [], doc, root, comm)
317 props = self._get_properties(doc)
318 props[self._property_mapping['objects']] = objects
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/layout/base.py:298, in Panel._get_objects(self, model, old_objects, doc, root, comm)
296 else:
297 try:
--> 298 child = pane._get_model(doc, root, model, comm)
299 except RerenderError as e:
300 if e.layout is not None and e.layout is not self:
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/pane/holoviews.py:494, in HoloViews._get_model(self, doc, root, parent, comm)
492 plot = self.object
493 else:
--> 494 plot = self._render(doc, comm, root)
496 plot.pane = self
497 backend = plot.renderer.backend
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/pane/holoviews.py:588, in HoloViews._render(self, doc, comm, root)
585 if comm:
586 kwargs['comm'] = comm
--> 588 return renderer.get_plot(self.object, **kwargs)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/renderer.py:70, in BokehRenderer.get_plot(self_or_cls, obj, doc, renderer, **kwargs)
63 @bothmethod
64 def get_plot(self_or_cls, obj, doc=None, renderer=None, **kwargs):
65 """Given a HoloViews Viewable return a corresponding plot instance.
66 Allows supplying a document attach the plot to, useful when
67 combining the bokeh model with another plot.
68
69 """
---> 70 plot = super().get_plot(obj, doc, renderer, **kwargs)
71 if plot.document is None:
72 plot.document = Document() if self_or_cls.notebook_context else curdoc()
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/renderer.py:239, in Renderer.get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
236 defaults = [kd.default for kd in plot.dimensions]
237 init_key = tuple(v if d is None else d for v, d in
238 zip(plot.keys[0], defaults, strict=None))
--> 239 plot.update(init_key)
240 else:
241 plot = obj
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/plot.py:958, in DimensionedPlot.update(self, key)
956 def update(self, key):
957 if len(self) == 1 and key in (0, self.keys[0]) and not self.drawn:
--> 958 return self.initialize_plot()
959 item = self.__getitem__(key)
960 self.traverse(lambda x: setattr(x, '_updated', True))
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/plot.py:954, in LayoutPlot.initialize_plot(self, plots, ranges)
951 continue
953 shared_plots = list(passed_plots) if self.shared_axes else None
--> 954 subplots = subplot.initialize_plot(ranges=ranges, plots=shared_plots)
955 nsubplots = len(subplots)
957 modes = {sp.sizing_mode for sp in subplots
958 if sp.sizing_mode not in (None, 'auto', 'fixed')}
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/plot.py:1103, in AdjointLayoutPlot.initialize_plot(self, ranges, plots)
1101 else:
1102 passed_plots = plots + adjoined_plots
-> 1103 adjoined_plots.append(subplot.initialize_plot(ranges=ranges, plots=passed_plots))
1104 self.drawn = True
1105 return adjoined_plots or [None]
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/element.py:2220, in ElementPlot.initialize_plot(self, ranges, plot, plots, source)
2218 if self.autorange:
2219 self._setup_autorange()
-> 2220 self._init_glyphs(plot, element, ranges, source)
2221 if not self.overlaid:
2222 self._update_plot(key, plot, style_element)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/element.py:2548, in CompositeElementPlot._init_glyphs(self, plot, element, ranges, source, data, mapping, style)
2546 if None in (data, mapping):
2547 style = self.style[self.cyclic_index]
-> 2548 data, mapping, style = self.get_data(element, ranges, style)
2550 keys = glyph_order(dict(data, **mapping), self._draw_order)
2552 source_cache = {}
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/stats.py:551, in ViolinPlot.get_data(self, element, ranges, style)
549 if element.kdims:
550 key = tuple(d.pprint_value(k) for d, k in zip(element.kdims, key, strict=None))
--> 551 kde, line, segs, bars, scatter = self._kde_data(
552 element, g, key, split_dim, split_cats, **kwargs
553 )
554 for k, v in segs.items():
555 seg_data[k] += v
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/stats.py:488, in ViolinPlot._kde_data(self, element, el, key, split_dim, split_cats, **kwargs)
486 elif self.inner == 'box':
487 xpos = (*key, 0)
--> 488 q1, q2, q3, upper, lower, _ = self._box_stats(values)
489 segments['x'].append(xpos)
490 segments['y0'].append(lower)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/stats.py:164, in BoxWhiskerPlot._box_stats(self, vals)
162 q1, q2, q3 = 0, 0, 0
163 upper, lower = 0, 0
--> 164 outliers = vals[(vals > upper) | (vals < lower)]
166 if is_cupy:
167 return (q1.item(), q2.item(), q3.item(), upper.item(),
168 lower.item(), cupy.asnumpy(outliers))
TypeError: unsupported operand type(s) for |: 'NumpyExtensionArray' and 'NumpyExtensionArray'
:Layout
.Violin.I :Violin (percent_mito)
.Violin.II :Violin (n_counts)
.Violin.III :Violin (n_genes)
hv_sc.violin(adata, A.obs["S_score"], color=A.obs["bulk_labels"]).opts(
width=500, xrotation=30
)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/dimension.py:1381, in Dimensioned._repr_mimebundle_(self, include, exclude)
1374 def _repr_mimebundle_(self, include=None, exclude=None):
1375 """Resolves the class hierarchy for the class rendering the
1376 object using any display hooks registered on Store.display
1377 hooks. The output of all registered display_hooks is then
1378 combined and returned.
1379
1380 """
-> 1381 return Store.render(self)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/core/options.py:1433, in Store.render(cls, obj)
1431 data, metadata = {}, {}
1432 for hook in hooks:
-> 1433 ret = hook(obj)
1434 if ret is None:
1435 continue
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:340, in pprint_display(obj)
338 if not ip.display_formatter.formatters['text/plain'].pprint:
339 return None
--> 340 return display(obj, raw_output=True)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:308, in display(obj, raw_output, **kwargs)
306 elif isinstance(obj, (CompositeOverlay, ViewableElement)):
307 with option_state(obj):
--> 308 output = element_display(obj)
309 elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
310 with option_state(obj):
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:205, in display_hook.<locals>.wrapped(element)
203 try:
204 max_frames = OutputSettings.options['max_frames']
--> 205 mimebundle = fn(element, max_frames=max_frames)
206 if mimebundle is None:
207 return {}, {}
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:246, in element_display(element, max_frames)
243 if type(element) not in Store.registry[backend]:
244 return None
--> 246 return render(element)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/ipython/display_hooks.py:76, in render(obj, **kwargs)
73 if renderer.fig == 'pdf':
74 renderer = renderer.instance(fig='png')
---> 76 return renderer.components(obj, **kwargs)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/renderer.py:396, in Renderer.components(self, obj, fmt, comm, **kwargs)
394 embed = (not (dynamic or streams or self.widget_mode == 'live') or config.embed)
395 if embed or config.comms == 'default':
--> 396 return self._render_panel(plot, embed, comm)
397 return self._render_ipywidget(plot)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/renderer.py:403, in Renderer._render_panel(self, plot, embed, comm)
401 doc = Document()
402 with config.set(embed=embed):
--> 403 model = plot.layout._render_model(doc, comm)
404 if embed:
405 return render_model(model, comm)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/viewable.py:775, in Viewable._render_model(self, doc, comm)
773 if comm is None:
774 comm = state._comm_manager.get_server_comm()
--> 775 model = self.get_root(doc, comm)
777 if self._design and self._design.theme.bokeh_theme:
778 doc.theme = self._design.theme.bokeh_theme
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/layout/base.py:332, in Panel.get_root(self, doc, comm, preprocess)
328 def get_root(
329 self, doc: Document | None = None, comm: Comm | None = None,
330 preprocess: bool = True
331 ) -> Model:
--> 332 root = super().get_root(doc, comm, preprocess)
333 # ALERT: Find a better way to handle this
334 if hasattr(root, 'styles') and 'overflow-x' in root.styles:
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/viewable.py:705, in Renderable.get_root(self, doc, comm, preprocess)
703 wrapper = self._design._wrapper(self)
704 if wrapper is self:
--> 705 root = self._get_model(doc, comm=comm)
706 if preprocess:
707 self._preprocess(root)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/layout/base.py:316, in Panel._get_model(self, doc, root, parent, comm)
314 root = root or model
315 self._models[root.ref['id']] = (model, parent)
--> 316 objects, _ = self._get_objects(model, [], doc, root, comm)
317 props = self._get_properties(doc)
318 props[self._property_mapping['objects']] = objects
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/layout/base.py:298, in Panel._get_objects(self, model, old_objects, doc, root, comm)
296 else:
297 try:
--> 298 child = pane._get_model(doc, root, model, comm)
299 except RerenderError as e:
300 if e.layout is not None and e.layout is not self:
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/pane/holoviews.py:494, in HoloViews._get_model(self, doc, root, parent, comm)
492 plot = self.object
493 else:
--> 494 plot = self._render(doc, comm, root)
496 plot.pane = self
497 backend = plot.renderer.backend
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/panel/pane/holoviews.py:588, in HoloViews._render(self, doc, comm, root)
585 if comm:
586 kwargs['comm'] = comm
--> 588 return renderer.get_plot(self.object, **kwargs)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/renderer.py:70, in BokehRenderer.get_plot(self_or_cls, obj, doc, renderer, **kwargs)
63 @bothmethod
64 def get_plot(self_or_cls, obj, doc=None, renderer=None, **kwargs):
65 """Given a HoloViews Viewable return a corresponding plot instance.
66 Allows supplying a document attach the plot to, useful when
67 combining the bokeh model with another plot.
68
69 """
---> 70 plot = super().get_plot(obj, doc, renderer, **kwargs)
71 if plot.document is None:
72 plot.document = Document() if self_or_cls.notebook_context else curdoc()
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/renderer.py:239, in Renderer.get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
236 defaults = [kd.default for kd in plot.dimensions]
237 init_key = tuple(v if d is None else d for v, d in
238 zip(plot.keys[0], defaults, strict=None))
--> 239 plot.update(init_key)
240 else:
241 plot = obj
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/plot.py:958, in DimensionedPlot.update(self, key)
956 def update(self, key):
957 if len(self) == 1 and key in (0, self.keys[0]) and not self.drawn:
--> 958 return self.initialize_plot()
959 item = self.__getitem__(key)
960 self.traverse(lambda x: setattr(x, '_updated', True))
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/element.py:2220, in ElementPlot.initialize_plot(self, ranges, plot, plots, source)
2218 if self.autorange:
2219 self._setup_autorange()
-> 2220 self._init_glyphs(plot, element, ranges, source)
2221 if not self.overlaid:
2222 self._update_plot(key, plot, style_element)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/element.py:2548, in CompositeElementPlot._init_glyphs(self, plot, element, ranges, source, data, mapping, style)
2546 if None in (data, mapping):
2547 style = self.style[self.cyclic_index]
-> 2548 data, mapping, style = self.get_data(element, ranges, style)
2550 keys = glyph_order(dict(data, **mapping), self._draw_order)
2552 source_cache = {}
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/stats.py:551, in ViolinPlot.get_data(self, element, ranges, style)
549 if element.kdims:
550 key = tuple(d.pprint_value(k) for d, k in zip(element.kdims, key, strict=None))
--> 551 kde, line, segs, bars, scatter = self._kde_data(
552 element, g, key, split_dim, split_cats, **kwargs
553 )
554 for k, v in segs.items():
555 seg_data[k] += v
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/stats.py:488, in ViolinPlot._kde_data(self, element, el, key, split_dim, split_cats, **kwargs)
486 elif self.inner == 'box':
487 xpos = (*key, 0)
--> 488 q1, q2, q3, upper, lower, _ = self._box_stats(values)
489 segments['x'].append(xpos)
490 segments['y0'].append(lower)
File ~/.local/share/hatch/env/virtual/hv-anndata/STk7F69l/docs/lib/python3.13/site-packages/holoviews/plotting/bokeh/stats.py:164, in BoxWhiskerPlot._box_stats(self, vals)
162 q1, q2, q3 = 0, 0, 0
163 upper, lower = 0, 0
--> 164 outliers = vals[(vals > upper) | (vals < lower)]
166 if is_cupy:
167 return (q1.item(), q2.item(), q3.item(), upper.item(),
168 lower.item(), cupy.asnumpy(outliers))
TypeError: unsupported operand type(s) for |: 'NumpyExtensionArray' and 'NumpyExtensionArray'
:Violin [A.obs['bulk_labels']] (S_score)
missing:
see tracksplot above
can’t do
.hist()or.operations.dendrogramon GridSpaceslow!
markers = ["C1QA", "PSAP", "CD79A", "CD79B", "CST3", "LYZ"]
hv_sc.stacked_violin(adata[:, markers], A.var.index, A.obs["bulk_labels"]).opts(
hv.opts.Violin(frame_height=50, frame_width=50)
)
missing:
aspect="equal"breaks (bokeh tries to divideNone/None)hist doesn’t align properly
markers = ["C1QA", "PSAP", "CD79A", "CD79B", "CST3", "LYZ"]
hv_sc.matrixplot(
adata[:, markers], A.obs["bulk_labels"], data=A.layers["counts"], add_totals=True
).opts(hv.opts.Bars(width=150))
missing:
TickBar (see above)
hv_anndata.ClusterMap(adata=adata)