From 2a908e02f7d8b8df2a456c9638e6452088eb158e Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Mon, 18 May 2026 08:41:12 +0200 Subject: [PATCH 01/13] work in progress --- .../_differential_gene_expression/_base.py | 5 +++++ pertpy/tools/_enrichment.py | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/pertpy/tools/_differential_gene_expression/_base.py b/pertpy/tools/_differential_gene_expression/_base.py index a2f4c2ce..c7585d18 100644 --- a/pertpy/tools/_differential_gene_expression/_base.py +++ b/pertpy/tools/_differential_gene_expression/_base.py @@ -675,6 +675,8 @@ def plot_fold_change( # pragma: no cover # noqa: D417 *, var_names: Sequence[str] = None, n_top_vars: int = 15, + padj_threshold: float = 0.01, + padj_threshold_col: str = "adj_p_value", log2fc_col: str = "log_fc", symbol_col: str = "variable", y_label: str = "Log2 fold change", @@ -688,6 +690,8 @@ def plot_fold_change( # pragma: no cover # noqa: D417 results_df: DataFrame with results from DE analysis. var_names: Variables to plot. If None, the top n_top_vars variables based on the log2 fold change are plotted. n_top_vars: Number of top variables to plot. The top and bottom n_top_vars variables are plotted, respectively. + padj_threshold: Only variables with adjusted p-values below this threshold are included in the plot. + padj_threshold_col: Column name of adjusted p-values, log2fc_col: Column name of log2 Fold-Change values. symbol_col: Column name of gene IDs. y_label: Label for the y-axis. @@ -729,6 +733,7 @@ def plot_fold_change( # pragma: no cover # noqa: D417 assert len(var_names) == 2 * n_top_vars df = results_df[results_df[symbol_col].isin(var_names)] + df = df[df[padj_threshold_col] < padj_threshold] df.sort_values(log2fc_col, ascending=False, inplace=True) plt.figure(figsize=figsize) diff --git a/pertpy/tools/_enrichment.py b/pertpy/tools/_enrichment.py index 1064d0fb..dcd5c465 100644 --- a/pertpy/tools/_enrichment.py +++ b/pertpy/tools/_enrichment.py @@ -153,9 +153,10 @@ def hypergeometric( targets: dict[str, list[str] | dict[str, list[str]]] | None = None, nested: bool = False, categories: str | list[str] | None = None, - pvals_adj_thresh: float = 0.05, + padj_threshold: float = 0.05, direction: str = "both", corr_method: Literal["benjamini-hochberg", "bonferroni"] = "benjamini-hochberg", + **kwargs, ): """Perform a hypergeometric test to assess the overrepresentation of gene group members. @@ -170,7 +171,7 @@ def hypergeometric( nested: Whether `targets` is a dictionary of dictionaries with group categories as keys. categories: If `targets=None` or `nested=True`, this argument can be used to subset the gene groups to one or more categories (keys of the original dictionary). In case of the ChEMBL drug targets, these are ATC level 1/level 2 category codes. - pvals_adj_thresh: The `pvals_adj` cutoff to use on the `sc.tl.rank_genes_groups()` output to identify markers. + padj_threshold: The `pvals_adj` cutoff to use on the `sc.tl.rank_genes_groups()` output to identify markers. direction: Whether to seek out up/down-regulated genes for the groups, based on the values from `scores`. Can be `up`, `down`, or `both` (for no selection). corr_method: Which FDR correction to apply to the p-values of the hypergeometric test. @@ -180,6 +181,17 @@ def hypergeometric( Dictionary with clusters for which the original object markers were computed as the keys, and data frames of test results sorted on q-value as the items. """ + if "pvals_adj_thresh" in kwargs: + import warnings + + warnings.warn( + "`pvals_adj_thresh` is deprecated and will be removed in a future release; use `padj_threshold`", + DeprecationWarning, + ) + padj_threshold = kwargs.pop("pvals_adj_thresh") + if kwargs: + raise TypeError(f"hypergeometric() got unexpected keyword arguments {list(kwargs.keys())}") + universe = set(adata.var_names) targets = _prepare_targets(targets=targets, nested=nested, categories=categories) # type: ignore for group in targets: @@ -201,7 +213,7 @@ def hypergeometric( "pvals_adj", ], ) - mask = adata.uns["rank_genes_groups"]["pvals_adj"][cluster] < pvals_adj_thresh + mask = adata.uns["rank_genes_groups"]["pvals_adj"][cluster] < padj_threshold if direction == "up": mask = mask & (adata.uns["rank_genes_groups"]["scores"][cluster] > 0) elif direction == "down": From 7612986bc36874a20f9d85a0d7683526b01c70b4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 06:44:34 +0000 Subject: [PATCH 02/13] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pertpy/tools/_enrichment.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pertpy/tools/_enrichment.py b/pertpy/tools/_enrichment.py index dcd5c465..a9daec26 100644 --- a/pertpy/tools/_enrichment.py +++ b/pertpy/tools/_enrichment.py @@ -187,6 +187,7 @@ def hypergeometric( warnings.warn( "`pvals_adj_thresh` is deprecated and will be removed in a future release; use `padj_threshold`", DeprecationWarning, + stacklevel=2, ) padj_threshold = kwargs.pop("pvals_adj_thresh") if kwargs: From 031302b01dd56887086c2dba810720e6dc8ef2c8 Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Mon, 18 May 2026 16:45:40 +0200 Subject: [PATCH 03/13] test deprecated_arg() --- pertpy/tools/_enrichment.py | 14 ++++++++------ pyproject.toml | 3 ++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/pertpy/tools/_enrichment.py b/pertpy/tools/_enrichment.py index dcd5c465..8a885b09 100644 --- a/pertpy/tools/_enrichment.py +++ b/pertpy/tools/_enrichment.py @@ -13,6 +13,7 @@ from scanpy.tools._score_genes import _sparse_nanmean from scipy.sparse import issparse from scipy.stats import hypergeom +from scverse_misc import Deprecation, deprecated_arg from statsmodels.stats.multitest import multipletests from pertpy._doc import _doc_params, doc_common_plot_args @@ -147,6 +148,12 @@ def score( adata.uns[f"{key_added}_genes"]["var"].loc[drug, "genes"] = "|".join(adata.var_names[targets[drug]]) adata.uns[f"{key_added}_all_genes"]["var"].loc[drug, "all_genes"] = "|".join(full_targets[drug]) + @deprecated_arg( + "pvals_adj_thresh", + Deprecation( + "1.0.6", "`pvals_adj_thresh` is deprecated and will be removed in a future release. Use `padj_threshold`." + ), + ) def hypergeometric( self, adata: AnnData, @@ -176,18 +183,13 @@ def hypergeometric( Can be `up`, `down`, or `both` (for no selection). corr_method: Which FDR correction to apply to the p-values of the hypergeometric test. Can be `benjamini-hochberg` or `bonferroni`. + kwargs: Used only for the deprecated `pvals_adj_thresh` argument. Returns: Dictionary with clusters for which the original object markers were computed as the keys, and data frames of test results sorted on q-value as the items. """ if "pvals_adj_thresh" in kwargs: - import warnings - - warnings.warn( - "`pvals_adj_thresh` is deprecated and will be removed in a future release; use `padj_threshold`", - DeprecationWarning, - ) padj_threshold = kwargs.pop("pvals_adj_thresh") if kwargs: raise TypeError(f"hypergeometric() got unexpected keyword arguments {list(kwargs.keys())}") diff --git a/pyproject.toml b/pyproject.toml index 9e6f04d7..dd35cf7f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,7 +66,8 @@ dependencies = [ "scikit-learn>=1.4", "fast-array-utils[accel,sparse]", "arviz>=1.0.0", - "filelock" + "filelock", + "scverse-misc" ] [project.optional-dependencies] From 65521178dbff750be13c6546e3e63472bc236261 Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Tue, 19 May 2026 07:48:58 +0200 Subject: [PATCH 04/13] final deprecation warning after testing --- pertpy/tools/_enrichment.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/pertpy/tools/_enrichment.py b/pertpy/tools/_enrichment.py index 8a885b09..81d956cd 100644 --- a/pertpy/tools/_enrichment.py +++ b/pertpy/tools/_enrichment.py @@ -150,9 +150,7 @@ def score( @deprecated_arg( "pvals_adj_thresh", - Deprecation( - "1.0.6", "`pvals_adj_thresh` is deprecated and will be removed in a future release. Use `padj_threshold`." - ), + Deprecation("1.0.6", "Use `padj_threshold`."), ) def hypergeometric( self, @@ -161,9 +159,9 @@ def hypergeometric( nested: bool = False, categories: str | list[str] | None = None, padj_threshold: float = 0.05, + pvals_adj_thresh: float | None = None, direction: str = "both", corr_method: Literal["benjamini-hochberg", "bonferroni"] = "benjamini-hochberg", - **kwargs, ): """Perform a hypergeometric test to assess the overrepresentation of gene group members. @@ -183,16 +181,14 @@ def hypergeometric( Can be `up`, `down`, or `both` (for no selection). corr_method: Which FDR correction to apply to the p-values of the hypergeometric test. Can be `benjamini-hochberg` or `bonferroni`. - kwargs: Used only for the deprecated `pvals_adj_thresh` argument. + pvals_adj_thresh: Deprecated and will be removed in a future release. Use `padj_threshold`. Returns: Dictionary with clusters for which the original object markers were computed as the keys, and data frames of test results sorted on q-value as the items. """ - if "pvals_adj_thresh" in kwargs: - padj_threshold = kwargs.pop("pvals_adj_thresh") - if kwargs: - raise TypeError(f"hypergeometric() got unexpected keyword arguments {list(kwargs.keys())}") + if pvals_adj_thresh is not None: + padj_threshold = pvals_adj_thresh universe = set(adata.var_names) targets = _prepare_targets(targets=targets, nested=nested, categories=categories) # type: ignore From 1a17df1fed6d2cc1f362720cad66a5bc7d9c9ea8 Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Wed, 27 May 2026 18:39:26 +0200 Subject: [PATCH 05/13] add deprecated_arg() to plot_volcano() --- .../_differential_gene_expression/_base.py | 98 ++++++++++++------- 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/pertpy/tools/_differential_gene_expression/_base.py b/pertpy/tools/_differential_gene_expression/_base.py index c7585d18..aad61d6a 100644 --- a/pertpy/tools/_differential_gene_expression/_base.py +++ b/pertpy/tools/_differential_gene_expression/_base.py @@ -14,6 +14,7 @@ import seaborn as sns from matplotlib.pyplot import Figure from matplotlib.ticker import MaxNLocator +from scverse_misc import Deprecation, deprecated_arg from pertpy._doc import _doc_params, doc_common_plot_args from pertpy._logger import logger @@ -98,15 +99,27 @@ def compare_groups( ... @_doc_params(common_plot_args=doc_common_plot_args) + @deprecated_arg( + "pval_thresh", + Deprecation("1.1.0", "Use `padj_threshold`."), + ) + @deprecated_arg( + "pvalue_col", + Deprecation("1.1.0", "Use `padj_col`."), + ) + @deprecated_arg( + "log2fc_thresh", + Deprecation("1.1.0", "Use `log2fc_threshold`."), + ) def plot_volcano( # pragma: no cover # noqa: D417 self, data: pd.DataFrame | ad.AnnData, *, + log2fc_threshold: float = 0.75, + padj_threshold: float = 0.01, log2fc_col: str = "log_fc", - pvalue_col: str = "adj_p_value", + padj_col: str = "adj_p_value", symbol_col: str = "variable", - pval_thresh: float = 0.05, - log2fc_thresh: float = 0.75, to_label: int | list[str] = 5, s_curve: bool | None = False, colors: list[str] = None, @@ -124,20 +137,23 @@ def plot_volcano( # pragma: no cover # noqa: D417 x_label: str | None = None, y_label: str | None = None, return_fig: bool = False, + log2fc_thresh: float | None = None, + pval_thresh: float | None = None, + pvalue_col: str | None = None, **kwargs: int, ) -> Figure | None: """Creates a volcano plot from a pandas DataFrame or Anndata. Args: data: DataFrame or Anndata to plot. + log2fc_threshold: Threshold for log2 fold change significance. + padj_threshold: Adjusted p-values for significance. log2fc_col: Column name of log2 Fold-Change values. - pvalue_col: Column name of the p values. + padj_col: Column name of adjusted p-values. symbol_col: Column name of gene IDs. varm_key: Key in Anndata.varm slot to use for plotting if an Anndata object was passed. size_col: Column name to size points by. point_sizes: Lower and upper bounds of point sizes. - pval_thresh: Threshold p value for significance. - log2fc_thresh: Threshold for log2 fold change significance. to_label: Number of top genes or list of genes to label. s_curve: Whether to use a reciprocal threshold for up and down gene determination. color_dict: Dictionary for coloring dots by categories. @@ -151,6 +167,9 @@ def plot_volcano( # pragma: no cover # noqa: D417 shape_order: Order of categories for shapes. x_label: Label for the x-axis. y_label: Label for the y-axis. + log2fc_thresh: Deprecated and will be removed in a future release. Use `log2fc_threshold`. + pval_thresh: Deprecated and will be removed in a future release. Use `padj_threshold`. + pvalue_col: Deprecated and will be removed in a future release. Use `padj_col`. {common_plot_args} **kwargs: Additional arguments for seaborn.scatterplot. @@ -177,11 +196,18 @@ def plot_volcano( # pragma: no cover # noqa: D417 >>> res_df = edgr.test_contrasts( ... edgr.contrast(column="Treatment", baseline="Chemo", group_to_compare="Anti-PD-L1+Chemo") ... ) - >>> edgr.plot_volcano(res_df, log2fc_thresh=0) + >>> edgr.plot_volcano(res_df, log2fc_threshold=0) Preview: .. image:: /_static/docstring_previews/de_volcano.png """ + if pvalue_col is not None: + padj_col = pvalue_col + if pval_thresh is not None: + padj_threshold = pval_thresh + if log2fc_thresh is not None: + log2fc_threshold = log2fc_thresh + if colors is None: colors = ["gray", "#D62728", "#1F77B4"] @@ -190,7 +216,7 @@ def _pval_reciprocal(lfc: float) -> float: Used for plotting the S-curve """ - return pval_thresh / (lfc - log2fc_thresh) + return padj_threshold / (lfc - log2fc_threshold) def _map_shape(symbol: str) -> str: if shape_dict is not None: @@ -204,8 +230,8 @@ def _map_genes_categories( row: pd.Series, log2fc_col: str, nlog10_col: str, - log2fc_thresh: float, - pval_thresh: float = None, + log2fc_threshold: float, + padj_threshold: float = None, s_curve: bool = False, ) -> str: """Map genes to categorize based on log2fc and pvalue. @@ -219,16 +245,16 @@ def _map_genes_categories( if s_curve: # S-curve condition for Up or Down categorization reciprocal_thresh = _pval_reciprocal(abs(log2fc)) - if log2fc > log2fc_thresh and nlog10 > reciprocal_thresh: + if log2fc > log2fc_threshold and nlog10 > reciprocal_thresh: return "Up" - elif log2fc < -log2fc_thresh and nlog10 > reciprocal_thresh: + elif log2fc < -log2fc_threshold and nlog10 > reciprocal_thresh: return "Down" else: return "not DE" # Standard condition for Up or Down categorization - elif log2fc > log2fc_thresh and nlog10 > pval_thresh: + elif log2fc > log2fc_threshold and nlog10 > padj_threshold: return "Up" - elif log2fc < -log2fc_thresh and nlog10 > pval_thresh: + elif log2fc < -log2fc_threshold and nlog10 > padj_threshold: return "Down" else: return "not DE" @@ -237,8 +263,8 @@ def _map_genes_categories_highlight( row: pd.Series, log2fc_col: str, nlog10_col: str, - log2fc_thresh: float, - pval_thresh: float = None, + log2fc_threshold: float, + padj_threshold: float = None, s_curve: bool = False, symbol_col: str = None, ) -> str: @@ -258,12 +284,12 @@ def _map_genes_categories_highlight( if s_curve: # Use S-curve condition for filtering DE - if nlog10 > _pval_reciprocal(abs(log2fc)) and abs(log2fc) > log2fc_thresh: + if nlog10 > _pval_reciprocal(abs(log2fc)) and abs(log2fc) > log2fc_threshold: return "DE" return "not DE" else: # Use standard condition for filtering DE - if abs(log2fc) < log2fc_thresh or nlog10 < pval_thresh: + if abs(log2fc) < log2fc_threshold or nlog10 < padj_threshold: return "not DE" return "DE" @@ -277,18 +303,18 @@ def _map_genes_categories_highlight( df = data.copy(deep=True) # clean and replace 0s as they would lead to -inf - if df[[log2fc_col, pvalue_col]].isnull().values.any(): + if df[[log2fc_col, padj_col]].isnull().values.any(): print("NaNs encountered, dropping rows with NaNs") - df = df.dropna(subset=[log2fc_col, pvalue_col]) + df = df.dropna(subset=[log2fc_col, padj_col]) - if df[pvalue_col].min() == 0: + if df[padj_col].min() == 0: print("0s encountered for p value, replacing with 1e-323") - df.loc[df[pvalue_col] == 0, pvalue_col] = 1e-323 + df.loc[df[padj_col] == 0, padj_col] = 1e-323 # convert p value threshold to nlog10 - pval_thresh = -np.log10(pval_thresh) + padj_threshold = -np.log10(padj_threshold) # make nlog10 column - df["nlog10"] = -np.log10(df[pvalue_col]) + df["nlog10"] = -np.log10(df[padj_col]) y_max = df["nlog10"].max() + 1 # make a column to pick top genes df["top_genes"] = df["nlog10"] * df[log2fc_col] @@ -323,8 +349,8 @@ def _map_genes_categories_highlight( row, log2fc_col=log2fc_col, nlog10_col="nlog10", - log2fc_thresh=log2fc_thresh, - pval_thresh=pval_thresh, + log2fc_threshold=log2fc_threshold, + padj_threshold=padj_threshold, s_curve=s_curve, ), axis=1, @@ -339,8 +365,8 @@ def _map_genes_categories_highlight( row, log2fc_col=log2fc_col, nlog10_col="nlog10", - log2fc_thresh=log2fc_thresh, - pval_thresh=pval_thresh, + log2fc_threshold=log2fc_threshold, + padj_threshold=padj_threshold, symbol_col=symbol_col, s_curve=s_curve, ), @@ -427,15 +453,15 @@ def _map_genes_categories_highlight( # plot vertical and horizontal lines if s_curve: - x = np.arange((log2fc_thresh + 0.000001), y_max, 0.01) + x = np.arange((log2fc_threshold + 0.000001), y_max, 0.01) y = _pval_reciprocal(x) ax.plot(x, y, zorder=1, c="k", lw=2, ls="--") ax.plot(-x, y, zorder=1, c="k", lw=2, ls="--") else: - ax.axhline(pval_thresh, zorder=1, c="k", lw=2, ls="--") - ax.axvline(log2fc_thresh, zorder=1, c="k", lw=2, ls="--") - ax.axvline(log2fc_thresh * -1, zorder=1, c="k", lw=2, ls="--") + ax.axhline(padj_threshold, zorder=1, c="k", lw=2, ls="--") + ax.axvline(log2fc_threshold, zorder=1, c="k", lw=2, ls="--") + ax.axvline(log2fc_threshold * -1, zorder=1, c="k", lw=2, ls="--") plt.ylim(0, y_max) ax.xaxis.set_major_locator(MaxNLocator(integer=True)) @@ -470,7 +496,7 @@ def _map_genes_categories_highlight( if x_label is None: x_label = log2fc_col if y_label is None: - y_label = f"-$log_{{10}}$ {pvalue_col}" + y_label = f"-$log_{{10}}$ {padj_col}" plt.xlabel(x_label, size=15) plt.ylabel(y_label, size=15) @@ -676,7 +702,7 @@ def plot_fold_change( # pragma: no cover # noqa: D417 var_names: Sequence[str] = None, n_top_vars: int = 15, padj_threshold: float = 0.01, - padj_threshold_col: str = "adj_p_value", + padj_col: str = "adj_p_value", log2fc_col: str = "log_fc", symbol_col: str = "variable", y_label: str = "Log2 fold change", @@ -691,7 +717,7 @@ def plot_fold_change( # pragma: no cover # noqa: D417 var_names: Variables to plot. If None, the top n_top_vars variables based on the log2 fold change are plotted. n_top_vars: Number of top variables to plot. The top and bottom n_top_vars variables are plotted, respectively. padj_threshold: Only variables with adjusted p-values below this threshold are included in the plot. - padj_threshold_col: Column name of adjusted p-values, + padj_col: Column name of adjusted p-values. log2fc_col: Column name of log2 Fold-Change values. symbol_col: Column name of gene IDs. y_label: Label for the y-axis. @@ -733,7 +759,7 @@ def plot_fold_change( # pragma: no cover # noqa: D417 assert len(var_names) == 2 * n_top_vars df = results_df[results_df[symbol_col].isin(var_names)] - df = df[df[padj_threshold_col] < padj_threshold] + df = df[df[padj_col] < padj_threshold] df.sort_values(log2fc_col, ascending=False, inplace=True) plt.figure(figsize=figsize) From 795c7f7d8bc94327b4578dab314fa7767c762098 Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Wed, 27 May 2026 19:36:59 +0200 Subject: [PATCH 06/13] replace alpha with padj_threshold --- pertpy/tools/_milo.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/pertpy/tools/_milo.py b/pertpy/tools/_milo.py index cb8a3ab3..e657e57b 100644 --- a/pertpy/tools/_milo.py +++ b/pertpy/tools/_milo.py @@ -844,11 +844,15 @@ def _graph_spatial_fdr( sample_adata.var["SpatialFDR"] = sample_adata.var["SpatialFDR"].fillna(1) @_doc_params(common_plot_args=doc_common_plot_args) + @deprecated_arg( + "alpha", + Deprecation("1.1.0", "Use `padj_threshold`."), + ) def plot_nhood_graph( # pragma: no cover # noqa: D417 self, mdata: MuData, *, - alpha: float = 0.1, + padj_threshold: float = 0.1, min_logFC: float = 0, min_size: int = 10, plot_edges: bool = False, @@ -857,17 +861,19 @@ def plot_nhood_graph( # pragma: no cover # noqa: D417 palette: str | Sequence[str] | None = None, ax: Axes | None = None, return_fig: bool = False, + alpha: float | None = None, **kwargs, ) -> Figure | None: """Visualize DA results on abstracted graph (wrapper around sc.pl.embedding). Args: mdata: MuData object - alpha: Significance threshold. (default: 0.1) + padj_threshold: Significance threshold. (default: 0.1) min_logFC: Minimum absolute log-Fold Change to show results. If is 0, show all significant neighbourhoods. min_size: Minimum size of nodes in visualization. (default: 10) plot_edges: If edges for neighbourhood overlaps whould be plotted. title: Plot title. + alpha: Deprecated and will be removed in a future release. Use `padj_threshold`. {common_plot_args} **kwargs: Additional arguments to `scanpy.pl.embedding`. @@ -890,6 +896,9 @@ def plot_nhood_graph( # pragma: no cover # noqa: D417 Preview: .. image:: /_static/docstring_previews/milo_nhood_graph.png """ + if alpha is not None: + padj_threshold = alpha + nhood_adata = mdata["milo"].T.copy() if "Nhood_size" not in nhood_adata.obs.columns: @@ -899,7 +908,7 @@ def plot_nhood_graph( # pragma: no cover # noqa: D417 ) nhood_adata.obs["graph_color"] = nhood_adata.obs["logFC"] - nhood_adata.obs.loc[nhood_adata.obs["SpatialFDR"] > alpha, "graph_color"] = np.nan + nhood_adata.obs.loc[nhood_adata.obs["SpatialFDR"] > padj_threshold, "graph_color"] = np.nan nhood_adata.obs["abs_logFC"] = abs(nhood_adata.obs["logFC"]) nhood_adata.obs.loc[nhood_adata.obs["abs_logFC"] < min_logFC, "graph_color"] = np.nan @@ -998,16 +1007,21 @@ def plot_nhood( # pragma: no cover # noqa: D417 return None @_doc_params(common_plot_args=doc_common_plot_args) + @deprecated_arg( + "alpha", + Deprecation("1.1.0", "Use `padj_threshold`."), + ) def plot_da_beeswarm( # pragma: no cover # noqa: D417 self, mdata: MuData, *, feature_key: str | None = "rna", anno_col: str = "nhood_annotation", - alpha: float = 0.1, + padj_threshold: float = 0.1, subset_nhoods: list[str] = None, palette: str | Sequence[str] | dict[str, str] | None = None, return_fig: bool = False, + alpha: float | None = None, ) -> Figure | None: """Plot beeswarm plot of logFC against nhood labels. @@ -1015,10 +1029,11 @@ def plot_da_beeswarm( # pragma: no cover # noqa: D417 mdata: MuData object feature_key: Key in mdata to the cell-level AnnData object. anno_col: Column in adata.uns['nhood_adata'].obs to use as annotation. (default: 'nhood_annotation'.) - alpha: Significance threshold. (default: 0.1) + padj_threshold: Significance threshold. (default: 0.1) subset_nhoods: List of nhoods to plot. If None, plot all nhoods. palette: Name of Seaborn color palette for violinplots. Defaults to pre-defined category colors for violinplots. + alpha: Deprecated and will be removed in a future release. Use `padj_threshold`. {common_plot_args} Returns: @@ -1040,6 +1055,9 @@ def plot_da_beeswarm( # pragma: no cover # noqa: D417 Preview: .. image:: /_static/docstring_previews/milo_da_beeswarm.png """ + if alpha is not None: + padj_threshold = alpha + try: nhood_adata = mdata["milo"].T.copy() except KeyError: @@ -1069,7 +1087,7 @@ def plot_da_beeswarm( # pragma: no cover # noqa: D417 ) anno_df = nhood_adata.obs[[anno_col, "logFC", "SpatialFDR"]].copy() - anno_df["is_signif"] = anno_df["SpatialFDR"] < alpha + anno_df["is_signif"] = anno_df["SpatialFDR"] < padj_threshold anno_df = anno_df[anno_df[anno_col] != "nan"] try: @@ -1115,7 +1133,9 @@ def plot_da_beeswarm( # pragma: no cover # noqa: D417 orient="h", alpha=0.5, ) - plt.legend(loc="upper left", title=f"< {int(alpha * 100)}% SpatialFDR", bbox_to_anchor=(1, 1), frameon=False) + plt.legend( + loc="upper left", title=f"< {int(padj_threshold * 100)}% SpatialFDR", bbox_to_anchor=(1, 1), frameon=False + ) plt.axvline(x=0, ymin=0, ymax=1, color="black", linestyle="--") if return_fig: From 631ea7f6ee8034e07cf61cf8e89693663716aaac Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Fri, 29 May 2026 06:29:04 +0200 Subject: [PATCH 07/13] small fixes during testing --- .../tools/_differential_gene_expression/_base.py | 14 ++++---------- .../_differential_gene_expression/_pydeseq2.py | 3 +++ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/pertpy/tools/_differential_gene_expression/_base.py b/pertpy/tools/_differential_gene_expression/_base.py index 4c229869..e19cb211 100644 --- a/pertpy/tools/_differential_gene_expression/_base.py +++ b/pertpy/tools/_differential_gene_expression/_base.py @@ -95,14 +95,8 @@ def compare_groups( "pval_thresh", Deprecation("1.1.0", "Use `padj_threshold`."), ) - @deprecated_arg( - "pvalue_col", - Deprecation("1.1.0", "Use `padj_col`."), - ) - @deprecated_arg( - "log2fc_thresh", - Deprecation("1.1.0", "Use `log2fc_threshold`."), - ) + @deprecated_arg("pvalue_col", Deprecation("1.1.0", "Use `padj_col`."), stacklevel=2) + @deprecated_arg("log2fc_thresh", Deprecation("1.1.0", "Use `log2fc_threshold`."), stacklevel=3) def plot_volcano( # pragma: no cover # noqa: D417 self, data: pd.DataFrame | ad.AnnData, @@ -721,13 +715,13 @@ def plot_fold_change( # pragma: no cover # noqa: D417 Preview: .. image:: /_static/docstring_previews/de_fold_change.png """ + results_df = results_df[results_df[padj_col] < padj_threshold] if var_names is None: var_names = results_df.sort_values(log2fc_col, ascending=False).head(n_top_vars)[symbol_col].tolist() var_names += results_df.sort_values(log2fc_col, ascending=True).head(n_top_vars)[symbol_col].tolist() assert len(var_names) == 2 * n_top_vars - df = results_df[results_df[symbol_col].isin(var_names)] - df = df[df[padj_col] < padj_threshold] + df = results_df[results_df[symbol_col].isin(var_names)].copy() df.sort_values(log2fc_col, ascending=False, inplace=True) plt.figure(figsize=figsize) diff --git a/pertpy/tools/_differential_gene_expression/_pydeseq2.py b/pertpy/tools/_differential_gene_expression/_pydeseq2.py index fd6bed4f..600ca627 100644 --- a/pertpy/tools/_differential_gene_expression/_pydeseq2.py +++ b/pertpy/tools/_differential_gene_expression/_pydeseq2.py @@ -1,4 +1,5 @@ import os +import warnings import numpy as np import pandas as pd @@ -12,6 +13,8 @@ from ._base import LinearModelBase from ._checks import check_is_integer_matrix +warnings.filterwarnings("always", message=".*(pval_thresh|pvalue_col|log2fc_thresh).*") + class PyDESeq2(LinearModelBase): """Differential expression test using a PyDESeq2.""" From 6571d3832d1193a97491ddfb789cde2db63d8bd9 Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Fri, 29 May 2026 06:40:40 +0200 Subject: [PATCH 08/13] keep old default value --- pertpy/tools/_differential_gene_expression/_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pertpy/tools/_differential_gene_expression/_base.py b/pertpy/tools/_differential_gene_expression/_base.py index e19cb211..509bacdf 100644 --- a/pertpy/tools/_differential_gene_expression/_base.py +++ b/pertpy/tools/_differential_gene_expression/_base.py @@ -102,7 +102,7 @@ def plot_volcano( # pragma: no cover # noqa: D417 data: pd.DataFrame | ad.AnnData, *, log2fc_threshold: float = 0.75, - padj_threshold: float = 0.01, + padj_threshold: float = 0.05, log2fc_col: str = "log_fc", padj_col: str = "adj_p_value", symbol_col: str = "variable", From c934878f06fb6bce7f108bb4de94913b90a69685 Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Fri, 29 May 2026 09:27:15 +0200 Subject: [PATCH 09/13] add warning filter for milo deprecation --- pertpy/tools/_milo.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pertpy/tools/_milo.py b/pertpy/tools/_milo.py index 4842e033..da5164f4 100644 --- a/pertpy/tools/_milo.py +++ b/pertpy/tools/_milo.py @@ -466,9 +466,13 @@ def da_nhoods( if find_spec("pydeseq2") is None: raise ImportError("pydeseq2 is required but not installed. Install with: pip install pydeseq2") + import warnings + from pydeseq2.dds import DeseqDataSet from pydeseq2.ds import DeseqStats + warnings.filterwarnings("always", message=".*(alpha).*") + counts_filtered = count_mat[np.ix_(keep_nhoods, keep_smp)] design_df_filtered = design_df.iloc[keep_smp].copy() From 7e6edb23e793ad14b79a9e75911f3d2bcd1397e8 Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Sun, 31 May 2026 09:29:47 +0200 Subject: [PATCH 10/13] add plot_disp_ests --- .../_pydeseq2.py | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/pertpy/tools/_differential_gene_expression/_pydeseq2.py b/pertpy/tools/_differential_gene_expression/_pydeseq2.py index 600ca627..56669581 100644 --- a/pertpy/tools/_differential_gene_expression/_pydeseq2.py +++ b/pertpy/tools/_differential_gene_expression/_pydeseq2.py @@ -1,6 +1,7 @@ import os import warnings +import matplotlib.pyplot as plt import numpy as np import pandas as pd from anndata import AnnData @@ -10,6 +11,8 @@ from pydeseq2.ds import DeseqStats from scipy.sparse import issparse +from pertpy._doc import _doc_params, doc_common_plot_args + from ._base import LinearModelBase from ._checks import check_is_integer_matrix @@ -66,6 +69,172 @@ def fit(self, **kwargs) -> pd.DataFrame: dds.deseq2() self.dds = dds + @_doc_params(common_plot_args=doc_common_plot_args) + def plot_disp_ests( + self, + *, + ymin: float | None = None, + cv: bool = False, + gene_col: str = "black", + fit_col: str = "red", + final_col: str = "dodgerblue", + legend: bool = True, + xlabel: str | None = None, + ylabel: str | None = None, + log: str = "xy", + s: float = 0.45, + return_fig: bool = False, + **kwargs, + ) -> None: + """Plot dispersion estimates. + + A helper function that visualizes per-gene dispersion estimates together + with the fitted mean–dispersion relationship. + + This plot shows: + - gene-wise dispersion estimates + - fitted dispersion trend + - final dispersion estimates used for testing + + Optionally, the square root of dispersion (coefficient of variation) can + be shown instead of raw dispersion values. + + Args: + ymin: Lower bound for plotted values. Points below this threshold + are clipped and drawn at ymin using triangle markers. + cv: If True, plot the square root of dispersion (coefficient of + variation) instead of dispersion. + gene_col: Color for gene-wise dispersion estimates. + fit_col: Color for fitted dispersion trend. + final_col: Color for final dispersion estimates used for testing. + legend: Whether to draw a legend. + xlabel: Label for the x-axis (defaults to "mean of normalized counts"). + ylabel: Label for the y-axis (defaults to dispersion or CV). + log: Axis scaling. "x", "y", or "xy" for log scaling. + s: Scaling factor for point sizes. + return_fig: If True, returns the matplotlib figure instead of None. + {common_plot_args} + **kwargs: Additional arguments for TODO + + Returns: + matplotlib.figure.Figure | None + + Examples: + >>> model.plot_disp_ests() + + Preview: + .. image:: /_static/docstring_previews/dispersion_estimates.png + """ + if not hasattr(self, "dds"): + raise ValueError("Model not fitted yet. Call .fit() first.") + + dds = self.dds + + genecol = gene_col + fitcol = fit_col + finalcol = final_col + + if xlabel is None: + xlabel = "mean of normalized counts" + if ylabel is None: + ylabel = "coefficient of variation" if cv else "dispersion" + + px = np.asarray(dds.var["_normed_means"]) + sel = px > 0 + px = px[sel] + + py = np.asarray(dds.var["genewise_dispersions"])[sel] + if cv: + py = np.sqrt(py) + + if ymin is None: + positive = py[(py > 0) & np.isfinite(py)] + ymin = 1e-08 if positive.size == 0 else 10 ** np.floor(np.log10(np.min(positive)) - 0.1) + + py_plot = np.maximum(py, ymin) + + fig, ax = plt.subplots(dpi=300) + + below = py < ymin + above = ~below + + if above.any(): + ax.scatter( + px[above], + py_plot[above], + facecolor=genecol, + edgecolors="none", + s=s * 20, + marker="o", + **kwargs, + ) + + if below.any(): + ax.scatter( + px[below], + py_plot[below], + c=genecol, + s=s * 20, + marker="v", + **kwargs, + ) + + outliers = np.asarray( + dds.var.get( + "_outlier_genes", + pd.Series(False, index=dds.var_names), + ) + )[sel] + + final_disp = np.asarray(dds.var["dispersions"])[sel] + final_y = np.sqrt(final_disp) if cv else final_disp + + ax.scatter( + px, + final_y, + s=s * (20 + 20 * outliers.astype(int)), + facecolor=np.where(outliers, "none", finalcol), + edgecolors=np.where(outliers, finalcol, "none"), + ) + + fitted_disp = np.asarray(dds.var["fitted_dispersions"])[sel] + fitted_y = np.sqrt(fitted_disp) if cv else fitted_disp + + ax.scatter( + px, + fitted_y, + facecolor=fitcol, + edgecolors="none", + marker="o", + s=s * 20, + ) + + if "x" in log: + ax.set_xscale("log") + if "y" in log: + ax.set_yscale("log") + + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) + + if legend: + from matplotlib.lines import Line2D + + handles = [ + Line2D([0], [0], marker="o", linestyle="", color=genecol, label="gene-est"), + Line2D([0], [0], marker="o", linestyle="", color=fitcol, label="fitted"), + Line2D([0], [0], marker="o", linestyle="", color=finalcol, label="final"), + ] + ax.legend(handles=handles, loc="lower right", frameon=True) + + plt.tight_layout() + + if return_fig: + return plt.gcf() + + plt.show() + return None + def _test_single_contrast(self, contrast, alpha=0.05, *, lfc_shrink=None, **kwargs) -> pd.DataFrame: """Conduct a specific test and returns a Pandas DataFrame. From 52ae3e98d86825e06bf5180103fb5d11fd3f5949 Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Mon, 1 Jun 2026 12:31:17 +0200 Subject: [PATCH 11/13] final plot --- .../docstring_previews/de_disp_ests.png | Bin 0 -> 122547 bytes .../_pydeseq2.py | 68 ++++++++---------- 2 files changed, 30 insertions(+), 38 deletions(-) create mode 100644 docs/_static/docstring_previews/de_disp_ests.png diff --git a/docs/_static/docstring_previews/de_disp_ests.png b/docs/_static/docstring_previews/de_disp_ests.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd26aa6456e5cb10a8adbd70a8c0f8e006c7a7e GIT binary patch literal 122547 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 z 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

!RkcI*1Bu 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 z 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 pd.DataFrame: self.dds = dds @_doc_params(common_plot_args=doc_common_plot_args) - def plot_disp_ests( + def plot_disp_ests( # pragma: no cover # noqa: D417 self, *, ymin: float | None = None, @@ -86,54 +87,46 @@ def plot_disp_ests( return_fig: bool = False, **kwargs, ) -> None: - """Plot dispersion estimates. - - A helper function that visualizes per-gene dispersion estimates together - with the fitted mean–dispersion relationship. - - This plot shows: - - gene-wise dispersion estimates - - fitted dispersion trend - - final dispersion estimates used for testing - - Optionally, the square root of dispersion (coefficient of variation) can - be shown instead of raw dispersion values. + """Plots per-gene dispersion estimates together with the fitted mean–dispersion relationship. Args: ymin: Lower bound for plotted values. Points below this threshold - are clipped and drawn at ymin using triangle markers. + are drawn at ymin using triangle markers. cv: If True, plot the square root of dispersion (coefficient of variation) instead of dispersion. gene_col: Color for gene-wise dispersion estimates. fit_col: Color for fitted dispersion trend. final_col: Color for final dispersion estimates used for testing. legend: Whether to draw a legend. - xlabel: Label for the x-axis (defaults to "mean of normalized counts"). - ylabel: Label for the y-axis (defaults to dispersion or CV). + xlabel: Label for the x-axis (default: "mean of normalized counts"). + ylabel: Label for the y-axis (default: "dispersion" or "coefficient of variation"). log: Axis scaling. "x", "y", or "xy" for log scaling. s: Scaling factor for point sizes. - return_fig: If True, returns the matplotlib figure instead of None. {common_plot_args} - **kwargs: Additional arguments for TODO + **kwargs: Additional arguments for ax.scatter. Returns: - matplotlib.figure.Figure | None + If `return_fig` is `True`, returns the figure, otherwise `None`. Examples: - >>> model.plot_disp_ests() - + >>> import pertpy as pt + >>> import decoupler as dc + >>> adata = pt.dt.zhang_2021() + >>> adata = adata[adata.obs["Origin"] == "t", :].copy() + >>> adata.layers["counts"] = adata.X.copy() + >>> pdata = dc.pp.pseudobulk(adata, sample_col="Patient", groups_col="Cluster", layer="counts", mode="sum") + >>> dc.pp.filter_samples(pdata, inplace=True) + >>> pds2 = pt.tl.PyDESeq2(pdata, design="~Efficacy+Treatment") + >>> pds2.fit() + >>> pds2.plot_disp_ests(s=0.1) Preview: - .. image:: /_static/docstring_previews/dispersion_estimates.png + .. image:: /_static/docstring_previews/de_disp_ests.png """ if not hasattr(self, "dds"): raise ValueError("Model not fitted yet. Call .fit() first.") dds = self.dds - genecol = gene_col - fitcol = fit_col - finalcol = final_col - if xlabel is None: xlabel = "mean of normalized counts" if ylabel is None: @@ -149,7 +142,7 @@ def plot_disp_ests( if ymin is None: positive = py[(py > 0) & np.isfinite(py)] - ymin = 1e-08 if positive.size == 0 else 10 ** np.floor(np.log10(np.min(positive)) - 0.1) + ymin = 10 ** np.floor(np.log10(np.min(positive)) - 0.1) py_plot = np.maximum(py, ymin) @@ -162,7 +155,7 @@ def plot_disp_ests( ax.scatter( px[above], py_plot[above], - facecolor=genecol, + facecolor=gene_col, edgecolors="none", s=s * 20, marker="o", @@ -173,7 +166,8 @@ def plot_disp_ests( ax.scatter( px[below], py_plot[below], - c=genecol, + facecolor=gene_col, + edgecolors="none", s=s * 20, marker="v", **kwargs, @@ -193,8 +187,8 @@ def plot_disp_ests( px, final_y, s=s * (20 + 20 * outliers.astype(int)), - facecolor=np.where(outliers, "none", finalcol), - edgecolors=np.where(outliers, finalcol, "none"), + facecolor=np.where(outliers, "none", final_col), + edgecolors=np.where(outliers, final_col, "none"), ) fitted_disp = np.asarray(dds.var["fitted_dispersions"])[sel] @@ -203,7 +197,7 @@ def plot_disp_ests( ax.scatter( px, fitted_y, - facecolor=fitcol, + facecolor=fit_col, edgecolors="none", marker="o", s=s * 20, @@ -218,16 +212,14 @@ def plot_disp_ests( ax.set_ylabel(ylabel) if legend: - from matplotlib.lines import Line2D - handles = [ - Line2D([0], [0], marker="o", linestyle="", color=genecol, label="gene-est"), - Line2D([0], [0], marker="o", linestyle="", color=fitcol, label="fitted"), - Line2D([0], [0], marker="o", linestyle="", color=finalcol, label="final"), + Line2D([0], [0], marker="o", linestyle="", color=gene_col, label="gene-est"), + Line2D([0], [0], marker="o", linestyle="", color=fit_col, label="fitted"), + Line2D([0], [0], marker="o", linestyle="", color=final_col, label="final"), ] ax.legend(handles=handles, loc="lower right", frameon=True) - plt.tight_layout() + plt.tight_layout(pad=2.0) if return_fig: return plt.gcf() From 16752b01756d6b064199b368b81addf4f031492b Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Mon, 1 Jun 2026 12:35:47 +0200 Subject: [PATCH 12/13] fix return type --- pertpy/tools/_differential_gene_expression/_pydeseq2.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pertpy/tools/_differential_gene_expression/_pydeseq2.py b/pertpy/tools/_differential_gene_expression/_pydeseq2.py index c448f04c..c2917b76 100644 --- a/pertpy/tools/_differential_gene_expression/_pydeseq2.py +++ b/pertpy/tools/_differential_gene_expression/_pydeseq2.py @@ -6,6 +6,7 @@ import pandas as pd from anndata import AnnData from matplotlib.lines import Line2D +from matplotlib.pyplot import Figure from numpy import ndarray from pydeseq2.dds import DeseqDataSet from pydeseq2.default_inference import DefaultInference @@ -86,7 +87,7 @@ def plot_disp_ests( # pragma: no cover # noqa: D417 s: float = 0.45, return_fig: bool = False, **kwargs, - ) -> None: + ) -> Figure | None: """Plots per-gene dispersion estimates together with the fitted mean–dispersion relationship. Args: From 89c1af5b56ec38d74f0d8e1071f576de6a3b14f5 Mon Sep 17 00:00:00 2001 From: LuisHeinzlmeier Date: Tue, 2 Jun 2026 07:06:11 +0200 Subject: [PATCH 13/13] incorporate the review --- .../_pydeseq2.py | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/pertpy/tools/_differential_gene_expression/_pydeseq2.py b/pertpy/tools/_differential_gene_expression/_pydeseq2.py index c2917b76..5e5d3c40 100644 --- a/pertpy/tools/_differential_gene_expression/_pydeseq2.py +++ b/pertpy/tools/_differential_gene_expression/_pydeseq2.py @@ -84,17 +84,15 @@ def plot_disp_ests( # pragma: no cover # noqa: D417 xlabel: str | None = None, ylabel: str | None = None, log: str = "xy", - s: float = 0.45, + point_size: float = 0.45, return_fig: bool = False, **kwargs, ) -> Figure | None: """Plots per-gene dispersion estimates together with the fitted mean–dispersion relationship. Args: - ymin: Lower bound for plotted values. Points below this threshold - are drawn at ymin using triangle markers. - cv: If True, plot the square root of dispersion (coefficient of - variation) instead of dispersion. + ymin: Lower bound for plotted values. Points below this threshold are drawn at ymin using triangle markers. + cv: If True, plot the square root of dispersion (coefficient of variation) instead of dispersion. gene_col: Color for gene-wise dispersion estimates. fit_col: Color for fitted dispersion trend. final_col: Color for final dispersion estimates used for testing. @@ -102,7 +100,7 @@ def plot_disp_ests( # pragma: no cover # noqa: D417 xlabel: Label for the x-axis (default: "mean of normalized counts"). ylabel: Label for the y-axis (default: "dispersion" or "coefficient of variation"). log: Axis scaling. "x", "y", or "xy" for log scaling. - s: Scaling factor for point sizes. + point_size: Scaling factor for point sizes. {common_plot_args} **kwargs: Additional arguments for ax.scatter. @@ -119,7 +117,8 @@ def plot_disp_ests( # pragma: no cover # noqa: D417 >>> dc.pp.filter_samples(pdata, inplace=True) >>> pds2 = pt.tl.PyDESeq2(pdata, design="~Efficacy+Treatment") >>> pds2.fit() - >>> pds2.plot_disp_ests(s=0.1) + >>> pds2.plot_disp_ests(point_size=0.1) + Preview: .. image:: /_static/docstring_previews/de_disp_ests.png """ @@ -158,7 +157,7 @@ def plot_disp_ests( # pragma: no cover # noqa: D417 py_plot[above], facecolor=gene_col, edgecolors="none", - s=s * 20, + s=point_size * 20, marker="o", **kwargs, ) @@ -169,7 +168,7 @@ def plot_disp_ests( # pragma: no cover # noqa: D417 py_plot[below], facecolor=gene_col, edgecolors="none", - s=s * 20, + s=point_size * 20, marker="v", **kwargs, ) @@ -187,7 +186,7 @@ def plot_disp_ests( # pragma: no cover # noqa: D417 ax.scatter( px, final_y, - s=s * (20 + 20 * outliers.astype(int)), + s=point_size * (20 + 20 * outliers.astype(int)), facecolor=np.where(outliers, "none", final_col), edgecolors=np.where(outliers, final_col, "none"), ) @@ -201,7 +200,7 @@ def plot_disp_ests( # pragma: no cover # noqa: D417 facecolor=fit_col, edgecolors="none", marker="o", - s=s * 20, + s=point_size * 20, ) if "x" in log:

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