Plots¶
Six of these functions accept return_data=True and then return (Figure, DataFrame) instead of a bare figure. Schemas are registered in _RETURN_DATA_SCHEMAS and pinned by a regression test, so they are part of the public contract.
missing_mechanism() always returns (Figure, DataFrame), so it needs no flag. missing_abundance_density() returns a figure, and missing_matrix_html() returns an HTML string; neither has a tabular result to hand back.
| Function | return_data columns |
|---|---|
missing_matrix |
feature, sample, missing |
completeness_bars |
group, completeness, n_samples |
detection_waterfall |
feature, detection_rate, rank |
missing_runorder |
sample, run_order, missing_rate, group |
comissing_heatmap |
feature_a, feature_b, comissingness |
missing_upset |
feature, intersection_id, members, n_features, rank, plotted |
The nullity matrix¶
missing_matrix ¶
missing_matrix(
df: DataFrame,
*,
title: str = "",
subtitle: str = "",
feature_type: str = "PROT",
annotation_levels: list[int] | None = None,
annotation_colors: dict[int | str, dict[str, str]]
| None = None,
label_level: int = -1,
sort_features: str | None = "descending",
cluster_samples: bool = True,
cluster_method: str = "average",
show_dendrogram: bool = True,
color_present: str | tuple = "#2d2d2d",
color_missing: str | tuple = "#f0f0f0",
invert: bool = False,
figsize: tuple[float, float] | None = None,
fontsize: int = 10,
fontsize_legend: int | None = None,
fontsize_rows: int | None = None,
fontsize_cols: int | None = None,
fontsize_annotations: int | None = None,
completeness: str = "below",
completeness_threshold: float | None = None,
legend_loc: str = "upper right",
group_summary: int | str | None = None,
split_by: int | str | None = None,
save: str | None = None,
dpi: int = 150,
return_data: bool = False,
) -> plt.Figure
Pretty missing-data matrix with multi-level sample annotations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
Features (rows) x Samples (columns). Use MultiIndex columns for annotation strips; level names become strip labels automatically. NaN = missing / not detected. |
required |
title
|
str
|
Figure title (empty string = no title). |
''
|
subtitle
|
str
|
Secondary line below title for dataset metadata. |
''
|
feature_type
|
str
|
Type of features: "PROT", "GENE", or "PEPTIDE". Used for labels. |
'PROT'
|
annotation_levels
|
list[int] | None
|
Column-index levels to show as colour bars. Default: all levels except the innermost (used for tick labels). |
None
|
annotation_colors
|
dict | None
|
Custom colours for annotation levels. Keys are level indices (int) or level names (str). Values are dicts mapping factor levels to hex colours. |
None
|
label_level
|
int
|
Column level for x-axis tick labels (-1 = innermost). |
-1
|
sort_features
|
'ascending' | 'descending' | None
|
Sort features by completeness. Default "descending". |
'descending'
|
cluster_samples
|
bool
|
Cluster samples by nullity pattern (default True). |
True
|
cluster_method
|
str
|
scipy linkage method (default "average"). |
'average'
|
show_dendrogram
|
bool
|
Draw dendrogram above annotations (default True). |
True
|
color_present
|
colour spec
|
Colours for detected vs missing cells. |
'#2d2d2d'
|
color_missing
|
colour spec
|
Colours for detected vs missing cells. |
'#2d2d2d'
|
invert
|
bool
|
Swap present and missing colours. When |
False
|
figsize
|
tuple | None
|
Figure size; auto-calculated if None. |
None
|
fontsize
|
int
|
Base font size used as fallback (default 10). |
10
|
fontsize_legend
|
int | None
|
Font size for legend entries. |
None
|
fontsize_rows
|
int | None
|
Font size for row (feature) labels. |
None
|
fontsize_cols
|
int | None
|
Font size for column (sample) labels. |
None
|
fontsize_annotations
|
int | None
|
Font size for annotation strip labels. |
None
|
completeness
|
'below' | 'side'
|
Where to place the completeness sparkline. |
'below'
|
completeness_threshold
|
float | None
|
Draw a threshold line on the sparkline at this value (0-1). E.g. 0.5 draws a line at 50% completeness. |
None
|
legend_loc
|
str
|
Corner for the annotation legends: "upper right", "upper left", "lower right", "lower left" (default "upper right"). |
'upper right'
|
group_summary
|
int | str | None
|
Column level (int index or str name) to group by for a per-group completeness summary printed to the console. Only works when there is more than one factor level. Default None (disabled). |
None
|
split_by
|
int | str | None
|
Split the matrix into side-by-side panels by this column level (int index or str name). Each factor value gets its own panel. |
None
|
save
|
str | None
|
Save figure to this path if set. |
None
|
dpi
|
int
|
Save resolution (default 150). |
150
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
missing_matrix_html ¶
missing_matrix_html(
df: DataFrame,
*,
title: str = "Missing Data Matrix",
subtitle: str = "",
feature_type: str = "PROT",
annotation_levels: list[int] | None = None,
annotation_colors: dict[int | str, dict[str, str]]
| None = None,
label_level: int = -1,
sort_features: str | None = "descending",
cluster_samples: bool = True,
cluster_method: str = "average",
color_present: str = "#2d2d2d",
color_missing: str = "#f0f0f0",
invert: bool = False,
completeness: str = "below",
completeness_threshold: float | None = None,
width: int | None = None,
height: int | None = None,
save: str | None = None,
) -> str
Interactive HTML missing-data matrix using plotly.
Hover tooltips show the feature name, sample ID, every annotation level, and
detection status. Supports the same clustering, sorting, annotation and
completeness options as :func:missing_matrix.
Requires the optional plotly dependency (pip install mismap-qc[interactive]).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
Features (rows) x samples (columns). NaN marks a missing value. |
required |
title
|
str
|
Figure title. |
'Missing Data Matrix'
|
subtitle
|
str
|
Secondary line below the title, for dataset metadata. |
''
|
feature_type
|
str
|
Type of features: "PROT", "GENE", or "PEPTIDE". Used for hover labels. |
'PROT'
|
annotation_levels
|
list of int
|
Column levels to draw as annotation strips. Defaults to all levels except the innermost. |
None
|
annotation_colors
|
dict
|
Per-level colour overrides, keyed by level index or level name. Levels left unspecified fall back to the built-in palettes. |
None
|
label_level
|
int
|
Which column level supplies the x-axis tick labels. |
-1
|
sort_features
|
('ascending', 'descending')
|
Sort features by completeness. None leaves the input order. |
"ascending"
|
cluster_samples
|
bool
|
Cluster samples by their binary nullity pattern. |
True
|
cluster_method
|
str
|
scipy linkage method used when |
'average'
|
color_present
|
str
|
Colour for detected cells. |
'#2d2d2d'
|
color_missing
|
str
|
Colour for missing cells. |
'#f0f0f0'
|
invert
|
bool
|
Swap the present and missing colours. |
False
|
completeness
|
('below', 'side')
|
Place the completeness sparkline below (per sample) or to the side (per feature). |
"below"
|
completeness_threshold
|
float
|
Draw a reference line at this completeness value, between 0 and 1. |
None
|
width
|
int
|
Plot dimensions in pixels. Calculated from the data when None. |
None
|
height
|
int
|
Plot dimensions in pixels. Calculated from the data when None. |
None
|
save
|
str
|
Write the HTML to this path in addition to returning it. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The rendered HTML document. |
Examples:
Per-check plots¶
completeness_bars ¶
completeness_bars(
df: DataFrame,
group_level: int | str,
*,
threshold: float | None = None,
color: str | dict | None = None,
orientation: str = "horizontal",
title: str = "Per-Group Completeness",
fontsize: int = 10,
save: str | None = None,
dpi: int = 150,
return_data: bool = False,
) -> plt.Figure
Horizontal (or vertical) bar chart of per-group detection completeness.
For each group, shows the mean fraction of features detected across all
samples in that group. Replaces the console-only group_summary output
of missing_matrix with a publishable figure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
Features (rows) x Samples (columns). NaN = missing / not detected.
Columns may be a MultiIndex; use |
required |
group_level
|
int or str
|
Column level (index or name) to group samples by.
If |
required |
threshold
|
float or None
|
Draw a dashed red line at this completeness value (0–1). E.g. |
None
|
color
|
str, dict, or None
|
Single hex colour for all bars, or |
None
|
orientation
|
'horizontal' or 'vertical'
|
Bar orientation. Horizontal (default) is easier to read with long group names. |
'horizontal'
|
title
|
str
|
Figure title. |
'Per-Group Completeness'
|
fontsize
|
int
|
Base font size (default 10). |
10
|
save
|
str or None
|
Save figure to this path if set. |
None
|
dpi
|
int
|
Save resolution (default 150). |
150
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
detection_waterfall ¶
detection_waterfall(
df: DataFrame,
thresholds: list[float] | None = None,
group_level: int | str | None = None,
feature_type: str = "PROT",
color: str = "#2d2d2d",
title: str | None = None,
subtitle: str = "",
figsize: tuple[float, float] | None = None,
fontsize: int = 10,
save: str | None = None,
dpi: int = 150,
return_data: bool = False,
) -> plt.Figure
Waterfall plot showing features ranked by detection rate.
Features are ranked by their detection rate across samples and plotted as a cumulative curve. Threshold lines show how many features survive at different filtering cutoffs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
Features (rows) x samples (columns). NaN = missing/not detected. |
required |
thresholds
|
list of float or None
|
Detection rate thresholds to draw as horizontal lines (0-1 scale). Default: [0.5, 0.7, 0.9]. |
None
|
group_level
|
int, str, or None
|
If set, compute and plot separate curves per group (MultiIndex level). |
None
|
feature_type
|
str
|
Type of features: "PROT", "GENE", or "PEPTIDE". Used for axis labels. |
'PROT'
|
color
|
str
|
Colour for the curve when not grouping. Default "#2d2d2d". |
'#2d2d2d'
|
title
|
str or None
|
Figure title. Auto-generated from feature_type if None. |
None
|
subtitle
|
str
|
Italic line below title. |
''
|
figsize
|
tuple or None
|
Figure size. Auto-calculated if None. |
None
|
fontsize
|
int
|
Base font size (default 10). |
10
|
save
|
str or None
|
Save figure to this path if set. |
None
|
dpi
|
int
|
Save resolution (default 150). |
150
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
missing_runorder ¶
missing_runorder(
df: DataFrame,
run_order: list | Series | ndarray | None = None,
group_level: int | str | None = None,
smooth: bool = True,
smooth_window: int = 5,
title: str = "Missingness Over Run Order",
subtitle: str = "",
figsize: tuple[float, float] | None = None,
fontsize: int = 10,
save: str | None = None,
dpi: int = 150,
return_data: bool = False,
) -> plt.Figure
Plot per-sample missingness rate against run order.
Shows how missingness varies across sample acquisition order. Useful for detecting instrument drift or batch effects in proteomics experiments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
Features (rows) x samples (columns). NaN = missing/not detected. |
required |
run_order
|
array - like or None
|
Explicit run order values (one per sample). Uses column index if None. |
None
|
group_level
|
int, str, or None
|
If set, colour points by this MultiIndex level (e.g. batch, condition). |
None
|
smooth
|
bool
|
Add a rolling mean smoother line. Default True. |
True
|
smooth_window
|
int
|
Window size for rolling mean. Default 5. |
5
|
title
|
str
|
Figure title. |
'Missingness Over Run Order'
|
subtitle
|
str
|
Italic line below title. |
''
|
figsize
|
tuple or None
|
Figure size. Auto-calculated if None. |
None
|
fontsize
|
int
|
Base font size (default 10). |
10
|
save
|
str or None
|
Save figure to this path if set. |
None
|
dpi
|
int
|
Save resolution (default 150). |
150
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
missing_mechanism ¶
missing_mechanism(
df: DataFrame,
*,
method: str = "mannwhitneyu",
alpha: float = 0.05,
min_present: int = 3,
feature_type: str = "PROT",
show_scatter: bool = True,
title: str | None = None,
subtitle: str = "",
figsize: tuple[float, float] | None = None,
fontsize: int = 10,
save: str | None = None,
dpi: int = 150,
) -> tuple[plt.Figure, pd.DataFrame]
Classify per-feature missing-data mechanism and plot the result.
For each feature, compares the per-sample mean abundance of samples where the feature is detected against samples where it is missing (one-sided Mann-Whitney U). Significantly higher present-side means => MNAR (the feature drops out preferentially in low-abundance samples).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
features (rows) x samples (columns). NaN = missing. |
required |
method
|
str
|
Classification method. Only "mannwhitneyu" is implemented for v0.2.0. |
'mannwhitneyu'
|
alpha
|
float
|
Significance threshold for the MNAR call. |
0.05
|
min_present
|
int
|
Minimum non-missing AND non-present samples required to test a feature. Features below this threshold are classified "INSUFFICIENT". |
3
|
feature_type
|
str
|
"PROT" | "GENE" | "PEPTIDE". |
'PROT'
|
show_scatter
|
bool
|
Show the abundance-vs-missing-rate scatter panel. |
True
|
title
|
str
|
Figure title. None => auto from feature_type. |
None
|
subtitle
|
str
|
Italic line below the title. |
''
|
figsize
|
tuple
|
Auto-sized when None. |
None
|
fontsize
|
int
|
Base font size. |
10
|
save
|
str
|
Path to save the figure. |
None
|
dpi
|
int
|
Save resolution. |
150
|
Returns:
| Name | Type | Description |
|---|---|---|
fig |
Figure
|
|
classification |
DataFrame
|
Columns: feature, mechanism, missing_rate, mean_abundance, p_value. mechanism is one of {"MNAR", "MAR", "MCAR", "INSUFFICIENT"}. |
Examples:
comissing_heatmap ¶
comissing_heatmap(
df: DataFrame,
*,
top_n: int = 50,
cluster: bool = True,
method: str = "average",
feature_type: str = "PROT",
cmap: str = "Blues",
title: str | None = None,
subtitle: str = "",
figsize: tuple[float, float] | None = None,
fontsize: int = 10,
save: str | None = None,
dpi: int = 150,
return_data: bool = False,
) -> plt.Figure
Heatmap of pairwise co-missingness for the top_n most-missing features.
Cell (i, j) = fraction of samples where features i and j are simultaneously missing. Tight clusters indicate co-dropping protein complexes, batch failures, or correlated low-abundance features.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
features (rows) x samples (columns). NaN = missing. |
required |
top_n
|
int
|
Number of most-missing features to display. |
50
|
cluster
|
bool
|
Hierarchically cluster features by co-missingness pattern. |
True
|
method
|
str
|
scipy linkage method ("average", "complete", "ward", etc.). |
'average'
|
feature_type
|
str
|
"PROT" | "GENE" | "PEPTIDE". |
'PROT'
|
cmap
|
str
|
matplotlib colormap. |
'Blues'
|
title
|
str
|
Title / subtitle. |
None
|
subtitle
|
str
|
Title / subtitle. |
None
|
figsize
|
tuple
|
Auto-sized when None. |
None
|
fontsize
|
int
|
Base font size. |
10
|
save
|
str
|
Path to save the figure. |
None
|
dpi
|
int
|
Save resolution. |
150
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
missing_upset ¶
missing_upset(
df: DataFrame,
*,
by="sample",
group_min_frac: float = 0.5,
min_size: int = 1,
max_intersections: int = 50,
feature_type: str = "PROT",
title: str | None = None,
subtitle: str = "",
figsize: tuple[float, float] | None = None,
fontsize: int = 10,
save: str | None = None,
dpi: int = 150,
return_data: bool = False,
) -> plt.Figure
UpSet plot of which sample combinations share missing features.
For each intersection of samples (or groups), shows how many features are missing in exactly that combination and no others. Bar charts show totals and Venn diagrams stop working past three sets; this answers whether particular replicates lose the same features together, which is what separates technical dropout from biology at small n.
Every feature with at least one missing value belongs to exactly one intersection. Fully detected features carry no intersection information and are excluded.
Requires upsetplot (pip install mismap-qc[upset]).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
features (rows) x samples (columns). NaN = missing. |
required |
by
|
str or int
|
|
'sample'
|
group_min_frac
|
float
|
Group mode only. A feature counts as missing in a group when it is missing in at least this fraction of that group's samples. The 0.5 default treats a feature as lost in a group once it is absent from the majority of it. |
0.5
|
min_size
|
int
|
Intersections smaller than this are not drawn. |
1
|
max_intersections
|
int
|
Draw at most this many intersections, largest first. Intersection count
grows quickly with sample count, and an uncapped plot is unreadable past a
few dozen samples. Truncation is annotated on the figure, and
|
50
|
feature_type
|
str
|
"PROT" | "GENE" | "PEPTIDE". |
'PROT'
|
title
|
str
|
Title / subtitle. Title is auto-generated when None. |
None
|
subtitle
|
str
|
Title / subtitle. Title is auto-generated when None. |
None
|
figsize
|
tuple
|
Auto-sized when None. |
None
|
fontsize
|
int
|
Base font size. |
10
|
save
|
str
|
Path to save the figure. |
None
|
dpi
|
int
|
Save resolution. |
150
|
return_data
|
bool
|
Return |
False
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
missing_abundance_density ¶
missing_abundance_density(
df: DataFrame,
*,
groups: Series | ndarray | list | None = None,
max_na_levels: int = 6,
title: str = "Abundance by Missingness",
xlabel: str = "Mean Abundance",
ylabel: str = "Density",
figsize: tuple[float, float] | None = None,
fontsize: int = 10,
palette: list[str] | None = None,
alpha: float = 0.7,
linewidth: float = 1.5,
legend_title: str = "# Missing",
save: str | None = None,
dpi: int = 150,
) -> plt.Figure
Density plot of mean abundance stratified by missingness count.
This diagnostic plot reveals whether missing data follows the MNAR (Missing Not At Random) pattern typical of proteomics/mass-spec data, where low-abundance features are more likely to be missing due to detection limits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
Genes/proteins (rows) x Samples (columns). NaN = missing. |
required |
groups
|
Series, array, or list
|
Group labels for each sample (same length as df.columns). If provided, creates faceted subplots, one per group. |
None
|
max_na_levels
|
int
|
Maximum number of distinct missingness levels to show (default 6). Higher counts are binned into "N+" category. |
6
|
title
|
str
|
Figure title. |
'Abundance by Missingness'
|
xlabel
|
str
|
Axis labels. |
'Mean Abundance'
|
ylabel
|
str
|
Axis labels. |
'Mean Abundance'
|
figsize
|
tuple
|
Figure size. Auto-calculated if None. |
None
|
fontsize
|
int
|
Base font size. |
10
|
palette
|
list[str]
|
Colors for missingness levels. Uses built-in palette if None. |
None
|
alpha
|
float
|
Line/fill transparency (default 0.7). |
0.7
|
linewidth
|
float
|
Density line width (default 1.5). |
1.5
|
legend_title
|
str
|
Legend title (default "# Missing"). |
'# Missing'
|
save
|
str
|
Save figure to this path. |
None
|
dpi
|
int
|
Save resolution (default 150). |
150
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples: