_corr_dotplots
Correlation-scatter and rank-comparison plotting helpers from _plotting/_corr_dotplots.py.
This is the most test-backed plotting module in the package. Direct regression tests live in tests/test_corr_dotplots.py.
Main entry points
corr_dotplotcorr_dotplot_devspearman_cor_dotplotspearman_cor_dotplot_2plot_rank_scatterplot_rank_heatmapplot_rank_scatter_densitypairwise_spearman_corr_matrixcompare_ranked_listsplot_heatmap
corr_dotplot
corr_dotplot(...) is the primary public API.
Full signature
def corr_dotplot(
df: pd.DataFrame | None = None,
*,
adata: anndata.AnnData | None = None,
layer: str | None = None,
x_df: Any | None = None,
var_df: pd.DataFrame | None = None,
obs_df: pd.DataFrame | None = None,
column_key_x: str | None = None,
column_key_y: str | None = None,
hue: str | None = None,
subset_key: str | None = None,
figsize: tuple[float, float] = (20, 10),
xlabel: str | None = None,
ylabel: str | None = None,
axes_title: str | None = None,
axes_lines: bool = True,
show_y_intercept: bool = True,
palette: Sequence[Any] | str | None = palettes.godsnot_102,
subset_palette: Sequence[Any] | str | None = None,
dot_size: float = 200,
title_fontsize: int = 20,
stats_fontsize: int | None = None,
axes_title_y: float | None = None,
axis_label_fontsize: int = 20,
tick_label_fontsize: int | None = None,
legend_fontsize: int | None = None,
fit_legend_bbox_to_anchor: Sequence[float] | None = None,
hue_legend_bbox_to_anchor: Sequence[float] | None = None,
show_all_obs_fit: bool = False,
show_fit_legend: bool = True,
show_hue_legend: bool = True,
show_stats_text: bool = True,
nas2zeros: bool = False,
dropna: bool = False,
dropzeros: bool = False,
method: Literal["spearman", "pearson"] = "pearson",
show: bool = True,
):
import adata_science_tools as adtl
fig, ax, fit, corr_value, corr_pvalue = adtl.corr_dotplot(
adata=adata,
layer="log1p",
column_key_x="geneA",
column_key_y="geneB",
hue="Treatment",
subset_key="Batch",
method="spearman",
show=False,
)
Supported input modes
df=...with preassembled plotting columnsadata=...with optionallayerx_dfplusobs_df, with optionalvar_dfwhen feature columns need names
When df is provided, the AnnData-derived path is ignored.
Required arguments
column_key_xcolumn_key_y
These must resolve to numeric columns after the final plotting table is assembled.
Return value
corr_dotplot(...) returns:
figaxesfitcorr_valuecorr_pvalue
The returned fit, corr_value, and corr_pvalue always describe the overall filtered observations, even when subset_key is used to draw subgroup fits.
Important behavior
methodmust be"pearson"or"spearman".nas2zeros,dropna, anddropzeroscontrol x/y cleanup before statistics.palettecolorshue-driven scatter points, whilesubset_palettecolorssubset_key-driven subgroup fit lines.subset_keydraws one fit line per subgroup when fitting succeeds.show_all_obs_fit=Trueadds the overall fit line in subset mode.show_fit_legendandshow_hue_legendcan be toggled independently.fit_legend_bbox_to_anchorandhue_legend_bbox_to_anchoraccept either 2-item or 4-item sequences.show=Falsecloses the figure before returning so notebook backends do not auto-render it.There is no built-in
savefigargument; callers save the returned figure themselves.
Tested behaviors
The current regression tests lock in several details:
Observation columns that collide with feature names are renamed to
<name>_obsbefore concatenation.Public styling kwargs such as
dot_size,title_fontsize,stats_fontsize,axes_title_y,axis_label_fontsize,tick_label_fontsize, andlegend_fontsizeaffect the final figure.show_stats_text=Falsesuppresses the footer text without suppressing the returned statistics.Non-categorical
subset_keycolumns are supported.Subsets that cannot produce a fit are reported as
fit unavailablein the footer and omitted from the fit legend.The fit legend title changes with method, for example
batch fit\nPearson_corrversusbatch fit\nSpearman_corr.
corr_dotplot_dev
corr_dotplot_dev(...) is the experimental variant that adds optional top and right marginal histograms while mostly keeping the same filtered-data correlation and fit behavior as corr_dotplot(...).
Full signature
def corr_dotplot_dev(
df: pd.DataFrame | None = None,
*,
adata: anndata.AnnData | None = None,
layer: str | None = None,
x_df: Any | None = None,
var_df: pd.DataFrame | None = None,
obs_df: pd.DataFrame | None = None,
column_key_x: str | None = None,
column_key_y: str | None = None,
hue: str | None = None,
subset_key: str | None = None,
figsize: tuple[float, float] = (20, 10),
xlabel: str | None = None,
ylabel: str | None = None,
axes_title: str | None = None,
axes_lines: bool = True,
show_y_intercept: bool = True,
palette: Sequence[Any] | str | None = palettes.godsnot_102,
subset_palette: Sequence[Any] | str | None = None,
dot_size: float = 200,
title_fontsize: int = 20,
stats_fontsize: int | None = None,
axes_title_y: float | None = None,
axis_label_fontsize: int = 20,
tick_label_fontsize: int | None = None,
legend_fontsize: int | None = None,
fit_legend_bbox_to_anchor: Sequence[float] | None = None,
hue_legend_bbox_to_anchor: Sequence[float] | None = None,
show_all_obs_fit: bool = False,
show_fit_legend: bool = True,
show_hue_legend: bool = True,
show_stats_text: bool = True,
nas2zeros: bool = False,
dropna: bool = False,
dropzeros: bool = False,
method: Literal["spearman", "pearson"] = "pearson",
show_x_marginal_hist: bool = False,
show_y_marginal_hist: bool = False,
x_marginal_hist_bins: int | Sequence[float] = 20,
y_marginal_hist_bins: int | Sequence[float] = 20,
x_marginal_hist_fill: bool = True,
x_marginal_hist_KDE: bool = True,
y_marginal_hist_fill: bool = True,
y_marginal_hist_KDE: bool = True,
show_all_obs_x_hist: bool = False,
show_all_obs_y_hist: bool = False,
x_marginal_hist_height_ratio: float = 0.18,
y_marginal_hist_width_ratio: float = 0.18,
show: bool = True,
):
fig, axes, fit, corr_value, corr_pvalue = adtl.corr_dotplot_dev(
df=df,
column_key_x="Age",
column_key_y="CRP",
hue="Outcome",
subset_key="Batch",
show_x_marginal_hist=True,
show_y_marginal_hist=True,
show=False,
)
main_ax = axes["main"]
top_hist_ax = axes["x_marginal"]
right_hist_ax = axes["y_marginal"]
Important behavior:
It accepts the full
corr_dotplot(...)keyword API, includingpaletteforhuelayers andsubset_paletteforsubset_keylayers, plusshow_x_marginal_hist,show_y_marginal_hist,x_marginal_hist_bins,y_marginal_hist_bins,x_marginal_hist_fill,x_marginal_hist_KDE,y_marginal_hist_fill,y_marginal_hist_KDE,show_all_obs_x_hist,show_all_obs_y_hist,x_marginal_hist_height_ratio, andy_marginal_hist_width_ratio.It returns
(fig, axes_dict, fit, corr_value, corr_pvalue)instead of a single scatter axes.axes_dictalways contains"main","x_marginal", and"y_marginal"keys, with disabled marginal panels set toNone.Marginals use the same filtered
working_dfas the scatter, correlation, and fit layers.When
subset_keyis provided, marginal histograms followsubset_keyrather thanhue, so their subgroup colors followsubset_palette.When
subset_keyis provided but no valid subgroup values remain after filtering,corr_dotplot_dev(...)falls back to the overall fit, footer stats, and all-observation marginals even ifshow_all_obs_fit,show_all_obs_x_hist, orshow_all_obs_y_histwereFalse.corr_dotplot(...)keeps its current behavior in that edge case and does not apply this dev-only fallback.Marginals default to
fill=TrueandKDE=Trueand can be turned off independently for the x and y panels.When
show_x_marginal_hist=True,axes_titleis attached toaxes["x_marginal"]so the title sits above the full composite plot; otherwise it remains onaxes["main"].corr_dotplot_dev(method="spearman", ...)is the supported Spearman path for the dev API; there is no separatespearman_cor_dotplot_dev(...)wrapper in this change.
Repo example with simulated data
The repository now includes a config-driven example that uses corr_dotplot_dev(...) end to end:
example_simulated_data/scripts/simulate_1_var_covar_age.pycreates a baselineAnnDataobject withobscolumnsAgeandcase_controland one feature,simulated_feature.example_simulated_data/scripts/plot_dotplot_simulate_1_var_covar_age.pyloads that.h5adfile and callscorr_dotplot_dev(...)withcolumn_key_x="Age",column_key_y="simulated_feature",hue="case_control", andsubset_key="case_control".The default example uses the explicit palette
['#AA4499', '#332288', '#1f77b4', '#661100', '#117733', '#ff7f0e']from the YAML config rather thanadtl.palettes.
The generated example figure is available at baseline.png.
spearman_cor_dotplot
spearman_cor_dotplot(...) is a backward-compatible wrapper around corr_dotplot(...).
Full signature
def spearman_cor_dotplot(*args, **kwargs):
fig, ax, fit, corr_value, corr_pvalue = adtl.spearman_cor_dotplot(
df,
"x",
"y",
"group",
show=False,
)
Important behavior:
It forces
method="spearman"even if a different method is passed.It still supports the older positional calling style
df, column_key_x, column_key_y, hue, ....
Secondary helpers
spearman_cor_dotplot_2
Creates a two-panel scatter plot of the same x/y pair with two different hue columns. It returns (figure, axes).
Full signature
def spearman_cor_dotplot_2(df, column_key_x, column_key_y, hue, hue_right, figsize=(20, 10)):
Rank-comparison helpers
plot_rank_scatter,plot_rank_heatmap, andplot_rank_scatter_densitycompare two ranked lists using the ranks of shared elements.They return
(correlation, p_value).If the lists share no common elements, they return
(None, None).
pairwise_spearman_corr_matrix
Builds a pairwise Spearman correlation matrix across a dictionary of ranked lists.
compare_ranked_lists
Computes the Spearman correlation between two ranked lists without plotting and returns (correlation, p_value), or (None, None) when there is no overlap.
plot_heatmap
Heatmap helper for numeric matrices or DataFrame input. This function is documented from code rather than regression tests; use it as a convenience helper rather than a heavily stabilized API.
Example with plain DataFrame
fig, ax, fit, corr_value, corr_pvalue = adtl.corr_dotplot(
df=df,
column_key_x="Age",
column_key_y="CRP",
hue="Outcome",
show=False,
)
fig.savefig("results/age_crp_corr.png", dpi=300, bbox_inches="tight")