theislab / scvelo

RNA Velocity generalized through dynamical modeling
https://scvelo.org
BSD 3-Clause "New" or "Revised" License
414 stars 102 forks source link

Plotting Differential Kinetics Error #199

Closed le-ander closed 4 years ago

le-ander commented 4 years ago

Hey Volker! I have some weird plotting issues for the differential kinetics results. Unfortunately this is not reproducible with your pancreas example (no error there).

Looks the the groups_to_bool() function produces some non numeric outpu here which numpy cannot sum. Have you seen something like this before?

top_genes = adata.var['fit_likelihood'].sort_values(ascending=False).index[:100]
scv.tl.differential_kinetic_test(adata, var_names=top_genes, groupby='louvain_separate_fine')

scv.pl.scatter(adata, basis=top_genes[:20], ncols=5, add_outline='fit_diff_kinetics')
Error ```pytb --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in ----> 1 scv.pl.scatter(adata, basis=top_genes[:20], ncols=5, add_outline='fit_diff_kinetics') ~/.local/lib/python3.7/site-packages/scvelo/plotting/scatter.py in scatter(adata, basis, x, y, vkey, color, use_raw, layer, color_map, colorbar, palette, size, alpha, linewidth, linecolor, perc, groups, sort_order, components, projection, legend_loc, legend_loc_lines, legend_fontsize, legend_fontweight, xlabel, ylabel, title, fontsize, figsize, xlim, ylim, add_density, add_assignments, add_linfit, add_polyfit, add_rug, add_text, add_text_pos, add_outline, outline_width, outline_color, n_convolve, smooth, rescale_color, color_gradients, dpi, frameon, zorder, ncols, nrows, wspace, hspace, show, save, ax, **kwargs) 109 for key in mkeys: # multi_kwargs[key] = key[i] if is multikey (list with more than 1 element) else key 110 multi_kwargs[key] = eval('{0}[i * (len({0}) > i)] if is_list({0}) else {0}'.format(key)) --> 111 ax.append(scatter(adata, ax=pl.subplot(gs), **multi_kwargs, **scatter_kwargs, **kwargs)) 112 113 if not frameon and isinstance(ylabel, str): # later makes this a label on the figure rather than axis. ~/.local/lib/python3.7/site-packages/scvelo/plotting/scatter.py in scatter(adata, basis, x, y, vkey, color, use_raw, layer, color_map, colorbar, palette, size, alpha, linewidth, linecolor, perc, groups, sort_order, components, projection, legend_loc, legend_loc_lines, legend_fontsize, legend_fontweight, xlabel, ylabel, title, fontsize, figsize, xlim, ylim, add_density, add_assignments, add_linfit, add_polyfit, add_rug, add_text, add_text_pos, add_outline, outline_width, outline_color, n_convolve, smooth, rescale_color, color_gradients, dpi, frameon, zorder, ncols, nrows, wspace, hspace, show, save, ax, **kwargs) 375 add_outline = str(adata[:, basis].var[add_outline][0]) 376 idx = groups_to_bool(adata, add_outline, color) --> 377 if idx is not None and np.sum(idx) > 0: # if anything to be outlined 378 zorder = 2 if zorder is None else zorder + 2 379 if kwargs['s'] is not None: kwargs['s'] *= 1.2 <__array_function__ internals> in sum(*args, **kwargs) /opt/python/lib/python3.7/site-packages/numpy/core/fromnumeric.py in sum(a, axis, dtype, out, keepdims, initial, where) 2227 2228 return _wrapreduction(a, np.add, 'sum', axis, dtype, out, keepdims=keepdims, -> 2229 initial=initial, where=where) 2230 2231 /opt/python/lib/python3.7/site-packages/numpy/core/fromnumeric.py in _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs) 88 return reduction(axis=axis, out=out, **passkwargs) 89 ---> 90 return ufunc.reduce(obj, axis, dtype, out, **passkwargs) 91 92 TypeError: cannot perform reduce with flexible type ```

Versions:

scvelo==0.2.0 scanpy==1.5.1 anndata==0.7.3 loompy==3.0.6 numpy==1.18.2 scipy==1.4.1 matplotlib==3.2.1 sklearn==0.22.2.post1 pandas==1.0.3

VolkerBergen commented 4 years ago

With scv.get_df(adata, 'fit_diff_kinetics') you obtain the clusters that display a diff. kinetic.

What do you get from

from scvelo.plotting.utils import groups_to_bool
groups_to_bool(adata, 'cluster_that_displays_diff_kinetic', 'louvain')
le-ander commented 4 years ago

so with this command: scv.get_df(adata, 'fit_diff_kinetics'), I see that there a couple of genes with differential kinetics in the dorsal neurons cluster.

groups_to_bool(adata, 'Dorsal Neurons', 'louvain') gives: array(['Dorsal Neurons'], dtype='<U14') When I try to sum this, I get the exact error as above.

When I plug in the correct obs col name of my louvain groups: groups_to_bool(adata, 'Dorsal Neurons', 'louvain_separate_fine')gives: array([False, False, False, ..., False, False, False]) Which can be used as input to np.sum without errors.

le-ander commented 4 years ago

Solved it. I need to specify the argument color='louvain_separate_fine' when calling sc.pl.scatter.

If feasible it might be nice to provide a more informative error here I guess :)

le-ander commented 4 years ago

But can be closed otherwise.

le-ander commented 4 years ago

Hm, not quite sure if this one is directly related (apologies for posting it here if not):

When I want to recompute velocities with taking differential kinetics into account, the function expects a obs_column called 'clusters' which is not there in my adata:

scv.tl.velocity(adata, mode='dynamical', min_likelihood=.08, diff_kinetics=True)

computing velocities

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-29-89b3e97a629c> in <module>
----> 1 scv.tl.velocity(adata, mode='dynamical', min_likelihood=.08, diff_kinetics=True, groups_for_fit='louvain_separate_fine')
      2 scv.tl.velocity_graph(adata)

~/.local/lib/python3.7/site-packages/scvelo/tools/velocity.py in velocity(data, vkey, mode, fit_offset, fit_offset2, filter_genes, groups, groupby, groups_for_fit, constrain_ratio, use_raw, use_latent_time, perc, min_r2, min_likelihood, r2_adjusted, diff_kinetics, copy, **kwargs)
    280         if not isinstance(diff_kinetics, str): diff_kinetics = 'fit_diff_kinetics'
    281         if diff_kinetics in adata.var.keys():
--> 282             clusters = adata.obs.clusters  # store in .uns
    283             for i, v in enumerate(adata.var[diff_kinetics].values):
    284                 if len(v) > 0:

/opt/python/lib/python3.7/site-packages/pandas/core/generic.py in __getattr__(self, name)
   5272             if self._info_axis._can_hold_identifiers_and_holds_name(name):
   5273                 return self[name]
-> 5274             return object.__getattribute__(self, name)
   5275 
   5276     def __setattr__(self, name: str, value) -> None:

AttributeError: 'DataFrame' object has no attribute 'clusters'
VolkerBergen commented 4 years ago

True, this was marked as todo - forgot to implement. Should be fixed now.

VolkerBergen commented 4 years ago

and color key is retrieved now correctly. Thanks for raising this!

le-ander commented 4 years ago

Great stuff! Thanks a lot, Volker!