Plotting UMAP in backed mode leads to error when setting color palettes
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.6k
- Forks
- 779
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 27
Description
- [x ] I have checked that this issue has not already been reported.
- I have confirmed this bug exists on the latest version of scanpy.
- (optional) I have confirmed this bug exists on the master branch of scanpy.
_set_colors_for_categorical_obs copies adata if it is a view (e.g. rows/cells are reordered for plotting), leading to error in plotting.
The below fails as adata is view (reordered cells) and color of 'CellType' is not in uns
However, if we first run the plot without reordering cells so that uns color is set on adata and then reorder the cells and plot the view, this works
random_indices=np.random.permutation(adatas['Human'].obs_names)
sc.pl.embedding(adatas['Human'][random_indices,:],ACTIONet2D',
color=['CellType'],hspace=0.9)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-48-8a1d75e9b375> in <module>
2 np.random.seed(0)
3 random_indices=np.random.permutation(adatas['Human'].obs_names)
----> 4 sc.pl.embedding(adatas['Human'][random_indices,:],'ACTIONet2D',
5 color=['Batch','Region','Condition', 'Grade',
6 'PMI','Sex', 'Age','SubType','CellType'],hspace=0.9)
~/miniconda3/envs/csp/lib/python3.8/site-packages/scanpy/plotting/_tools/scatterplots.py in embedding(adata, basis, color, gene_symbols, use_raw, sort_order, edges, edges_width, edges_color, neighbors_key, arrows, arrows_kwds, groups, components, layer, projection, scale_factor, color_map, cmap, palette, na_color, na_in_legend, size, frameon, legend_fontsize, legend_fontweight, legend_loc, legend_fontoutline, vmax, vmin, vcenter, norm, add_outline, outline_width, outline_color, ncols, hspace, wspace, title, show, save, ax, return_fig, **kwargs)
250 groups=groups,
251 )
--> 252 color_vector, categorical = _color_vector(
253 adata,
254 value_to_plot,
~/miniconda3/envs/csp/lib/python3.8/site-packages/scanpy/plotting/_tools/scatterplots.py in _color_vector(adata, values_key, values, palette, na_color)
1267 color_map = {
1268 k: to_hex(v)
-> 1269 for k, v in _get_palette(adata, values_key, palette=palette).items()
1270 }
1271 # If color_map does not have unique values, this can be slow as the
~/miniconda3/envs/csp/lib/python3.8/site-packages/scanpy/plotting/_tools/scatterplots.py in _get_palette(adata, values_key, palette)
1238 ):
1239 # set a default palette in case that no colors or few colors are found
-> 1240 _utils._set_default_colors_for_categorical_obs(adata, values_key)
1241 else:
1242 _utils._validate_palette(adata, values_key)
~/miniconda3/envs/csp/lib/python3.8/site-packages/scanpy/plotting/_utils.py in _set_default_colors_for_categorical_obs(adata, value_to_plot)
468 )
469
--> 470 _set_colors_for_categorical_obs(adata, value_to_plot, palette[:length])
471
472
~/miniconda3/envs/csp/lib/python3.8/site-packages/scanpy/plotting/_utils.py in _set_colors_for_categorical_obs(adata, value_to_plot, palette)
428 colors_list = [to_hex(next(cc)['color']) for x in range(len(categories))]
429
--> 430 adata.uns[value_to_plot + '_colors'] = colors_list
431
432
~/miniconda3/envs/csp/lib/python3.8/site-packages/anndata/compat/_overloaded_dict.py in __setitem__(self, key, value)
104 self.overloaded[key].set(value)
105 else:
--> 106 self.data[key] = value
107
108 def __delitem__(self, key):
~/miniconda3/envs/csp/lib/python3.8/site-packages/anndata/_core/views.py in __setitem__(self, idx, value)
32 stacklevel=2,
33 )
---> 34 with self._update() as container:
35 container[idx] = value
36
~/miniconda3/envs/csp/lib/python3.8/contextlib.py in __enter__(self)
111 del self.args, self.kwds, self.func
112 try:
--> 113 return next(self.gen)
114 except StopIteration:
115 raise RuntimeError("generator didn't yield") from None
~/miniconda3/envs/csp/lib/python3.8/site-packages/anndata/_core/views.py in _update(self)
38 def _update(self):
39 adata_view, attr_name, keys = self._view_args
---> 40 new = adata_view.copy()
41 attr = getattr(new, attr_name)
42 container = reduce(lambda d, k: d[k], keys, attr)
~/miniconda3/envs/csp/lib/python3.8/site-packages/anndata/_core/anndata.py in copy(self, filename)
1526
1527 if filename is None:
-> 1528 raise ValueError(
1529 "To copy an AnnData object in backed mode, "
1530 "pass a filename: `.copy(filename='myfilename.h5ad')`. "
ValueError: To copy an AnnData object in backed mode, pass a filename: `.copy(filename='myfilename.h5ad')`. To load the object into memory, use `.to_memory()`.
Versions
Scanpy: 1.8.2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the failure with the reordered-cell embedding example, then start in scanpy/plotting/_tools/_utils.py at _set_colors_for_categorical_obs and follow its call from scatterplots.py. Done means plotting a categorical color on a reordered backed AnnData view completes without the reported ValueError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data-visualization
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100