From 6b1118888e26195d9eb896301da0634eb4a45c49 Mon Sep 17 00:00:00 2001 From: Dominik Klein Date: Fri, 23 Dec 2022 09:52:17 +0100 Subject: [PATCH] Feature/interpolate colors sankey (#434) * fix return type in mpl * change import acronyms * fix tests * add interpolation option to sankey * add test to interpolate color * define colors for pull/push` * adapt tests * introduce axes in mpl.push/pull * incorporate requested changes * change default color * adapt plotting * introduce scaling * fix scale * make start/end categorical in plot * regenerate images --- src/moscot/_constants/_key.py | 60 ++++- src/moscot/_docs/_docs_plot.py | 43 +++- src/moscot/plotting/_plotting.py | 78 +++++-- src/moscot/plotting/_utils.py | 208 +++++++++++++----- src/moscot/problems/time/_mixins.py | 8 + tests/conftest.py | 5 + tests/plotting/_images/Plotting_pull.png | Bin 576 -> 17018 bytes tests/plotting/_images/Plotting_push.png | Bin 576 -> 16640 bytes tests/plotting/_images/Plotting_sankey.png | Bin 23136 -> 17960 bytes .../_images/Plotting_sankey_params.png | Bin 16160 -> 21101 bytes tests/plotting/conftest.py | 27 ++- tests/plotting/test_plotting.py | 10 +- tests/plotting/test_utils.py | 7 +- 13 files changed, 350 insertions(+), 96 deletions(-) diff --git a/src/moscot/_constants/_key.py b/src/moscot/_constants/_key.py index 0124d70f8..e5869ed53 100644 --- a/src/moscot/_constants/_key.py +++ b/src/moscot/_constants/_key.py @@ -1,4 +1,8 @@ -from typing import Any, Callable +from typing import Any, Set, List, Callable, Optional + +import numpy as np + +from anndata import AnnData class cprop: @@ -28,3 +32,57 @@ def spatial(cls) -> str: @classmethod def nhood_enrichment(cls, cluster: str) -> str: return f"{cluster}_nhood_enrichment" + + +class RandomKeys: + """ + Create random keys inside an :class:`anndata.AnnData` object. + + Parameters + ---------- + adata + Annotated data object. + n + Number of keys, If `None`, create just 1 keys. + where + Attribute of ``adata``. If `'obs'`, also clean up `'{key}_colors'` for each generated key. + + """ + + def __init__(self, adata: AnnData, n: Optional[int] = None, where: str = "obs"): + self._adata = adata + self._where = where + self._n = n or 1 + self._keys: List[str] = [] + + def _generate_random_keys(self): + def generator(): + return f"RNG_COL_{np.random.randint(2 ** 16)}" + + where = getattr(self._adata, self._where) + names: List[str] = [] + seen: Set[str] = set(where.keys()) + + while len(names) != self._n: + name = generator() + if name not in seen: + seen.add(name) + names.append(name) + + return names + + def __enter__(self): + self._keys = self._generate_random_keys() + return self._keys + + def __exit__(self, exc_type, exc_val, exc_tb): + for key in self._keys: + try: + getattr(self._adata, self._where).drop(key, axis="columns", inplace=True) + except KeyError: + pass + if self._where == "obs": + try: + del self._adata.uns[f"{key}_colors"] + except KeyError: + pass diff --git a/src/moscot/_docs/_docs_plot.py b/src/moscot/_docs/_docs_plot.py index b6a8b4f7c..cdeb567ba 100644 --- a/src/moscot/_docs/_docs_plot.py +++ b/src/moscot/_docs/_docs_plot.py @@ -18,7 +18,7 @@ """ _cbar_kwargs_cell_transition = """\ cbar_kwargs - Keyword arguments for :meth:`matplotlib.figure.Figure.colorbar`.""" + Keyword arguments for :func:`matplotlib.figure.Figure.colorbar`.""" # return cell transition _return_cell_transition = """\ :class:`matplotlib.figure.Figure` heatmap of cell transition matrix. @@ -64,7 +64,18 @@ - `captions` - `key` """ - +_alpha_transparency = """\ +alpha + Transparancy value. +""" +_interpolate_color = """\ +interpolate_color + Whether the color is continuously interpolated. +""" +_sankey_kwargs = """\ +kwargs + Keyword arguments for :func:`matplotlib.pyplot.fill_between`. +""" ############################################################################### # plotting.push/pull # input @@ -85,6 +96,10 @@ basis Basis of the embedding, saved in :attr:`anndata.AnnData.obsm`. """ +_scale_push_pull = """\ +scale + Whether to linearly scale the distribution. +""" # return push/pull _return_push_pull = """\ :class:`matplotlib.figure.Figure` scatterplot in `basis` coordinates. @@ -113,8 +128,20 @@ Colormap for continuous annotations, see :class:`matplotlib.colors.Colormap`.""" _title = """\ title - TODO.""" - + Title of the plot. +""" +_dot_scale_factor = """\ +dot_scale_factor + If `time_points` is not `None`, `dot_scale_factor` increases the size of the dots by this factor. +""" +_na_color = """\ +na_color + Color to use for null or masked values. Can be anything matplotlib accepts as a color. +""" +_suptitle_fontsize = """ +suptitle_fontsize + Fontsize of the suptitle. +""" ############################################################################### # general output _return_fig = """\ @@ -133,6 +160,7 @@ Path where to save the plot. If `None`, the plot is not saved. {_ax}""" + d_plotting = DocstringProcessor( desc_cell_transition=_desc_cell_transition, transition_labels_cell_transition=_transition_labels_cell_transition, @@ -159,4 +187,11 @@ ax=_ax, figsize_dpi_save=_figsize_dpi_save, fontsize=_fontsize, + alpha_transparency=_alpha_transparency, + interpolate_color=_interpolate_color, + sankey_kwargs=_sankey_kwargs, + na_color=_na_color, + dot_scale_factor=_dot_scale_factor, + scale_push_pull=_scale_push_pull, + suptitle_fontsize=_suptitle_fontsize, ) diff --git a/src/moscot/plotting/_plotting.py b/src/moscot/plotting/_plotting.py index df1df7558..1eb36b2d7 100644 --- a/src/moscot/plotting/_plotting.py +++ b/src/moscot/plotting/_plotting.py @@ -1,5 +1,5 @@ from types import MappingProxyType -from typing import Any, Dict, List, Tuple, Union, Mapping, Iterable, Optional +from typing import Any, Dict, List, Tuple, Union, Mapping, Optional, Sequence from matplotlib import colors as mcolors from matplotlib.axes import Axes @@ -11,10 +11,9 @@ from moscot.problems.base import CompoundProblem # type: ignore[attr-defined] from moscot.problems.time import LineageProblem, TemporalProblem # type: ignore[attr-defined] -from moscot.plotting._utils import _sankey, _heatmap, _plot_temporal, _input_to_adatas +from moscot.plotting._utils import _sankey, _heatmap, _plot_temporal, _input_to_adatas, _create_col_colors from moscot._docs._docs_plot import d_plotting from moscot._constants._constants import AdataKeys, PlottingKeys, PlottingDefaults -from moscot.problems.base._compound_problem import K @d_plotting.dedent @@ -30,7 +29,7 @@ def cell_transition( dpi: Optional[int] = None, save: Optional[str] = None, ax: Optional[Axes] = None, - return_fig: bool = True, + return_fig: bool = False, cbar_kwargs: Mapping[str, Any] = MappingProxyType({}), **kwargs: Any, ) -> mpl.figure.Figure: @@ -99,12 +98,14 @@ def sankey( captions: Optional[List[str]] = None, title: Optional[str] = None, colors_dict: Optional[Dict[str, float]] = None, + alpha: float = 1.0, + interpolate_color: bool = False, cmap: Union[str, mcolors.Colormap] = "viridis", figsize: Optional[Tuple[float, float]] = None, dpi: Optional[int] = None, save: Optional[str] = None, ax: Optional[Axes] = None, - return_fig: bool = True, + return_fig: bool = False, **kwargs: Any, ) -> mpl.figure.Figure: """ @@ -119,8 +120,11 @@ def sankey( %(captions_sankey)s %(title)s %(colors_dict_sankey)s + %(alpha_transparency)s + %(interpolate_color)s %(cmap)s %(figsize_dpi_save)s + %(sankey_kwargs)s Returns ------- @@ -150,6 +154,8 @@ def sankey( figsize=figsize, dpi=dpi, ax=ax, + alpha=alpha, + interpolate_color=interpolate_color, **kwargs, ) if save: @@ -162,17 +168,21 @@ def sankey( def push( inp: Union[AnnData, TemporalProblem, LineageProblem, CompoundProblem], uns_key: Optional[str] = None, - time_points: Optional[Iterable[K]] = None, + time_points: Optional[Sequence[float]] = None, basis: str = "umap", - result_key: str = "plot_push", fill_value: float = np.nan, - title: Optional[str] = None, - cmap: Union[str, mcolors.Colormap] = "viridis", + scale: bool = True, + title: Optional[Union[str, List[str]]] = None, + suptitle: Optional[str] = None, + cmap: Optional[Union[str, mcolors.Colormap]] = None, + dot_scale_factor: float = 2.0, + na_color: str = "#e8ebe9", figsize: Optional[Tuple[float, float]] = None, dpi: Optional[int] = None, save: Optional[str] = None, ax: Optional[Axes] = None, - return_fig: bool = True, + return_fig: bool = False, + suptitle_fontsize: Optional[float] = None, **kwargs: Any, ) -> mpl.figure.Figure: """ @@ -186,11 +196,14 @@ def push( %(uns_key)s %(time_points_push_pull)s %(basis_push_pull)s - %(result_key_push_pull)s %(fill_value_push_pull)s + %(scale_push_pull)s %(title)s %(cmap)s + %(dot_scale_factor)s + %(na_color)s %(figsize_dpi_save)s + %(suptitle_fontsize)s Returns ------- @@ -206,20 +219,30 @@ def push( if key not in adata.obs: raise KeyError(f"No data found in `adata.obs[{key!r}]`.") data = adata.uns[AdataKeys.UNS][PlottingKeys.PUSH][key] + if data["data"] is not None and data["subset"] is not None and cmap is None: + cmap = _create_col_colors(adata, data["data"], data["subset"]) fig = _plot_temporal( adata=adata, temporal_key=data["temporal_key"], key_stored=key, + start=data["start"], + end=data["end"], + categories=data["subset"], + push=True, time_points=time_points, basis=basis, - result_key=result_key, constant_fill_value=fill_value, + scale=scale, save=save, cont_cmap=cmap, + dot_scale_factor=dot_scale_factor, + na_color=na_color, title=title, + suptitle=suptitle, figsize=figsize, dpi=dpi, ax=ax, + suptitle_fontsize=suptitle_fontsize, **kwargs, ) if return_fig: @@ -230,17 +253,21 @@ def push( def pull( inp: Union[AnnData, TemporalProblem, LineageProblem, CompoundProblem], uns_key: Optional[str] = None, - time_points: Optional[Iterable[K]] = None, + time_points: Optional[Sequence[float]] = None, basis: str = "umap", - result_key: str = "plot_pull", fill_value: float = np.nan, - title: Optional[str] = None, - cmap: Union[str, mcolors.Colormap] = "viridis", + scale: bool = True, + title: Optional[Union[str, List[str]]] = None, + suptitle: Optional[str] = None, + cmap: Optional[Union[str, mcolors.Colormap]] = None, + dot_scale_factor: float = 2.0, + na_color: str = "#e8ebe9", figsize: Optional[Tuple[float, float]] = None, dpi: Optional[int] = None, save: Optional[str] = None, ax: Optional[Axes] = None, - return_fig: bool = True, + return_fig: bool = False, + suptitle_fontsize: Optional[float] = None, **kwargs: Any, ) -> mpl.figure.Figure: """ @@ -254,11 +281,14 @@ def pull( %(uns_key)s %(time_points_push_pull)s %(basis_push_pull)s - %(result_key_push_pull)s %(fill_value_push_pull)s + %(scale_push_pull)s %(title)s %(cmap)s + %(dot_scale_factor)s + %(na_color)s %(figsize_dpi_save)s + %(suptitle_fontsize)s Returns ------- @@ -274,20 +304,30 @@ def pull( if key not in adata.obs: raise KeyError(f"No data found in `adata.obs[{key!r}]`.") data = adata.uns[AdataKeys.UNS][PlottingKeys.PULL][key] + if data["data"] is not None and data["subset"] is not None and cmap is None: + cmap = _create_col_colors(adata, data["data"], data["subset"]) fig = _plot_temporal( adata=adata, temporal_key=data["temporal_key"], key_stored=key, + start=data["start"], + end=data["end"], + categories=data["subset"], + push=False, time_points=time_points, basis=basis, - result_key=result_key, constant_fill_value=fill_value, + scale=scale, save=save, cont_cmap=cmap, + dot_scale_factor=dot_scale_factor, + na_color=na_color, title=title, + suptitle=suptitle, figsize=figsize, dpi=dpi, ax=ax, + suptitle_fontsize=suptitle_fontsize, **kwargs, ) if return_fig: diff --git a/src/moscot/plotting/_utils.py b/src/moscot/plotting/_utils.py index e90b31781..ed6eb917e 100644 --- a/src/moscot/plotting/_utils.py +++ b/src/moscot/plotting/_utils.py @@ -1,14 +1,16 @@ from copy import copy from types import MappingProxyType -from typing import Any, Set, Dict, List, Tuple, Union, Mapping, Iterable, Optional, TYPE_CHECKING +from typing import Any, Dict, List, Tuple, Union, Mapping, Optional, Sequence, TYPE_CHECKING from collections import defaultdict from matplotlib import colors as mcolors, pyplot as plt from matplotlib.axes import Axes +from pandas.api.types import is_categorical_dtype from matplotlib.colors import ListedColormap +from sklearn.preprocessing import MinMaxScaler from mpl_toolkits.axes_grid1 import make_axes_locatable import pandas as pd -import matplotlib as mp +import matplotlib as mpl import numpy as np @@ -17,8 +19,8 @@ import scanpy as sc from moscot.problems.base import CompoundProblem # type: ignore[attr-defined] +from moscot._constants._key import RandomKeys from moscot._constants._constants import AggregationMode -from moscot.problems.base._compound_problem import K def set_palette( @@ -51,8 +53,10 @@ def _sankey( fontsize: float = 12.0, horizontal_space: float = 1.5, force_update_colors: bool = False, - **_: Any, -) -> mp.figure.Figure: + alpha: float = 1.0, + interpolate_color: bool = False, + **kwargs: Any, +) -> mpl.figure.Figure: if ax is None: fig, ax = plt.subplots(constrained_layout=True, dpi=dpi, figsize=figsize) if captions is not None and len(captions) != len(transition_matrices): @@ -110,7 +114,8 @@ def _sankey( 2 * [leftWidths[leftLabel]["bottom"]], 2 * [leftWidths[leftLabel]["bottom"] + leftWidths[leftLabel]["left"]], color=colorDict[leftLabel], - alpha=0.99, + alpha=alpha, + **kwargs, ) ax.text( -0.05 * xMax, @@ -121,11 +126,12 @@ def _sankey( ) for rightLabel in rightLabels: ax.fill_between( - [xMax + left_pos[ind], 1.02 * xMax + left_pos[ind]], + [xMax + left_pos[ind], xMax + left_pos[ind]], 2 * [rightWidths[rightLabel]["bottom"]], 2 * [rightWidths[rightLabel]["bottom"] + rightWidths[rightLabel]["right"]], color=colorDict[rightLabel], - alpha=0.99, + alpha=alpha, + **kwargs, ) ax.text( 1.05 * xMax + left_pos[ind], @@ -143,7 +149,6 @@ def _sankey( # Plot strips for leftLabel in leftLabels: for rightLabel in rightLabels: - labelColor = leftLabel if dataFrame.loc[leftLabel, rightLabel] > 0: # Create array of y values for each strip, half at left value, # half at right, convolve @@ -161,22 +166,17 @@ def _sankey( leftWidths[leftLabel]["bottom"] += dataFrame.loc[leftLabel, rightLabel] rightWidths[rightLabel]["bottom"] += dataFrame.loc[leftLabel, rightLabel] - if ind == 0: - ax.fill_between( - np.linspace(0 + left_pos[ind], xMax + left_pos[ind], len(ys_d)), - ys_d, - ys_u, - alpha=0.65, - color=colorDict[labelColor], + arr = np.linspace(0 + left_pos[ind], xMax + left_pos[ind], len(ys_d)) + if interpolate_color: + color = _color_transition( + colorDict[leftLabel], colorDict[rightLabel], num=len(arr), alpha=alpha ) + for l in range(len(ys_d)): # necessary to get smooth lines + ax.fill_between( + arr[l:], ys_d[l:], ys_u[l:], color=color[l], ec=color[l], alpha=alpha, **kwargs + ) else: - ax.fill_between( - np.linspace(0 + left_pos[ind], xMax + left_pos[ind], len(ys_d)), - ys_d, - ys_u, - alpha=0.65, - color=colorDict[labelColor], - ) + ax.fill_between(arr, ys_d, ys_u, alpha=alpha, color=colorDict[leftLabel], **kwargs) ax.axis("off") ax.set_title(title) @@ -200,7 +200,7 @@ def _heatmap( cbar_kwargs: Mapping[str, Any] = MappingProxyType({}), ax: Optional[Axes] = None, **kwargs: Any, -) -> mp.figure.Figure: +) -> mpl.figure.Figure: cbar_kwargs = dict(cbar_kwargs) if ax is None: @@ -214,10 +214,10 @@ def _heatmap( row_adata, col_adata, transition_matrix, row_annotation, col_annotation ) - row_sm = mp.cm.ScalarMappable(cmap=row_cmap, norm=row_norm) - col_sm = mp.cm.ScalarMappable(cmap=col_cmap, norm=col_norm) + row_sm = mpl.cm.ScalarMappable(cmap=row_cmap, norm=row_norm) + col_sm = mpl.cm.ScalarMappable(cmap=col_cmap, norm=col_norm) - norm = mp.colors.Normalize( + norm = mpl.colors.Normalize( vmin=kwargs.pop("vmin", np.nanmin(transition_matrix)), vmax=kwargs.pop("vmax", np.nanmax(transition_matrix)) ) cont_cmap = copy(plt.get_cmap(cont_cmap)) @@ -274,9 +274,9 @@ def _get_black_or_white(value: float, cmap: mcolors.Colormap) -> str: def _annotate_heatmap( transition_matrix: pd.DataFrame, - im: mp.image.AxesImage, + im: mpl.image.AxesImage, valfmt: str = "{x:.2f}", - cmap: Union[mp.colors.Colormap, str] = "viridis", + cmap: Union[mpl.colors.Colormap, str] = "viridis", fontsize: float = 5, **kwargs: Any, ) -> None: @@ -288,7 +288,7 @@ def _annotate_heatmap( kw.update(**kwargs) if isinstance(valfmt, str): - valfmt = mp.ticker.StrMethodFormatter(valfmt) + valfmt = mpl.ticker.StrMethodFormatter(valfmt) if TYPE_CHECKING: assert callable(valfmt) @@ -359,45 +359,135 @@ def _plot_temporal( adata: AnnData, temporal_key: str, key_stored: str, - time_points: Optional[Iterable[K]] = None, + start: float, + end: float, + categories: Optional[Union[str, List[str]]] = None, + *, + push: bool, + time_points: Optional[Sequence[float]] = None, basis: str = "umap", - result_key: str = "plot_tmp", - constant_fill_value: float = 0.0, + constant_fill_value: float = np.nan, + scale: bool = True, cont_cmap: Union[str, mcolors.Colormap] = "viridis", - title: Optional[str] = None, + title: Optional[Union[str, List[str]]] = None, + suptitle: Optional[str] = None, figsize: Optional[Tuple[float, float]] = None, dpi: Optional[int] = None, + dot_scale_factor: float = 2.0, + na_color: str = "#e8ebe9", save: Optional[str] = None, ax: Optional[Axes] = None, show: bool = False, + suptitle_fontsize: Optional[float] = None, **kwargs: Any, -) -> mp.figure.Figure: - all_keys = adata.obs[temporal_key].unique() - if time_points is None: - constant_fill_keys: Set[K] = set() +) -> mpl.figure.Figure: + if time_points is not None: + time_points = sorted(time_points) + if isinstance(cont_cmap, str): + cont_cmap = mpl.colormaps["viridis"] + fig, axs = plt.subplots( + 1, 1 if time_points is None else len(time_points), figsize=figsize, dpi=dpi, constrained_layout=True + ) + axs = np.ravel(axs) # make into iterable + + if not push and time_points is not None: + time_points = time_points[::-1] + + if isinstance(title, list): + if TYPE_CHECKING: + assert isinstance(time_points, list) + if len(title) != len(time_points): + raise ValueError("If `title` is a list, its length must be equal to the length of `time_points`.") + titles = title else: - constant_fill_keys = set(all_keys) - set(time_points) - tmp = np.full(len(adata), np.nan) - for t in adata.obs[temporal_key].unique(): - mask = adata.obs[temporal_key] == t - if t in constant_fill_keys: - tmp[mask] = constant_fill_value + name = "descendants" if push else "ancestors" + if time_points is not None: + titles = [f"{categories} at time {start if push else end}"] + titles.extend([f"{name} at time {time_points[i]}" for i in range(1, len(time_points))]) else: - tmp[mask] = adata[adata.obs[temporal_key] == t].obs[key_stored] - - adata.obs[result_key] = tmp - - sc.set_figure_params(figsize=figsize, dpi=dpi) # TODO(@MUCDK, michalk8): necessary? want to make it uniform - fig = sc.pl.embedding( - adata=adata, - basis=basis, - color=result_key, - color_map=cont_cmap, - title=title, - ax=ax, - show=show, - **kwargs, - ) + titles = [f"{categories} at time {start if push else end} and {name}"] + for i, ax in enumerate(axs): + with RandomKeys(adata, n=1, where="obs") as keys: + if time_points is None: + if scale: + adata.obs[keys[0]] = ( + MinMaxScaler().fit_transform(adata.obs[key_stored].values.reshape(-1, 1)).squeeze() + ) + else: + adata.obs[keys[0]] = adata.obs[key_stored] + size = None + else: + tmp = np.full(len(adata), constant_fill_value) + mask = adata.obs[temporal_key] == time_points[i] + + tmp[mask] = adata[mask].obs[key_stored] + if scale: + tmp[mask] = ( + MinMaxScaler().fit_transform(adata[mask].obs[key_stored].values.reshape(-1, 1)).squeeze() + ) + else: + tmp = mask * adata.obs[key_stored] + + size = (mask * 120000 * dot_scale_factor + (1 - mask) * 120000) / adata.n_obs # 120,000 from scanpy + + _ = kwargs.pop("color_map", None) + _ = kwargs.pop("palette", None) + if (time_points[i] == start and push) or (time_points[i] == end and not push): + st = f"not in {time_points[i]}" + vmin, vmax = np.nanmin(tmp[mask]), np.nanmax(tmp[mask]) + column = pd.Series(tmp).fillna(st).astype("category") + if len(np.unique(column[mask.values].values)) != 2: + raise ValueError(f"Not exactly two categories, found `{column.cat.categories}`.") + kwargs["palette"] = {vmax: cont_cmap.reversed()(0), vmin: cont_cmap(0), st: na_color} + adata.obs[keys[0]] = column.values + else: + kwargs["color_map"] = cont_cmap + kwargs["na_color"] = na_color + adata.obs[keys[0]] = tmp + + sc.pl.embedding( + adata=adata, + basis=basis, + color=keys[0], + title=titles[i], + size=size, + ax=ax, + show=show, + **kwargs, + ) + if suptitle is not None: + fig.suptitle(suptitle, fontsize=suptitle_fontsize) if save: fig.figure.savefig(save, bbox_inches="tight") return fig + + +def _color_transition(c1: str, c2: str, num: int, alpha: float) -> List[str]: + if not mpl.colors.is_color_like(c1): + raise ValueError(f"{c1} cannot be interpreted as an RGB color.") + if not mpl.colors.is_color_like(c2): + raise ValueError(f"{c2} cannot be interpreted as an RGB color.") + c1_rgb = np.asarray(mpl.colors.to_rgb(c1)) + c2_rgb = np.asarray(mpl.colors.to_rgb(c2)) + return [mpl.colors.to_rgb((1 - n / num) * c1_rgb + n / num * c2_rgb) + (alpha,) for n in range(num)] + + +def _create_col_colors(adata: AnnData, obs_col: str, subset: Union[str, List[str]]) -> Optional[mcolors.Colormap]: + if isinstance(subset, list): + subset = subset[0] + if not is_categorical_dtype(adata.obs[obs_col]): + raise TypeError(f"`adata.obs[{obs_col!r}] must be of categorical type.") + + for i, cat in enumerate(adata.obs[obs_col].cat.categories): + if cat == subset: + color = adata.uns[f"{obs_col}_colors"][i] + break + else: + raise ValueError(f"Cannot find color for {subset} in `adata.obs[{obs_col!r}]`.") + + h, _, v = mcolors.rgb_to_hsv(mcolors.to_rgb(color)) + end_color = mcolors.hsv_to_rgb([h, 1, v]) + + col_cmap = mcolors.LinearSegmentedColormap.from_list("category_cmap", ["darkgrey", end_color]) + + return col_cmap diff --git a/src/moscot/problems/time/_mixins.py b/src/moscot/problems/time/_mixins.py index 6bb354983..075212109 100644 --- a/src/moscot/problems/time/_mixins.py +++ b/src/moscot/problems/time/_mixins.py @@ -340,7 +340,11 @@ def push( if key_added is not None: plot_vars = { + "start": start, + "end": end, "temporal_key": self.temporal_key, + "data": data if isinstance(data, str) else None, + "subset": subset, } self.adata.obs[key_added] = self._flatten(result, key=self.temporal_key) Key.uns.set_plotting_vars(self.adata, AdataKeys.UNS, PlottingKeys.PUSH, key_added, plot_vars) @@ -395,6 +399,10 @@ def pull( if key_added is not None: plot_vars = { "temporal_key": self.temporal_key, + "data": data if isinstance(data, str) else None, + "subset": subset, + "start": start, + "end": end, } self.adata.obs[key_added] = self._flatten(result, key=self.temporal_key) Key.uns.set_plotting_vars(self.adata, AdataKeys.UNS, PlottingKeys.PULL, key_added, plot_vars) diff --git a/tests/conftest.py b/tests/conftest.py index a0cd42515..8e19f3692 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,6 +25,11 @@ _gt_temporal_adata = sc.read("tests/data/moscot_temporal_tests.h5ad") +def pytest_sessionstart() -> None: + sc.pl.set_rcParams_defaults() + sc.set_figure_params(dpi=40, color_map="viridis") + + @pytest.fixture() def x() -> Geom_t: rng = np.random.RandomState(0) diff --git a/tests/plotting/_images/Plotting_pull.png b/tests/plotting/_images/Plotting_pull.png index 330e647c380ba7e6114822525945ed7f300ca85a..8a1b723ae010d4441ed824dcc99572d5eaa98b2a 100644 GIT binary patch literal 17018 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

QW85$avpEx=% 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 Jjf6?q{{a)c24nyL literal 576 zcmeAS@N?(olHy`uVBq!ia0vp^3qY8I4M=vMPuB%fmL;wcCBgY=CFO}lsSLh}B?US8 zB{`W%3T3H9#hLke#(HLY2098EB_##LR{Hw6a0Pn#Md|vsi-LK9hHw^mL>4nJu&IME zqi@KK;|vUpYdu{YLn`LHy=2IEz<}ZKhSEQl%MEHmoE{ubzirp?r<5VzSV5C{lF=wJ c2*P03lpFVdQ&MBb@0P8c2AOHXW diff --git a/tests/plotting/_images/Plotting_push.png b/tests/plotting/_images/Plotting_push.png index 330e647c380ba7e6114822525945ed7f300ca85a..53a307c4ce84761ee56589ca70d11395c7cd2f94 100644 GIT binary patch literal 16640 zcmX|JWl&p9+lJ!q?(XjH)?&dPXmO{wyOiSYE+tUBxVux_-L1I0e~0(SH^WJoA(LeH z?CyQtmk_S1EQf+fhzJ1zfubNUtp+^*`ncd>fyc-R3l`u>z(q#eMcv-q#ofrs3_{7s z#lgnj#m35*+|A6%*~;FIi-UPuxUdI^% z0+#OMf>hF29E5-nw^fjq(D2AQ≫wbxnQ~yPt2b|L=V5kY;UZW{FRp91;%~28TEq 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 VDdCm~{5Jv!1sP@O3Q5Dj{{tsDj|>0+ literal 576 zcmeAS@N?(olHy`uVBq!ia0vp^3qY8I4M=vMPuB%fmL;wcCBgY=CFO}lsSLh}B?US8 zB{`W%3T3H9#hLke#(HLY2098EB_##LR{Hw6a0Pn#Md|vsi-LK9hHw^mL>4nJu&IME zqi@KK;|vUpYdu{YLn`LHy=2IEz<}ZKhSEQl%MEHmoE{ubzirp?r<5VzSV5C{lF=wJ c2*P03lpFVdQ&MBb@0P8c2AOHXW diff --git a/tests/plotting/_images/Plotting_sankey.png b/tests/plotting/_images/Plotting_sankey.png index 193cf2696491e73612c0f0ea85eac6c998ec60ab..1a314097455e3a632b05f29537f30225dc64e09b 100644 GIT binary patch literal 17960 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 Ef}AVIjQ{`u literal 16160 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 AnnData: @pytest.fixture() def adata_pl_push(adata_time: AnnData) -> AnnData: rng = np.random.RandomState(0) - plot_vars = {"temporal_key": "time"} + plot_vars = {"temporal_key": "time", "data": "celltype", "subset": "A", "start": 0, "end": 1} + adata_time.uns["celltype_colors"] = ["#cc1b1b", "#2ccc1b", "#cc1bcc"] + adata_time.obs["celltype"] = adata_time.obs["celltype"].astype("category") Key.uns.set_plotting_vars(adata_time, AdataKeys.UNS, PlottingKeys.PUSH, PlottingDefaults.PUSH, plot_vars) - adata_time.obs[PlottingDefaults.PUSH] = np.abs(rng.randn(len(adata_time))) + push_initial_dist = np.zeros( + shape=(len(adata_time[adata_time.obs["time"] == 0]),) + ) # we need this for a cat. distr. in plots + push_initial_dist[0:10] = 0.1 + nan2 = np.empty(len(adata_time[adata_time.obs["time"] == 2])) + nan2[:] = np.nan + adata_time.obs[PlottingDefaults.PUSH] = np.hstack( + (push_initial_dist, np.abs(rng.randn(len(adata_time[adata_time.obs["time"] == 1]))), nan2) + ) return adata_time @pytest.fixture() def adata_pl_pull(adata_time: AnnData) -> AnnData: rng = np.random.RandomState(0) - plot_vars = {"temporal_key": "time"} + plot_vars = {"temporal_key": "time", "data": "celltype", "subset": "A", "start": 0, "end": 1} + adata_time.uns["celltype_colors"] = ["#cc1b1b", "#2ccc1b", "#cc1bcc"] + adata_time.obs["celltype"] = adata_time.obs["celltype"].astype("category") Key.uns.set_plotting_vars(adata_time, AdataKeys.UNS, PlottingKeys.PULL, PlottingDefaults.PULL, plot_vars) - adata_time.obs[PlottingDefaults.PULL] = np.abs(rng.randn(len(adata_time))) + pull_initial_dist = np.zeros( + shape=(len(adata_time[adata_time.obs["time"] == 1]),) + ) # we need this for a cat. distr. in plots + pull_initial_dist[0:10] = 0.1 + rand0 = np.abs(rng.randn(len(adata_time[adata_time.obs["time"] == 0]))) + nan2 = np.empty(len(adata_time[adata_time.obs["time"] == 2])) + nan2[:] = np.nan + adata_time.obs[PlottingDefaults.PULL] = np.hstack((rand0, pull_initial_dist, nan2)) return adata_time diff --git a/tests/plotting/test_plotting.py b/tests/plotting/test_plotting.py index 555a298ae..98abe24ed 100644 --- a/tests/plotting/test_plotting.py +++ b/tests/plotting/test_plotting.py @@ -1,12 +1,8 @@ from anndata import AnnData -import scanpy as sc from tests.plotting.conftest import PlotTester, PlotTesterMeta import moscot.plotting as mpl -sc.pl.set_rcParams_defaults() -sc.set_figure_params(dpi=40, color_map="viridis") - # WARNING: # 1. all classes must both subclass PlotTester and use metaclass=PlotTesterMeta # 2. tests which produce a plot must be prefixed with `test_plot_` @@ -26,10 +22,10 @@ def test_plot_sankey(self, adata_pl_sankey: AnnData): mpl.sankey(adata_pl_sankey) def test_plot_sankey_params(self, adata_pl_sankey: AnnData): - mpl.sankey(adata_pl_sankey, captions=["Test", "Other test"], titel="Title", figsize=(3, 3)) + mpl.sankey(adata_pl_sankey, captions=["Test", "Other test"], title="Title") def test_plot_push(self, adata_pl_push: AnnData): - mpl.push(adata_pl_push, time_points=[2]) + mpl.push(adata_pl_push, time_points=[0, 1]) def test_plot_pull(self, adata_pl_pull: AnnData): - mpl.pull(adata_pl_pull, time_points=[1]) + mpl.pull(adata_pl_pull, time_points=[0, 1]) diff --git a/tests/plotting/test_utils.py b/tests/plotting/test_utils.py index 206a82a6e..d7586e136 100644 --- a/tests/plotting/test_utils.py +++ b/tests/plotting/test_utils.py @@ -84,11 +84,14 @@ def test_pull( @pytest.mark.parametrize("save", [None, "tests/data/test_plot.png"]) @pytest.mark.parametrize("return_fig", [True, False]) - def test_sankey(self, adata_pl_sankey: AnnData, return_fig: bool, save: Optional[str]): + @pytest.mark.parametrize("interpolate_color", [True, False]) + def test_sankey(self, adata_pl_sankey: AnnData, return_fig: bool, save: Optional[str], interpolate_color: bool): if save: if os.path.exists(save): os.remove(save) - fig = msc.plotting.sankey(adata_pl_sankey, return_fig=return_fig, save=save) + fig = msc.plotting.sankey( + adata_pl_sankey, return_fig=return_fig, save=save, interpolate_color=interpolate_color + ) if return_fig: assert fig is not None assert isinstance(fig, mpl.figure.Figure)