From 3bbb5f3b44dacec7b61b76f4d715d9194f4e0b21 Mon Sep 17 00:00:00 2001 From: michalk8 <46717574+michalk8@users.noreply.github.com> Date: Tue, 26 Jan 2021 23:31:12 +0100 Subject: [PATCH] Expose cbar kwargs (#244) * Add cbar_kwargs to heatmap * Add tests --- squidpy/_docs.py | 2 ++ squidpy/pl/_graph.py | 4 +++ squidpy/pl/_utils.py | 30 ++++++++++++----------- tests/_images/Heatmap_cbar_kwargs.png | Bin 0 -> 1107 bytes tests/_images/Heatmap_cbar_vmin_vmax.png | Bin 0 -> 1031 bytes tests/tests_plotting/test_graph.py | 14 +++++++++++ 6 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 tests/_images/Heatmap_cbar_kwargs.png create mode 100644 tests/_images/Heatmap_cbar_vmin_vmax.png diff --git a/squidpy/_docs.py b/squidpy/_docs.py index 927e8845..7d5642e1 100644 --- a/squidpy/_docs.py +++ b/squidpy/_docs.py @@ -102,6 +102,8 @@ def decorator2(obj: Any) -> Any: The title of the plot. cmap Continuous colormap to use. +cbar_kwargs + Keyword arguments for :meth:`matplotlib.figure.Figure.colorbar`. {_cat_plotting}""" _plotting_returns = """\ Nothing, just plots the and optionally saves the plot. diff --git a/squidpy/pl/_graph.py b/squidpy/pl/_graph.py index 654855db..c42303f6 100644 --- a/squidpy/pl/_graph.py +++ b/squidpy/pl/_graph.py @@ -151,6 +151,7 @@ def interaction_matrix( title: Optional[str] = None, cmap: str = "viridis", palette: Palette_t = None, + cbar_kwargs: Mapping[str, Any] = MappingProxyType({}), figsize: Optional[Tuple[float, float]] = None, dpi: Optional[int] = None, save: Optional[Union[str, Path]] = None, @@ -189,6 +190,7 @@ def interaction_matrix( annotate=annotate, figsize=(2 * ad.n_obs // 3, 2 * ad.n_obs // 3) if figsize is None else figsize, dpi=dpi, + cbar_kwargs=cbar_kwargs, **kwargs, ) @@ -206,6 +208,7 @@ def nhood_enrichment( title: Optional[str] = None, cmap: str = "viridis", palette: Palette_t = None, + cbar_kwargs: Mapping[str, Any] = MappingProxyType({}), figsize: Optional[Tuple[float, float]] = None, dpi: Optional[int] = None, save: Optional[Union[str, Path]] = None, @@ -251,6 +254,7 @@ def nhood_enrichment( annotate=annotate, figsize=(2 * ad.n_obs // 3, 2 * ad.n_obs // 3) if figsize is None else figsize, dpi=dpi, + cbar_kwargs=cbar_kwargs, **kwargs, ) diff --git a/squidpy/pl/_utils.py b/squidpy/pl/_utils.py index 647e3b3d..4c91232b 100644 --- a/squidpy/pl/_utils.py +++ b/squidpy/pl/_utils.py @@ -1,4 +1,5 @@ from copy import copy +from types import MappingProxyType from typing import ( Any, Dict, @@ -482,10 +483,12 @@ def _heatmap( annotate: bool = True, figsize: Optional[Tuple[float, float]] = None, dpi: Optional[int] = None, + cbar_kwargs: Mapping[str, Any] = MappingProxyType({}), **kwargs: Any, ) -> mpl.figure.Figure: - _assert_categorical_obs(adata, key=key) + + cbar_kwargs = dict(cbar_kwargs) fig, ax = plt.subplots(constrained_layout=True, dpi=dpi, figsize=figsize) if method is not None: @@ -495,15 +498,14 @@ def _heatmap( row_order = row_order[::-1] row_labels = adata.obs[key][row_order] - data = adata[row_order, col_order].X + row_cmap, col_cmap, row_norm, col_norm, n_cls = _get_cmap_norm(adata, key, order=(row_order, col_order)) row_sm = mpl.cm.ScalarMappable(cmap=row_cmap, norm=row_norm) col_sm = mpl.cm.ScalarMappable(cmap=col_cmap, norm=col_norm) - minn, maxx = np.nanmin(data), np.nanmax(data) - norm = mpl.colors.Normalize(vmin=minn, vmax=maxx) + norm = mpl.colors.Normalize(vmin=kwargs.pop("vmin", np.nanmin(data)), vmax=kwargs.pop("vmax", np.nanmax(data))) cont_cmap = copy(plt.get_cmap(cont_cmap)) cont_cmap.set_bad(color="grey") @@ -526,26 +528,26 @@ def _heatmap( sch.dendrogram(col_link, no_labels=True, ax=col_ax, color_threshold=0, above_threshold_color="black") col_ax.axis("off") - _ = mpl.colorbar.ColorbarBase( - cax, - cmap=cont_cmap, - norm=norm, - ticks=np.linspace(np.nanmin(data), np.nanmax(data), 10), + _ = fig.colorbar( + im, + cax=cax, + ticks=np.linspace(norm.vmin, norm.vmax, 10), orientation="vertical", format="%0.2f", + **cbar_kwargs, ) + + # column labels colorbar c = fig.colorbar(col_sm, cax=col_cats, orientation="horizontal") c.set_ticks([]) + (col_cats if method is None else col_ax).set_title(title) + + # row labels colorbar c = fig.colorbar(row_sm, cax=row_cats, orientation="vertical", ticklocation="left") c.set_ticks(np.arange(n_cls) + 0.5) c.set_ticklabels(row_labels) c.set_label(key) - if method is not None: - col_ax.set_title(title) - else: - col_cats.set_title(title) - return fig diff --git a/tests/_images/Heatmap_cbar_kwargs.png b/tests/_images/Heatmap_cbar_kwargs.png new file mode 100644 index 0000000000000000000000000000000000000000..876d9585dfe2462a00b28edf5200c08a2b7ed9b8 GIT binary patch literal 1107 zcmeAS@N?(olHy`uVBq!ia0vp^6(G#P1|%(0%r1eb64!{5;QX|b^2DN42H(Vzf}H%4 zoXjMJvecsD%=|oKJs{Lk$S5f(D7Mnq&xI?{%P&gTKQVp#9H1eb1s;*b3=C}QAk63+ za^pAy1M>k-7srr_IdAVedWZzd9RGO#)RxH}%W|7?CQOh>)oJnEAik83_0dXi*~Q+^ z4^)?YzHwI1v4bUcPr2Zc8+&`3f+i>=%{aBm@#PbqwSMiXIp$Mc?q@$W-+%sSX~aF9 zn#$E@{>}7t4HP-J!D}hg@xlkc?b_Pf3~X(4e~A>i_?n5$oi*#wg9i$1Y-|QbMoEu> zf-7&y%CsrkoX>vpdZO@)*RPvj?98D5@{P^+J z?Jr8)#qW4uXJmM{Q#58r{plAc85MrNTKv&8dH3I+_4Y3%g3_d~oZMmUcKx=F{(I|d zmoFzj-=AS=D>7pa)8ycUA}$}l#*>-`maJ;a4?LOm?D=!)zfwn(-Xq}VqCjf}AWu%ira{)~05>J3c7m$$wEnhElD@YE+;nonk~nluNuqP+WOJ%T4L z&EL1JBH2IsazDS3{hBr043pollZrhb?;S30v)29{!+{q^bn?v1lk=*j&lhd)ofjeH zoqzEO!pR7)tb3icYSLVweZHZSF7ttc990!KL=1WNsW&h)c+cdtc>X!!SDee~SKcXi zn)mbnQ}L-!uhqS5{;g-GT<+S`DwXf2{r?|$eCr^JF_7q7mVJ?P!N$m>U1D9^8Nnydh)H^{};2i^PZHwe(V_At=qR> z_vz~CDT%T;KB<&rSP-Ihuy9VT|CGz;zt?{G_DyN_S*8_rlYmk|fg(3&r%!FWd_SRR aKclqMw>JsLHn;*aID@CFpUXO@geCymlm4av literal 0 HcmV?d00001 diff --git a/tests/_images/Heatmap_cbar_vmin_vmax.png b/tests/_images/Heatmap_cbar_vmin_vmax.png new file mode 100644 index 0000000000000000000000000000000000000000..ea46dc602c7cba888a3e44c08e3ee29b8fda78cd GIT binary patch literal 1031 zcmV+i1o-=jP)V>bE;BAOEFfrfbZ~PzFE4FjbZ~5MbZlv2E^l&Y zFUXg-oB#j-32;bRa{vGaCjbBjCjm`V*v9|>19VA5K~#90?b|;~98nYn@bf0aZcGzJ z7Q{$|REb0gb_+o}A(9VZoiC8aUQFee2&7mntYE9913e}cQ+E|MfEaz1ho3kwS$f_!9AwX( zZmWUvm(LhSrNC**U374caa8ct_5lF(dL3II-}IK~Qe_t9Cocd1_B#_J=D8bA!ixADv&lf!p3B>D=#qCl{G&c{OqN!!NCUMK4C7PN(bdbxn2Xo6! z*CcAWu1VZ-i+Wv^+og3>AI7McGQ7j{qUR+8q9vM~u1VySU~*pfU~c+UNlpnSr#+aQ z5=>4BCg)9EmDH4Aa=E%Hxp^g+n+io5GdX%8l6N-#ImA&Z+g z*XycWom$4&>=Zhe-|z^{qUZJ3Ua!9lGVcDyagcF`MG0o-wFgsEg4yX5O->0Wrv!5| zuLM(bN-#MUn4DKvB{wCQn*-EUNlm9{a$2If>6*k&1?J}T--YCqU~bxj*{Q(Xlwfv- zURUM6E>!npsBTSQI31hL|0?ii?GUfV#_+Y%!3RtRf3XaSmS}P+FgG2t*r~wW^r@1Z zmS}b=FgGQbork(AnJK~SOkI`Klwfwc2Xl+eRA6dKFgNYN?7Ws}YDzFW6_}gT5=~AC z=H{;2W*d_=#E+|Je6It|_eIZZWQ1&O9dt|X$;rvhhgzb!X%8l+YZ5zsi{_>!nw<(v zPD?a5Ez#_hU~+1kC1+j