Visualization
Prevalence Plot
quack.visualization._prevalence.prevalence_plot(method_names, true_prevalences, estim_prevalences, class_name='positive class', train_prevalence=None, n_bins=21, show_std=True, colors=None, markers=None, fig_size=(6, 6), font_size=11, legend_font_size=None, marker_size=5.0, line_width=1.5, band_alpha=0.2, title='Prevalence Plot', grid=True, ax=None)
Plot predicted vs. true prevalence for a target class (binary diagonal plot).
For each unique entry in method_names, all (true, estim) pairs across
every experiment sharing that name are pooled, binned by true prevalence
into n_bins equal-width intervals, and summarized by the mean predicted
prevalence per bin (connected by a line) with an optional +/- 1 standard
deviation shaded band. A dashed diagonal (y = x) marks the ideal,
unbiased quantifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method_names
|
str | Sequence[str]
|
Name of the method for each experiment. A name can repeat (e.g. one entry per dataset/fold); all matching experiments are merged before binning. |
required |
true_prevalences
|
ndarray | Sequence[ndarray]
|
True prevalence of |
required |
estim_prevalences
|
ndarray | Sequence[ndarray]
|
Predicted prevalence of |
required |
class_name
|
str
|
Label used on the axes/legend for the target class. Defaults to "positive class". |
'positive class'
|
train_prevalence
|
float | Sequence[float]
|
One or more training prevalences to mark on the diagonal. Defaults to None. |
None
|
n_bins
|
int
|
Number of equal-width bins over |
21
|
show_st
|
Whether to draw +/- 1 std shaded bands around each method's line. Defaults to True. |
required | |
colors
|
Sequence
|
Custom colors, one per unique method. Defaults to a colorblind-safe palette, auto-extended as needed. |
None
|
markers
|
Sequence[str]
|
Custom marker styles, one per unique method. Defaults to a built-in marker cycle. |
None
|
fig_size
|
tuple[float, float]
|
Figure size in inches. Defaults to (6, 6). |
(6, 6)
|
font_size
|
int
|
Base font size for axis labels/title. Defaults to 11. |
11
|
legend_font_size
|
int
|
Font size for the legend. Defaults to |
None
|
marker_size
|
float
|
Marker size. Defaults to 5.0. |
5.0
|
line_width
|
float
|
Line width. Defaults to 1.5. |
1.5
|
band_alpha
|
float
|
Opacity of the +/- 1 std band. Defaults to 0.2. |
0.2
|
title
|
str
|
Plot title. Defaults to "Prevalence Plot". |
'Prevalence Plot'
|
grid
|
bool
|
Whether to draw a background grid. Defaults to True. |
True
|
ax
|
Axes
|
Existing axes to draw on. A new figure/axes pair is created when None. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
fig |
Figure
|
The generated figure. Call |
Examples:
>>> import numpy as np
>>> from quack.visualization import prevalence_plot
>>> rng = np.random.default_rng(0)
>>> true_prev = rng.uniform(0, 1, 200)
>>> estim_prev = np.clip(true_prev + rng.normal(0, 0.05, 200), 0, 1)
>>> fig = prevalence_plot("CC", true_prev, estim_prev, train_prevalence=0.5)
>>> fig.savefig("prevalence.png", dpi=300)
Source code in quack/visualization/_prevalence.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | |
Quantification Bias Plot
quack.visualization._bias.bias_plot(method_names, true_prevalences, estim_prevalences, class_name='positive class', n_bins=1, colors=None, fig_size=(8, 6), font_size=11, legend_font_size=None, title='Bias Plot', box_width=0.6, grid=True, ax=None)
Plot the distribution of signed prevalence errors per method as box plots.
The bias for a single test bag is defined as
bias = estimated_prevalence - true_prevalence for class_name. A value
of 0 indicates a perfectly unbiased estimate; positive values indicate a
tendency to overestimate the class, negative values a tendency to
underestimate it.
When n_bins > 1, the true test prevalence range [0, 1] is split into
n_bins equal-width intervals and one group of boxes (one box per
method) is drawn per interval, mirroring QuaPy's binary_bias_bins, so
that bias-vs-prevalence patterns invisible in the global view can be
detected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method_names
|
str | Sequence[str]
|
Name of the method for each experiment (can repeat across datasets/folds; matching experiments are pooled together). |
required |
true_prevalences
|
ndarray | Sequence[ndarray]
|
True prevalence of |
required |
estim_prevalences
|
ndarray | Sequence[ndarray]
|
Predicted prevalence of |
required |
class_name
|
str
|
Target class label used in axis/legend text. Defaults to "positive class". |
'positive class'
|
n_bins
|
int
|
Number of equal-width true-prevalence bins. Use |
1
|
colors
|
Sequence
|
Custom colors, one per unique method. Defaults to a colorblind-safe palette, auto-extended as needed. |
None
|
fig_size
|
tuple[float, float]
|
Figure size in inches. Defaults to (8, 6). |
(8, 6)
|
font_size
|
int
|
Base font size for axis labels/title. Defaults to 11. |
11
|
legend_font_size
|
int
|
Legend font size. Defaults to |
None
|
title
|
str
|
Plot title. Defaults to "Bias Plot". |
'Bias Plot'
|
box_width
|
float
|
Width of each individual box. Defaults to 0.6. |
0.6
|
grid
|
bool
|
Whether to draw a background grid. Defaults to True. |
True
|
ax
|
Axes
|
Existing axes to draw on. A new figure/axes pair is created when None. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
fig |
Figure
|
The generated figure. Call |
Examples:
>>> import numpy as np
>>> from quack.visualization import quantification_bias_plot
>>> rng = np.random.default_rng(0)
>>> true_prev = rng.uniform(0, 1, 200)
>>> estim_prev = np.clip(true_prev + 0.1 + rng.normal(0, 0.05, 200), 0, 1)
>>> fig = quantification_bias_plot("CC", true_prev, estim_prev, n_bins=3)
Source code in quack/visualization/_bias.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |
Class Distribution Plot
quack.visualization._distribution.class_distribution_plot(y, normalize=False, title='Class Distribution', fig_size=(8, 5), colors=None, font_size=11, bar_label_font_size=None, show_bar_labels=True, horizontal=False, grid=True, ax=None)
Plot the (optionally normalized) class distribution of a label array.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y
|
ndarray
|
Array-like with all labels. |
required |
normalize
|
bool
|
If True, plot relative frequencies (prevalences summing to 1.0) instead of raw counts. Defaults to False. |
False
|
title
|
str
|
Plot title. Defaults to "Class Distribution". |
'Class Distribution'
|
fig_size
|
tuple[float, float]
|
Figure size in inches. Defaults to (8, 5). |
(8, 5)
|
colors
|
Sequence
|
Custom colors, one per class. Defaults to a colorblind-safe palette, auto-extended for many classes. |
None
|
font_size
|
int
|
Base font size for axis labels/title. Defaults to 11. |
11
|
bar_label_font_size
|
int
|
Font size for the value labels drawn on top of each bar.
Defaults to |
None
|
show_bar_labels
|
bool
|
Whether to annotate each bar with its value. Defaults to True. |
True
|
horizontal
|
bool
|
If True, draws horizontal bars (useful for many classes / long class names). Defaults to False. |
False
|
grid
|
bool
|
Whether to draw a background grid. Defaults to True. |
True
|
ax
|
Axes
|
Existing axes to draw on. A new figure/axes pair is created when None. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
fig |
Figure
|
The generated figure. Call |
Examples:
>>> import numpy as np
>>> from quack.visualization import class_distribution_plot
>>> y = np.random.choice([0, 1, 2], size=500, p=[0.6, 0.3, 0.1])
>>> fig = class_distribution_plot(y, normalize=True)
>>> fig.savefig("class_distribution.pdf")
Source code in quack/visualization/_distribution.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |
Prevalence Coverage Plot
quack.visualization._coverage.prevalence_coverage_plot(prevalences, labels=None, class_name='positive class', train_prevalence=None, n_bins=20, show_rug=True, show_stats=True, density=False, colors=None, fig_size=(8, 5), font_size=11, legend_font_size=None, bar_alpha=0.65, rug_height=0.04, title='Prevalence Coverage', grid=True, ax=None)
Plot how well a set of bags covers the [0, 1] prevalence range for a class.
Each entry in prevalences is a 1D array with the realized prevalence
of class_name for every generated bag in one experiment (typically
generator.sampled_prevalences_[:, class_index] from a
quack.bag_generator.BaseBagGenerator subclass). A histogram over
n_bins equal-width bins shows how many bags fall in each prevalence
range, while an optional rug plot marks every individual bag along the
x-axis, so isolated or empty regions of the simplex are easy to spot
even when the histogram bin is technically non-empty.
Multiple series can be overlaid (e.g. to compare PriorShiftBagGenerator
vs. CovariateShiftBagGenerator, or different sampling_strategy/
dirichlet_alpha configurations) using semi-transparent, colorblind-safe
colors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prevalences
|
ndarray | Sequence[ndarray]
|
One 1D array of per-bag prevalences for |
required |
labels
|
str | Sequence[str]
|
Name of each series, used in the legend and coverage statistics. Defaults to
|
None
|
class_name
|
str
|
Label used on the x-axis for the target class. Defaults to "positive class". |
'positive class'
|
train_prevalence
|
float | Sequence[float]
|
One or more training prevalences to mark as vertical reference lines. Defaults to None. |
None
|
n_bins
|
int
|
Number of equal-width histogram bins over |
20
|
show_rug
|
bool
|
Whether to draw a rug plot (one tick per bag) below the histogram. Defaults to True. |
True
|
show_stats
|
bool
|
Whether to annotate the plot with per-series min/max/mean prevalence
and simplex-bin coverage (the fraction of the |
True
|
density
|
bool
|
If True, normalize histograms to a density (area sums to 1) instead of raw bag counts — useful when comparing series generated with a different number of bags. Defaults to False. |
False
|
colors
|
Sequence
|
Custom colors, one per series. Defaults to a colorblind-safe palette, auto-extended as needed. |
None
|
fig_size
|
tuple[float, float]
|
Figure size in inches. Defaults to (8, 5). |
(8, 5)
|
font_size
|
int
|
Base font size for axis labels/title. Defaults to 11. |
11
|
legend_font_size
|
int
|
Legend font size. Defaults to |
None
|
bar_alpha
|
float
|
Opacity of the histogram bars, low enough for overlapping series to remain distinguishable. Defaults to 0.65. |
0.65
|
rug_height
|
float
|
Height of each rug row, as a fraction of the histogram's y-range. Defaults to 0.04. |
0.04
|
title
|
str
|
Plot title. Defaults to "Prevalence Coverage". |
'Prevalence Coverage'
|
grid
|
bool
|
Whether to draw a background grid. Defaults to True. |
True
|
ax
|
Axes
|
Existing axes to draw on. A new figure/axes pair is created when None. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
fig |
Figure
|
The generated figure. Call |
Raises:
| Type | Description |
|---|---|
ValueError: If `labels` length does not match the number of series,
|
any series is not 1D, or any prevalence value falls outside
|
Examples:
>>> import numpy as np
>>> from quack.bag_generator import PriorShiftBagGenerator, CovariateShiftBagGenerator
>>> from quack.visualization import prevalence_coverage_plot
>>> from sklearn.datasets import make_classification
>>> X, y = make_classification(n_samples=500, n_classes=2, random_state=0)
>>> prior_gen = PriorShiftBagGenerator(n_bags=200, bag_size=100, random_state=0)
>>> cov_gen = CovariateShiftBagGenerator(n_bags=200, bag_size=100, random_state=0)
>>> prior_gen.to_list(X, y)
>>> cov_gen.to_list(X, y)
>>> fig = prevalence_coverage_plot(
... [prior_gen.sampled_prevalences_[:, 1], cov_gen.sampled_prevalences_[:, 1]],
... labels=["Prior Shift", "Covariate Shift"],
... class_name="positive class",
... )
>>> fig.savefig("prevalence_coverage.png", dpi=300)
Source code in quack/visualization/_coverage.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | |
Color Utilities
quack.visualization._colors.get_color_palette(n_colors, palette=None)
Build a list of n_colors visually distinct colors.
Falls back to the colorblind-safe base palette while there are enough colors available. When more colors than the base palette are requested (e.g. many quantifiers being compared at once), it extends the palette by uniformly sampling a perceptually-uniform colormap so that all colors remain distinguishable from each other.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_colors
|
int
|
Number of distinct colors needed. |
required |
palette
|
Sequence
|
User-provided palette (hex strings or RGBA tuples) to use instead of the default colorblind-safe one. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
colors_list |
list
|
List of length |
Source code in quack/visualization/_colors.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | |
quack.visualization._colors.get_marker_cycle(n_markers, markers=None)
Cycle through a fixed list of distinguishable marker shapes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_markers
|
int
|
Number of markers needed. |
required |
markers
|
Sequence[str]
|
Custom marker list. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
markers_shapes |
list
|
List of length |
Source code in quack/visualization/_colors.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | |