API reference¶
Every public name in depictr is documented here, grouped along the path an analysis takes:
look at the data, reduce it or follow it over time, read the model, check the model, judge a
classifier, set the look, and compose and save the result. The groups follow the
R package's reference index in the same
order, so a function can be looked up in the same place on either site.
The two indexes are cut slightly differently in the few places where the Python package's own families do not line up with the R one. Time series has no group of its own here, and those functions close the 'Multivariate, survival and time series' group, which is where the Python package has always documented them. The R index's 'Diagnostics and classification' is split in two, because the classification curves are all computed by scikit-learn and reached through a separate install extra. R's 'Uncertainty and power' has no counterpart either, and the posterior and power curves are documented with the other model estimates they are drawn from. What the R index calls 'Theming, accessibility and reporting' appears here as 'Theme, palette and accessibility', covering the theme, the colour-vision checks and the figure audit, while plot composition and saving move to the last group beside the datasets and the one-figure model report stays with the diagnostics it collects.
Everything listed under a group heading is importable straight from depictr. The same plots are
shown rendered, with the code that produced them, in the gallery.
Exploratory analysis¶
A first look at a dataset: distributions, categories, relationships, correlation, cumulative distributions, outliers and a missing-data map.
These plots are shown, with the code that produced them, on the exploring data page of the gallery.
explore_distribution ¶
explore_distribution(data, x, group=None, kind='density', bins=30, alpha=0.6, legend_inside=False, title=None)
Plot the distribution of a numeric variable, optionally split by a group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
x
|
str
|
Name of the numeric column to display. |
required |
group
|
str
|
A grouping column mapped to colour/fill. |
None
|
kind
|
('density', 'histogram', 'both')
|
What to draw. |
"density"
|
bins
|
int
|
Number of histogram bins. |
30
|
alpha
|
float
|
Fill transparency, useful when groups overlap. |
0.6
|
legend_inside
|
bool
|
When |
False
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> ld = dp.lexical_decision()
>>> p = dp.explore_distribution(ld, "RT", group="condition", kind="both")
Source code in src/depictr/eda.py
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 | |
explore_categorical ¶
explore_categorical(data, x, group=None, proportion=True, title=None)
Bar chart of a categorical variable, optionally grouped (dodged).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
|
required |
x
|
str
|
The categorical column. |
required |
group
|
str
|
A second categorical column mapped to fill, drawn side by side. |
None
|
proportion
|
bool
|
Show proportions within each group rather than raw counts. |
True
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> wb = dp.wellbeing_survey()
>>> p = dp.explore_categorical(wb, "education", group="region")
Source code in src/depictr/eda.py
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 | |
explore_bivariate ¶
explore_bivariate(data, x, y, title=None)
Plot the relationship between two columns, choosing the plot from their types.
The plot is selected from the column dtypes:
- two numeric columns give a scatter plot with a trend line
(:func:
scatter_trend); - one numeric and one categorical column give boxplots of the numeric variable across the categories, with the raw points jittered over them;
- two categorical columns give a tile of joint counts, shaded by frequency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
x
|
str
|
Names of the two columns to relate. |
required |
y
|
str
|
Names of the two columns to relate. |
required |
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> ld = dp.lexical_decision()
>>> p = dp.explore_bivariate(ld, "condition", "RT")
Source code in src/depictr/bivariate.py
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 | |
scatter_trend ¶
scatter_trend(data, x, y, group=None, method='lm', title=None)
Scatter plot with a fitted trend line and confidence band.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
x
|
str
|
Names of the numeric columns for the horizontal and vertical axes. |
required |
y
|
str
|
Names of the numeric columns for the horizontal and vertical axes. |
required |
group
|
str
|
A grouping column. When given, points and a separate trend line are
coloured by group via :func: |
None
|
method
|
str
|
Smoothing method passed to :func: |
'lm'
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> cy = dp.crop_yield()
>>> p = dp.scatter_trend(cy, "fertiliser", "yield", group="treatment")
Source code in src/depictr/bivariate.py
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 | |
correlation_heatmap ¶
correlation_heatmap(data, cols=None, title=None)
Heatmap of pairwise Pearson correlations among numeric columns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
|
required |
cols
|
list of str
|
Columns to include; defaults to all numeric columns. |
None
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
Zero-variance columns are dropped with a warning, and any correlation
that remains undefined is labelled |
Examples:
>>> import depictr as dp
>>> wb = dp.wellbeing_survey()
>>> p = dp.correlation_heatmap(wb)
Source code in src/depictr/eda.py
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 228 229 230 231 | |
missingness_map ¶
missingness_map(data, sort=True, legend_inside=False, title=None)
Tile map of missing values, one column per variable and one row per record.
Variables are ordered most- to least-missing, so the worst offenders sit on the left. The percentage missing is shown in each axis label.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
|
required |
sort
|
bool
|
Order columns by their proportion of missing values. |
True
|
legend_inside
|
bool
|
When |
False
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> wb = dp.wellbeing_survey()
>>> p = dp.missingness_map(wb, legend_inside=True)
Source code in src/depictr/eda.py
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | |
ecdf_plot ¶
ecdf_plot(data, x, group=None, legend_inside=False, title=None)
Empirical cumulative distribution function, one step curve per group.
The ECDF reads off the proportion of observations at or below each value, so it shows the whole distribution without the smoothing choices a density makes. Curves that sit to the right are shifted towards larger values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
x
|
str
|
Name of the numeric column. |
required |
group
|
str
|
A grouping column mapped to colour, drawn as one curve per level. |
None
|
legend_inside
|
bool
|
When |
False
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> ld = dp.lexical_decision()
>>> p = dp.ecdf_plot(ld, "RT", group="condition", legend_inside=True)
Source code in src/depictr/distributions_extra.py
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 | |
ridgeline_plot ¶
ridgeline_plot(data, x, group, title=None)
Overlapping densities, one ridge per group level.
Each level gets its own filled density on a shared x-axis, stacked so the ridges overlap a little. Reading top to bottom gives a quick sense of how the distribution shifts across levels. Levels are ordered by their median so the progression is easy to follow.
The overlap is faked with :func:plotnine.facet_grid: one narrow row per
level, panel spacing pulled negative so neighbouring ridges touch. It stays a
single ggplot, since plotnine has no dedicated ridgeline geom.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
x
|
str
|
Name of the numeric column. |
required |
group
|
str
|
The grouping column; one ridge is drawn per level. |
required |
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> wb = dp.wellbeing_survey()
>>> p = dp.ridgeline_plot(wb, "life_satisfaction", "region")
Source code in src/depictr/distributions_extra.py
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 | |
dumbbell_plot ¶
dumbbell_plot(data, category, value, group, legend_inside=False, title=None)
Dumbbell plot pairing two group values per category.
For a group with exactly two levels, each category becomes one row with a point for each level joined by a segment. The length of the segment is the gap between the two levels, which is the comparison the plot is built to show.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
Either one row per category-and-group combination, or raw rows that are averaged to one value per combination. |
required |
category
|
str
|
The categorical column, one row per level on the y-axis. |
required |
value
|
str
|
The numeric column plotted along the x-axis. |
required |
group
|
str
|
A two-level grouping column; its levels are the two points. |
required |
legend_inside
|
bool
|
When |
False
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> wb = dp.wellbeing_survey()
>>> wb = wb.assign(age_group=np.where(wb["age"] < 50, "under 50", "50 or over"))
>>> p = dp.dumbbell_plot(wb, "region", "life_satisfaction", "age_group")
Source code in src/depictr/distributions_extra.py
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 | |
outlier_plot ¶
outlier_plot(data, x, title=None)
Box plot of one variable with outliers flagged in the accent colour.
Points beyond 1.5 times the interquartile range from the nearest quartile, the usual Tukey rule the box plot's whiskers already use, are drawn on top in the accent colour. The box itself suppresses its own outlier markers so they are not drawn twice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
x
|
str
|
Name of the numeric column to inspect. |
required |
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> cy = dp.crop_yield()
>>> p = dp.outlier_plot(cy, "yield")
Source code in src/depictr/distributions_extra.py
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | |
group_comparison_plot ¶
group_comparison_plot(data, x, group, title=None)
Group means with confidence intervals over the raw points.
The estimate-with-uncertainty alternative to a bar chart: each group shows its raw observations (jittered), the mean, and a confidence interval for the mean. Showing the spread of the data alongside the estimate guards against reading too much into a difference in means.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
x
|
str
|
Name of the numeric column being compared. |
required |
group
|
str
|
The grouping column on the x-axis. |
required |
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Notes
The interval is a normal-approximation 95% confidence interval for the mean (mean plus or minus 1.96 standard errors). It describes the precision of the mean, not the spread of the data.
Examples:
>>> import depictr as dp
>>> ld = dp.lexical_decision()
>>> p = dp.group_comparison_plot(ld, "RT", "condition")
Source code in src/depictr/distributions_extra.py
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | |
raincloud_plot ¶
raincloud_plot(data, x, group=None, title=None)
Raincloud plot of a numeric variable, optionally split by a group.
A raincloud sets three views of the same distribution side by side: a half-violin density (the "cloud"), a narrow boxplot for the median and quartiles, and the jittered raw points (the "rain"). Seeing the shape, the summary and every observation together guards against the boxplot hiding bimodality or a thin tail (Allen et al., 2021).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
x
|
str
|
Name of the numeric column whose distribution is shown. |
required |
group
|
str
|
A categorical column. Each level gets its own raincloud along the horizontal axis, coloured by the depictr palette. With no group a single raincloud is drawn. |
None
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
References
Allen, M., Poggiali, D., Whitaker, K., Marshall, T. R., van Langen, J., & Kievit, R. A. (2021). Raincloud plots: A multi-platform tool for robust data visualization. Wellcome Open Research, 4, 63. https://doi.org/10.12688/wellcomeopenres.15191.2
Examples:
>>> import depictr as dp
>>> ld = dp.lexical_decision()
>>> p = dp.raincloud_plot(ld, "RT", group="condition")
Source code in src/depictr/eda_extra.py
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 | |
explore_pairs ¶
explore_pairs(data, cols=None, title=None)
Scatter-plot matrix over a few numeric columns.
Builds the familiar pairs grid: a scatter of every variable against every other off the diagonal, and that variable's own density on the diagonal. Each cell is a small themed plot, composed into an N x N grid. The number of columns is capped at five, beyond which the cells are too small to read.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
cols
|
list of str
|
Numeric columns to include, in order. Defaults to the first few numeric
columns of |
None
|
title
|
str
|
Accepted for API symmetry, but dropped with a warning: plotnine compositions cannot carry a figure-level title, so the matrix draws without one. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot or Compose
|
The composed grid from :func: |
Examples:
>>> import depictr as dp
>>> cy = dp.crop_yield()
>>> p = dp.explore_pairs(cy, cols=["rainfall", "fertiliser", "yield"])
Source code in src/depictr/eda_extra.py
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 | |
Multivariate, survival and time series¶
Principal components and clustering, Kaplan-Meier survival, and the time-series family (series, autocorrelation, decomposition and seasonal views).
These plots are shown, with the code that produced them, on the multivariate and time series page of the gallery, and the survival curve on the classification and survival page.
pca_plot ¶
pca_plot(data, cols=None, group=None, title=None)
PCA biplot: observations on the first two components, with loading arrows.
Observations are scored on PC1 and PC2 and shown as points, optionally
coloured by group. Each original variable is drawn as an arrow from the
origin in the direction of its loading, labelled with the variable name. The
axis labels report the percentage of variance each component explains.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
cols
|
list of str
|
Numeric columns to decompose; defaults to all numeric columns. |
None
|
group
|
str
|
A column mapped to the colour of the observation points. Kept aside from
the decomposition, which uses only the numeric |
None
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> wb = dp.wellbeing_survey()
>>> p = dp.pca_plot(wb, group="region")
Source code in src/depictr/multivariate.py
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 | |
scree_plot ¶
scree_plot(data, cols=None, title=None)
Scree plot: variance explained per component, with the cumulative line.
Bars give the proportion of variance each principal component explains; an overlaid line and points give the running cumulative proportion. Both share the (0, 1) y-axis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
|
required |
cols
|
list of str
|
Numeric columns to decompose; defaults to all numeric columns. |
None
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> wb = dp.wellbeing_survey()
>>> p = dp.scree_plot(wb)
Source code in src/depictr/multivariate.py
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 | |
cluster_plot ¶
cluster_plot(data, cols=None, k=3, title=None)
k-means clusters drawn on the first two principal components.
The data are reduced to two principal components for display, k-means is run in that two-dimensional space, and points are coloured by cluster with each cluster centroid marked by a larger outlined point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
|
required |
cols
|
list of str
|
Numeric columns to use; defaults to all numeric columns. |
None
|
k
|
int
|
Number of clusters. |
3
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> wb = dp.wellbeing_survey()
>>> p = dp.cluster_plot(wb, k=3)
Source code in src/depictr/multivariate.py
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | |
dendrogram_plot ¶
dendrogram_plot(data, cols=None, method='ward', title=None)
Hierarchical-clustering dendrogram drawn from a scipy linkage.
The linkage is computed by scipy and the dendrogram coordinates it returns are redrawn as line segments under the depictr theme, so the tree matches the rest of the figure set. Leaves are not labelled, since the intent is to read the overall merge structure rather than individual observations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
|
required |
cols
|
list of str
|
Numeric columns to cluster on; defaults to all numeric columns. |
None
|
method
|
str
|
Linkage method passed to :func: |
'ward'
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> wb = dp.wellbeing_survey()
>>> p = dp.dendrogram_plot(wb.groupby("region").mean(numeric_only=True))
Source code in src/depictr/multivariate.py
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | |
silhouette_plot ¶
silhouette_plot(data, cols=None, k=3, title=None)
Silhouette widths per observation, grouped and ordered by cluster.
k-means is run on the standardised data and the silhouette width of each observation is drawn as a horizontal bar, sorted within its cluster and coloured by cluster. A dashed reference line marks the mean silhouette width, a quick read on how well-separated the clustering is overall.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
|
required |
cols
|
list of str
|
Numeric columns to use; defaults to all numeric columns. |
None
|
k
|
int
|
Number of clusters. |
3
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> wb = dp.wellbeing_survey()
>>> p = dp.silhouette_plot(wb, k=3)
Source code in src/depictr/multivariate.py
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | |
survival_plot ¶
survival_plot(time, event, group=None, conf_level=0.95, risk_table=False, legend_inside=False, title=None, x_lab='Time', y_lab='Survival probability')
Kaplan-Meier survival curves, optionally by group, with a log-rank test.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
time
|
array - like
|
Follow-up times. Must be finite: a missing or infinite time raises, since dropping or imputing it is the analyst's decision. |
required |
event
|
array - like
|
Event indicator (1 = event, 0 = censored). |
required |
group
|
array - like
|
Group label per observation; one curve per group, plus a log-rank test of the difference. Observations with a missing group are dropped with a warning, since they belong to no arm. |
None
|
conf_level
|
float
|
Accepted for future use; the Python twin does not yet draw the confidence band or censor marks the R package draws. |
0.95
|
risk_table
|
bool
|
Add a number-at-risk table as a thin strip beneath the curves. |
False
|
legend_inside
|
bool
|
When |
False
|
title
|
str
|
|
None
|
x_lab
|
str
|
Axis labels. |
'Time'
|
y_lab
|
str
|
Axis labels. |
'Time'
|
Returns:
| Type | Description |
|---|---|
ggplot
|
The plot carries |
Examples:
>>> import depictr as dp
>>> ct = dp.clinical_trial()
>>> p = dp.survival_plot(ct["time"], ct["event"], group=ct["arm"])
Source code in src/depictr/survival.py
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 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | |
acf_plot ¶
acf_plot(x, kind='acf', lags=None, title=None)
Autocorrelation or partial autocorrelation as a stem plot.
The correlations come from statsmodels (acf/pacf). The approximate
95% significance band, plus or minus 1.96 / sqrt(n), is drawn as a shaded
ribbon: stems reaching past it are the candidate lags.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Series or array - like
|
The series. Any index is ignored here; only the values are used. Missing values at either end are trimmed; an internal missing value is an error, since dropping it would correlate values across the closed-up gap. |
required |
kind
|
('acf', 'pacf')
|
Autocorrelation or partial autocorrelation. |
"acf"
|
lags
|
int
|
Number of lags to show. Defaults to |
None
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> import pandas as pd
>>> rng = np.random.default_rng(0)
>>> t = np.arange(120)
>>> series = pd.Series(50 + 0.3 * t + rng.normal(0, 3, 120))
>>> p = dp.acf_plot(series)
Source code in src/depictr/timeseries.py
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 | |
decompose_plot ¶
decompose_plot(x, period=None, model='additive', title=None)
Seasonal decomposition as a stacked, facetted figure.
statsmodels' seasonal_decompose splits the series into observed, trend,
seasonal and residual components. The four are drawn in one figure, stacked
in a single column with a free y-scale per component (facet_wrap on the
component), so each is legible at its own magnitude.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Series or array - like
|
The series. A datetime or period index sets the x-axis; otherwise the observation number is used. Missing values at either end are trimmed; an internal missing value is an error, since dropping it would shift every later observation and misalign the components. |
required |
period
|
int
|
Seasonal period. Inferred from a monthly, quarterly or daily index when omitted (12, 4 and 7 respectively; a daily index is assumed weekly). |
None
|
model
|
('additive', 'multiplicative')
|
The decomposition model. |
"additive"
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> import pandas as pd
>>> rng = np.random.default_rng(0)
>>> t = np.arange(120)
>>> series = pd.Series(
... 50 + 0.3 * t + 10 * np.sin(2 * np.pi * t / 12) + rng.normal(0, 3, 120),
... index=pd.period_range("2016-01", periods=120, freq="M"),
... )
>>> p = dp.decompose_plot(series, period=12)
Source code in src/depictr/timeseries.py
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 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | |
seasonal_plot ¶
seasonal_plot(x, period=None, title=None)
Seasonal subseries plot: value by position in the period, one line per cycle.
Each cycle (for example each year of monthly data) is one line, drawn across the within-period position (month 1 to 12); a trailing incomplete cycle is drawn as the short line it is. Overlaying the cycles makes the repeating shape and any drift between cycles easy to read. The lines take a sequential light-to-dark ramp so they read in time order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Series or array - like
|
The series. Missing values at either end are trimmed; an internal missing value is an error, since dropping it would assign every later observation to the wrong position in the period. |
required |
period
|
int
|
Seasonal period. Inferred from a monthly, quarterly or daily index when omitted (12, 4 and 7 respectively; a daily index is assumed weekly). |
None
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> import pandas as pd
>>> rng = np.random.default_rng(0)
>>> t = np.arange(120)
>>> series = pd.Series(
... 50 + 0.3 * t + 10 * np.sin(2 * np.pi * t / 12) + rng.normal(0, 3, 120),
... index=pd.period_range("2016-01", periods=120, freq="M"),
... )
>>> p = dp.seasonal_plot(series, period=12)
Source code in src/depictr/timeseries.py
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | |
timeseries_plot ¶
timeseries_plot(x, rolling=None, title=None)
The series as a line, optionally with a rolling-mean overlay.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Series or array - like
|
The series. A datetime or period index sets the x-axis; otherwise the observation number is used. |
required |
rolling
|
int
|
Window length for a centred rolling mean, drawn over the series in the accent colour. Omit for the raw line only. |
None
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> import pandas as pd
>>> rng = np.random.default_rng(0)
>>> t = np.arange(120)
>>> series = pd.Series(50 + 0.3 * t + rng.normal(0, 3, 120))
>>> p = dp.timeseries_plot(series, rolling=12)
Source code in src/depictr/timeseries.py
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | |
Estimation and model estimates¶
Estimation plots and summary tables, and the model-estimate family: forests, predicted effects, interactions, random effects, posteriors and power.
These plots are shown, with the code that produced them, on the model estimates and diagnostics page of the gallery.
estimation_plot ¶
estimation_plot(data, y, group, reference=None, conf_level=0.95, n_boot=2000, effsize='hedges_g', two_panel=False, title=None, seed=None)
Cumming-style estimation plot of mean differences.
For each non-reference group, the mean difference from the reference group is
drawn as a point with a bootstrap confidence interval. A dashed line marks a
difference of zero (the reference), and the standardised effect size is
annotated beside each point. With two_panel=True this difference axis sits
beneath a panel of the raw data and group means (the Gardner-Altman layout).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
y
|
str
|
Name of the numeric outcome column. |
required |
group
|
str
|
Name of the grouping column. |
required |
reference
|
str
|
The reference (control) group the others are compared with. Defaults to the first group level. |
None
|
conf_level
|
float
|
Confidence level for the bootstrap difference intervals. |
0.95
|
n_boot
|
int
|
Number of bootstrap resamples for each difference interval. |
2000
|
effsize
|
('hedges_g', 'cohens_d', 'none')
|
Standardised effect size annotated beside each difference. Hedges' g is
the small-sample corrected default; pass |
"hedges_g"
|
two_panel
|
bool
|
When |
False
|
title
|
str
|
Plot title. |
None
|
seed
|
int
|
Seed for the bootstrap, for reproducible intervals. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot or Compose
|
A single panel by default, or a two-panel composition when
|
Examples:
>>> import depictr as dp
>>> cy = dp.crop_yield()
>>> p = dp.estimation_plot(cy, "yield", "treatment", n_boot=200, seed=1)
Source code in src/depictr/estimation.py
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 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | |
summary_table ¶
summary_table(data, vars=None, group=None, digits=1, missing=True, max_levels=20)
Build a "Table 1" descriptive summary.
The first row always reports the sample size (N) overall and per group.
Numeric variables are summarised as mean (SD); categorical variables get one
row per level with count (percent). A Missing, n (%) row follows any
variable that has missing values, unless missing is False.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
The data. |
required |
vars
|
list of str
|
Columns to summarise. If |
None
|
group
|
str
|
A grouping column; one summary column is produced per level, alongside an
overall column. Categorical levels keep their declared category order and
everything else is sorted, so the table does not depend on the row order.
Records whose group value is missing get a |
None
|
digits
|
int
|
Decimal places for the numeric summaries. |
1
|
missing
|
bool
|
Add a |
True
|
max_levels
|
int
|
When |
20
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Columns |
Examples:
>>> import depictr as dp
>>> wb = dp.wellbeing_survey()
>>> tab = dp.summary_table(wb, vars=["life_satisfaction", "stress"], group="region")
>>> tab.columns.tolist()[0]
'variable'
Source code in src/depictr/tables.py
15 16 17 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 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 | |
coefficient_plot ¶
coefficient_plot(model, intercept=False, order='model', conf_level=0.95, title=None)
Forest (dot-and-whisker) plot of model coefficients.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels results object or pandas.DataFrame
|
See :func: |
required |
intercept
|
bool
|
Whether to include the intercept term. |
False
|
order
|
('model', 'ascending', 'descending')
|
Order of the terms up the axis. |
"model"
|
conf_level
|
float
|
Confidence level passed to :func: |
0.95
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph', cy).fit()
>>> p = dp.coefficient_plot(model, title="Drivers of crop yield")
Source code in src/depictr/models.py
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 | |
tidy_estimates ¶
tidy_estimates(model, conf_level=0.95)
Coerce a fitted model or an estimate table into one tidy frame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels results object or pandas.DataFrame
|
A fitted model exposing |
required |
conf_level
|
float
|
Confidence level for the interval when reading it from a model. |
0.95
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Columns |
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph', cy).fit()
>>> dp.tidy_estimates(model).columns.tolist()
['term', 'estimate', 'conf_low', 'conf_high']
Source code in src/depictr/models.py
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 | |
effects_plot ¶
effects_plot(model, var, conf_level=0.95, n=100, title=None)
Predicted response as one predictor varies, with a confidence band.
The predictor var is swept across its observed range while every other
numeric predictor is held at its mean and every categorical at its reference
(most common) level. The line is the predicted response and the ribbon its
confidence band, both read from statsmodels' get_prediction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels results object
|
A fitted OLS/GLM result from a formula and a DataFrame (so the source data is retained for building the grid). |
required |
var
|
str
|
The predictor to vary along the x-axis. Must be a numeric column. |
required |
conf_level
|
float
|
Confidence level for the band. |
0.95
|
n
|
int
|
Number of points across the predictor's range. |
100
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph', cy).fit()
>>> p = dp.effects_plot(model, "fertiliser")
Source code in src/depictr/predictions.py
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 | |
interaction_plot ¶
interaction_plot(model, x, group, conf_level=0.95, n=100, band=True, title=None)
Predicted response across x for each level of a categorical group.
One coloured line per group shows how the predicted response changes with
x within that group, so a fan of non-parallel lines is the visible mark of
an interaction. The remaining predictors are held at their mean (numeric) or
reference level (categorical).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels results object
|
A fitted OLS/GLM result from a formula and a DataFrame. |
required |
x
|
str
|
The numeric predictor on the x-axis. |
required |
group
|
str
|
The categorical predictor whose levels are drawn as separate lines. |
required |
conf_level
|
float
|
Confidence level for the bands. |
0.95
|
n
|
int
|
Number of points across the x range, per group. |
100
|
band
|
bool
|
Whether to draw a confidence ribbon behind each line. |
True
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> model = smf.ols('Q("yield") ~ fertiliser * treatment', cy).fit()
>>> p = dp.interaction_plot(model, "fertiliser", "treatment")
Source code in src/depictr/predictions.py
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 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | |
compare_models ¶
compare_models(models, intercept=False, conf_level=0.95, title=None)
Dodged forest comparing each coefficient across several models.
Each model contributes its estimates and confidence intervals (read with
:func:depictr.models.tidy_estimates, so a fitted model or a tidy frame both
work); the terms share a y-axis and the models are dodged apart and coloured,
so a coefficient that shifts from one specification to the next is easy to
spot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
models
|
dict
|
|
required |
intercept
|
bool
|
Whether to keep the intercept term. |
False
|
conf_level
|
float
|
Confidence level passed to :func: |
0.95
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> reduced = smf.ols('Q("yield") ~ fertiliser', cy).fit()
>>> model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph', cy).fit()
>>> p = dp.compare_models({"Reduced": reduced, "Full": model})
Source code in src/depictr/predictions.py
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | |
random_effects_plot ¶
random_effects_plot(model, title=None)
Caterpillar plot of the predicted random effects (BLUPs).
Each point is one group level's predicted random effect, the deviation of that group from the population fit. Levels are sorted by their effect, so the plot reads as a tilted ladder from the most negative to the most positive group, against a zero reference line. A group whose interval clears zero stands apart from the average; one straddling zero does not.
The points come straight from model.random_effects. When the fit exposes
the conditional covariance of each group's effects
(model.random_effects_cov), the diagonal gives a conditional standard
error and the plot adds a 95% interval (the point estimate plus or minus
1.96 standard errors); without it the points are drawn on their own. If the
model has more than one random-effect term per group (a random intercept and
one or more random slopes), the terms are shown in separate panels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels MixedLMResults
|
A fitted |
required |
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Notes
The interval is the conditional one around each predicted effect, not a confidence interval for a fixed parameter. It reflects how precisely that group's effect is pinned down given the fitted variance components.
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> wb = dp.wellbeing_survey().dropna(subset=["life_satisfaction", "sleep_hours"])
>>> mm = smf.mixedlm("life_satisfaction ~ stress + sleep_hours", wb,
... groups=wb["region"]).fit()
>>> p = dp.random_effects_plot(mm)
Source code in src/depictr/mixed.py
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 | |
posterior_plot ¶
posterior_plot(draws, labels=None, title=None)
Forest plot of posterior (or bootstrap) draws.
Each parameter is one row: the median as a point, a thick inner band for the central 66% credible interval and a thin outer band for the central 95%. The first parameter reads at the top.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
draws
|
pandas.DataFrame or dict of array-like
|
The draws, one column (or dict entry) per parameter. A dict maps a parameter name to a 1-D array of draws; the arrays may differ in length. |
required |
labels
|
dict
|
Remap raw parameter names to display names, |
None
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> draws = {"stress": rng.normal(-0.4, 0.1, 500),
... "sleep_hours": rng.normal(0.3, 0.1, 500)}
>>> p = dp.posterior_plot(draws)
Source code in src/depictr/posterior.py
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 | |
frequentist_bayesian_plot ¶
frequentist_bayesian_plot(frequentist, bayesian, title=None)
Overlay a frequentist estimate against a Bayesian posterior per term.
For each term the two sources share a row, offset slightly so they do not overlap. The frequentist side shows the point estimate with its confidence interval; the Bayesian side shows the posterior median with the inner 66% and outer 95% credible intervals. The sources are told apart by colour (brand blue for frequentist, accent orange for Bayesian).
Only terms present in both sources are drawn. The frequentist confidence
level is whatever :func:depictr.models.tidy_estimates reads from the model
(95% for a fitted statsmodels result), matching the Bayesian outer band.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frequentist
|
statsmodels results object or pandas.DataFrame
|
A fitted model or a tidy estimate frame, as accepted by
:func: |
required |
bayesian
|
pandas.DataFrame or dict of array-like
|
Posterior draws, one column (or dict entry) per term, as accepted by
:func: |
required |
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph', cy).fit()
>>> rng = np.random.default_rng(0)
>>> draws = {t: rng.normal(model.params[t], model.bse[t], 500)
... for t in model.params.index if t != "Intercept"}
>>> p = dp.frequentist_bayesian_plot(model, draws)
Source code in src/depictr/posterior.py
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 228 229 230 231 232 | |
power_curve_plot ¶
power_curve_plot(data, n='n', power='power', group=None, title=None)
Line plot of statistical power against sample size.
Reads a precomputed tidy table and draws power as a function of sample size,
with a dashed reference line at 0.8 (the conventional target). Where the
curve crosses the line is the sample size that reaches adequate power. Pass a
group to overlay one coloured curve per condition (for example several
effect sizes or designs).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
A tidy table with one row per sample size (per group, if grouped). |
required |
n
|
str
|
Name of the sample-size column. |
'n'
|
power
|
str
|
Name of the power column, on the 0-1 scale. |
'power'
|
group
|
str
|
A column mapped to colour, one curve per level. |
None
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
References
Cohen, J. (1988). Statistical power analysis for the behavioral sciences (2nd ed.). Lawrence Erlbaum Associates.
Examples:
>>> import depictr as dp
>>> import pandas as pd
>>> from statsmodels.stats.power import TTestIndPower
>>> analysis = TTestIndPower()
>>> power = pd.DataFrame({"n": range(25, 425, 25)})
>>> power["power"] = [analysis.power(effect_size=0.5, nobs1=n, alpha=0.05)
... for n in power["n"]]
>>> p = dp.power_curve_plot(power)
Source code in src/depictr/power.py
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 | |
Diagnostics¶
Residual and influence diagnostics, and a one-figure model report.
These plots are shown, with the code that produced them, on the model estimates and diagnostics page of the gallery.
qq_plot ¶
qq_plot(model, title=None)
Normal quantile-quantile plot of the residuals, with a reference line.
The sample residual quantiles are plotted against the matching standard-normal
quantiles. Points near the line mean the residuals are close to normal; a
systematic bend away from it flags skew or heavy tails. The line is drawn
through the first and third quartiles, the robust choice R's qqline uses,
so a few outliers do not tilt it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels results object or array-like
|
A fitted OLS/GLM result, from which the internally studentised residuals are read (the raw residuals if studentised ones are not available), or a 1-D array of residuals to plot directly. |
required |
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph', cy).fit()
>>> p = dp.qq_plot(model)
Source code in src/depictr/diagnostics.py
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 | |
influence_plot ¶
influence_plot(model, title=None)
Bubble plot of studentised residuals against leverage.
Each point is one observation; the bubble area is proportional to its Cook's distance, the standard measure of how much the fit would move if the point were dropped (Cook, 1977). Points to the right have high leverage (an unusual predictor combination), points far above or below zero are poorly fitted, and large bubbles are the ones that combine both into real influence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels results object
|
A fitted OLS/GLM result. |
required |
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
References
Cook, R. D. (1977). Detection of influential observation in linear regression. Technometrics, 19(1), 15-18. https://doi.org/10.1080/00401706.1977.10489493
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph', cy).fit()
>>> p = dp.influence_plot(model)
Source code in src/depictr/diagnostics.py
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 | |
vif_plot ¶
vif_plot(model, title=None)
Horizontal bar chart of the variance inflation factor per predictor.
The variance inflation factor (VIF) measures how much a coefficient's variance is inflated by collinearity with the other predictors. A VIF of 1 means no collinearity; the reference line sits at 5, a common threshold above which collinearity is usually treated as a concern. The intercept is dropped, as its VIF is not interpretable in the usual way.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels results object
|
A fitted OLS/GLM result with a design matrix of two or more predictors. |
required |
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph', cy).fit()
>>> p = dp.vif_plot(model)
Source code in src/depictr/diagnostics.py
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 228 229 230 231 232 | |
binned_residual_plot ¶
binned_residual_plot(model, n_bins=None, title=None)
Binned residual plot for a binomial GLM (Gelman & Hill, 2007).
Raw residuals from a logistic model are uninformative point by point, so the fitted probabilities are split into equal-count bins and the mean residual is plotted against the mean fitted value in each bin. The grey band is plus or minus two standard errors of the bin mean; under a well-fitting model about 95% of the points fall inside it. A run of points outside the band, or a clear trend in them, points to a missing predictor or the wrong functional form.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels results object
|
A fitted binomial GLM (logistic regression). |
required |
n_bins
|
int
|
Number of bins. Defaults to the square root of the sample size, rounded, the rule of thumb in Gelman & Hill. |
None
|
title
|
str
|
Plot title. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
References
Gelman, A., & Hill, J. (2007). Data analysis using regression and multilevel/hierarchical models. Cambridge University Press.
Examples:
>>> import depictr as dp
>>> import statsmodels.api as sm
>>> import statsmodels.formula.api as smf
>>> ct = dp.clinical_trial()
>>> glm = smf.glm("adverse_event ~ biomarker + age", ct,
... family=sm.families.Binomial()).fit()
>>> p = dp.binned_residual_plot(glm)
Source code in src/depictr/diagnostics.py
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | |
residual_diagnostics_plot ¶
residual_diagnostics_plot(model, title=None)
Four-panel residual report for a fitted OLS or GLM.
Composes the four checks R draws from plot.lm into a 2x2 grid: residuals
against fitted values, the scale-location plot, a normal quantile-quantile
plot of the residuals, and residuals against leverage. Read together they
cover the usual assumptions of a linear fit: the right functional form,
constant variance, approximately normal residuals, and no single point
dominating the fit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels results object
|
A fitted OLS/GLM result, the kind returned by |
required |
title
|
str
|
Accepted for API symmetry, but dropped with a warning: plotnine compositions cannot carry a figure-level title, so the grid keeps its per-panel titles instead. |
None
|
Returns:
| Type | Description |
|---|---|
Compose
|
A 2x2 composition with |
References
Fox, J., & Weisberg, S. (2019). An R companion to applied regression (3rd ed.). Sage.
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph', cy).fit()
>>> p = dp.residual_diagnostics_plot(model)
Source code in src/depictr/diagnostics_panels.py
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 | |
model_report ¶
model_report(model, title=None)
One-figure dashboard pairing the coefficient plot with key diagnostics.
Puts the three plots a reader usually wants first side by side: the
coefficient (forest) plot of the estimates and their confidence intervals,
the residuals-vs-fitted plot, and the normal quantile-quantile plot. It is a
quick "is the model worth trusting, and what does it say" view, with the full
set of checks left to :func:residual_diagnostics_plot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
statsmodels results object
|
A fitted OLS/GLM result exposing |
required |
title
|
str
|
Accepted for API symmetry, but dropped with a warning: plotnine compositions cannot carry a figure-level title, so the dashboard keeps its per-panel titles instead. |
None
|
Returns:
| Type | Description |
|---|---|
Compose
|
A composition with |
Examples:
>>> import depictr as dp
>>> import statsmodels.formula.api as smf
>>> cy = dp.crop_yield()
>>> model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph', cy).fit()
>>> p = dp.model_report(model)
Source code in src/depictr/diagnostics_panels.py
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 | |
Classification¶
The standard classification curves and tables, computed by scikit-learn and redrawn under the shared theme.
These plots are shown, with the code that produced them, on the classification and survival page of the gallery.
roc_curve_plot ¶
roc_curve_plot(y_true, y_score, title=None)
ROC curve with the area under the curve (AUC) annotated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_true
|
array - like
|
Binary outcomes (0/1). Both classes must be present: with only one, the true or false positive rate has no denominator and the AUC is undefined. |
required |
y_score
|
array - like
|
Predicted scores or probabilities for the positive class. |
required |
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> ct = dp.clinical_trial()
>>> score = 1 / (1 + np.exp(-ct["biomarker"]))
>>> p = dp.roc_curve_plot(ct["adverse_event"], score)
Source code in src/depictr/classification.py
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 | |
pr_curve_plot ¶
pr_curve_plot(y_true, y_score, title=None)
Precision-recall curve with the average precision (AP) annotated.
The dashed horizontal line is the positive rate, the precision a random classifier achieves, which is the baseline a precision-recall curve is read against (unlike a ROC curve, whose baseline is fixed at the diagonal).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_true
|
array - like
|
Binary outcomes (0/1). Both classes must be present: with only one, precision or recall has no denominator and the average precision is undefined. |
required |
y_score
|
array - like
|
Predicted scores or probabilities for the positive class. |
required |
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> ct = dp.clinical_trial()
>>> score = 1 / (1 + np.exp(-ct["biomarker"]))
>>> p = dp.pr_curve_plot(ct["adverse_event"], score)
Source code in src/depictr/classification.py
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 | |
confusion_matrix_plot ¶
confusion_matrix_plot(y_true, y_pred, normalise=None, title=None)
Confusion-matrix heatmap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_true
|
array - like
|
True and predicted labels. |
required |
y_pred
|
array - like
|
True and predicted labels. |
required |
normalise
|
(None, 'true', 'pred', 'all')
|
Passed to scikit-learn's |
None
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> ct = dp.clinical_trial()
>>> score = 1 / (1 + np.exp(-ct["biomarker"]))
>>> p = dp.confusion_matrix_plot(ct["adverse_event"], (score > 0.6).astype(int))
Source code in src/depictr/classification.py
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 | |
calibration_plot ¶
calibration_plot(y_true, y_score, n_bins=10, title=None)
Reliability (calibration) curve of predicted vs observed frequencies.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_true
|
array - like
|
Binary outcomes (0/1). |
required |
y_score
|
array - like
|
Predicted probabilities from a fitted model, on the probability scale. Unlike the ROC and gains charts, which only rank cases, a reliability curve compares the predicted probability with the observed frequency, so an arbitrary monotone score would misstate the calibration. |
required |
n_bins
|
int
|
Number of equal-width bins spanning 0 to 1. Empty bins are dropped, so a rare outcome whose scores never approach 1 leaves fewer points than bins requested. |
10
|
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> from sklearn.linear_model import LogisticRegression
>>> ct = dp.clinical_trial()
>>> X = ct[["biomarker", "age"]]
>>> fit = LogisticRegression().fit(X, ct["adverse_event"])
>>> p = dp.calibration_plot(ct["adverse_event"],
... fit.predict_proba(X)[:, 1], n_bins=5)
Source code in src/depictr/classification.py
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 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | |
gain_plot ¶
gain_plot(y_true, y_score, title=None)
Cumulative gains chart: positives captured as more of the ranked population is targeted.
The population is sorted by y_score, best first, and the curve traces
the share of all positive cases captured by each depth. The dashed diagonal
is random targeting.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_true
|
array - like
|
Binary outcomes (0/1). Both classes must be present: with no positives the share captured has no denominator, and with no negatives every depth captures everything. |
required |
y_score
|
array - like
|
Predicted scores or probabilities for the positive class. Only the ranking matters, so any monotone score works. |
required |
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> ct = dp.clinical_trial()
>>> score = 1 / (1 + np.exp(-ct["biomarker"]))
>>> p = dp.gain_plot(ct["adverse_event"], score)
Source code in src/depictr/classification.py
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | |
lift_plot ¶
lift_plot(y_true, y_score, title=None)
Cumulative lift chart.
Lift is the share of positives captured at a given depth of the score-ordered population, divided by that depth. A lift of 3 in the top 10% means that decile holds three times the baseline positive rate. The dashed line at 1 is random targeting.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_true
|
array - like
|
Binary outcomes (0/1). Both classes must be present: lift is a ratio to the baseline positive rate, which is zero with no positives and one at every depth with no negatives. |
required |
y_score
|
array - like
|
Predicted scores or probabilities for the positive class. Only the ranking matters, so any monotone score works. |
required |
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> ct = dp.clinical_trial()
>>> score = 1 / (1 + np.exp(-ct["biomarker"]))
>>> p = dp.lift_plot(ct["adverse_event"], score)
Source code in src/depictr/classification.py
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | |
threshold_plot ¶
threshold_plot(y_true, y_score, title=None)
Sensitivity, specificity, precision and F1 across the decision threshold.
Sweeps the probability cut-off and plots each metric, so the trade-off when choosing an operating point can be read straight off the curves.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_true
|
array - like
|
Binary outcomes (0/1). Both classes must be present: with only one, sensitivity or specificity has no denominator at any threshold. |
required |
y_score
|
array - like
|
Predicted scores or probabilities for the positive class. |
required |
title
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
ggplot
|
|
Examples:
>>> import depictr as dp
>>> import numpy as np
>>> ct = dp.clinical_trial()
>>> score = 1 / (1 + np.exp(-ct["biomarker"]))
>>> p = dp.threshold_plot(ct["adverse_event"], score)
Source code in src/depictr/classification.py
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | |
Theme, palette and accessibility¶
The shared theme and the colourblind-safe palette, the tools that verify the palette stays distinguishable under colour-vision deficiency, and the audit that checks a finished figure rather than the palette it was built from.
The palette, the colour-vision checks and the figure audit are shown in use on the accessibility page of the gallery.
theme_depictr ¶
theme_depictr(base_size=11, grid='xy')
Return the depictr plotnine theme.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_size
|
float
|
Base font size in points. |
11
|
grid
|
('xy', 'x', 'y', 'none')
|
Which major gridlines to keep. |
"xy"
|
Returns:
| Type | Description |
|---|---|
theme
|
A theme object to add to any plot with |
Examples:
>>> import depictr as dp
>>> ld = dp.lexical_decision()
>>> p = dp.ecdf_plot(ld, "RT") + dp.theme_depictr(base_size=13, grid="y")
Source code in src/depictr/theme.py
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 | |
scale_colour_depictr ¶
scale_colour_depictr(n=None, **kwargs)
A discrete colour scale drawn from :func:depictr.palette.depictr_palette.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
int
|
Number of colours to draw. Defaults to the full qualitative palette;
pass |
None
|
**kwargs
|
Passed to :func: |
{}
|
Examples:
>>> import depictr as dp
>>> from plotnine import aes, geom_point, ggplot
>>> cy = dp.crop_yield()
>>> p = (ggplot(cy, aes("rainfall", "yield", colour="treatment"))
... + geom_point() + dp.scale_colour_depictr())
Source code in src/depictr/theme.py
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 | |
scale_fill_depictr ¶
scale_fill_depictr(n=None, **kwargs)
A discrete fill scale drawn from :func:depictr.palette.depictr_palette.
See :func:scale_colour_depictr for the parameters.
Examples:
>>> import depictr as dp
>>> from plotnine import aes, geom_bar, ggplot
>>> wb = dp.wellbeing_survey()
>>> p = (ggplot(wb, aes("education", fill="region"))
... + geom_bar() + dp.scale_fill_depictr())
Source code in src/depictr/theme.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | |
legend_inside ¶
legend_inside(corner='top right')
Theme fragment that moves the legend into the plotting area.
Places the legend in a corner the plot's geometry usually leaves empty, on
a solid white panel with a light border, so the figure needs no separate
legend column.
The functions that expose a legend_inside argument add this for you.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
corner
|
('top right', 'top left', 'bottom right', 'bottom left')
|
Which corner to use, or an explicit |
"top right"
|
Returns:
| Type | Description |
|---|---|
theme
|
|
Examples:
>>> import depictr as dp
>>> ld = dp.lexical_decision()
>>> p = dp.ecdf_plot(ld, "RT", group="condition") + dp.legend_inside("bottom right")
Source code in src/depictr/theme.py
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 | |
depictr_palette ¶
depictr_palette(n=None, kind='qualitative')
Return a depictr palette.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
int
|
Number of colours to return. For the qualitative palette |
None
|
kind
|
('qualitative', 'sequential', 'diverging')
|
The palette family. |
"qualitative"
|
Returns:
| Type | Description |
|---|---|
list of str
|
Hex colour codes. |
Warns:
| Type | Description |
|---|---|
UserWarning
|
When |
Examples:
>>> import depictr as dp
>>> dp.depictr_palette(3)
['#005b96', '#e69f00', '#009e73']
Source code in src/depictr/palette.py
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 | |
depictr_brand ¶
depictr_brand()
Return the depictr brand colour as a hex string.
Examples:
>>> import depictr as dp
>>> dp.depictr_brand()
'#005b96'
Source code in src/depictr/palette.py
55 56 57 58 59 60 61 62 63 64 | |
depictr_accent ¶
depictr_accent()
Return the depictr accent colour as a hex string.
Examples:
>>> import depictr as dp
>>> dp.depictr_accent()
'#e69f00'
Source code in src/depictr/palette.py
67 68 69 70 71 72 73 74 75 76 | |
check_figure ¶
check_figure(plot, width_cm=17.78, render_width_cm=17.78, min_delta_e=5, min_text_pt=6)
Audit a finished figure for accessibility and honesty.
Checks a figure as it will be submitted, rather than the palette it was
built from. Every row carries the value it measured next to the threshold it
was measured against, so a verdict can be argued with rather than merely
accepted. A check passes when the measured value is at least the threshold.
A check with nothing to measure, such as colour separability on a figure
that encodes nothing by colour, reports NaN and a verdict of
"not applicable" instead of a free pass.
colour_separability is the smallest CIE76 colour difference (Delta-E)
between any two of the figure's encoding colours, and the three
colour_separability_* rows repeat that measurement after simulating each
dichromacy at full severity with :func:depictr.simulate_cvd. Encoding
colours are the distinct colour and fill values a layer uses to tell groups
apart; a continuous colour or fill scale is a smooth ramp rather than a set
of codes, so it is excluded.
greyscale_separability is the smallest difference in CIE lightness
between those same colours, which is what survives printing in black and
white.
text_size is the smallest point size of any text the figure draws, after
scaling by width_cm / render_width_cm: a figure drawn seven inches wide
and printed in an 8.9 cm column has every point size halved. Text drawn
inside the panel, by a layer such as geom_text or by an annotation, is
deliberately left out. It sits on the marks rather than on the background,
so there is no one background to measure its contrast against, and the two
engines size a layer's text in different units, which would leave the check
disagreeing with its R twin on the same figure.
text_contrast and geometry_contrast are the smallest WCAG 2.x
contrast ratios of, respectively, any drawn text against the plot background
and any encoding colour against the panel background.
redundant_encoding counts how many of shape and line type also vary in a
layer whose colour varies. Zero means the distinction between groups is
carried by colour alone, the single most common way an otherwise careful
figure becomes unreadable.
A limitation of the default palette. The eight-colour qualitative
palette clears the colour-separability checks comfortably and fails
greyscale_separability: its orange (#e69f00) and sky blue
(#56b4e9) differ by only 0.79 in lightness, so they print as the same
grey. The colourblind-safety guarantee depictr makes is about hue confusion,
and it was never a claim about greyscale. A figure that may be printed in
black and white should use fewer groups, or a sequential palette, or add a
redundant shape or line type; the four leading colours are not safe in
greyscale either, since the bluish green and the vermillion differ by 3.55.
The threshold has been left where it is rather than moved to let the
package's own defaults through.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plot
|
ggplot
|
A plot, as returned by any depictr plotting function, including one
extended afterwards with |
required |
width_cm
|
float
|
The width, in centimetres, that the figure will occupy in the finished
document. Defaults to 17.78 cm, the seven inches
:func: |
17.78
|
render_width_cm
|
float
|
The width, in centimetres, that the figure is drawn at. Defaults to the same 17.78 cm. The ratio of the two widths is the factor every point size is multiplied by. |
17.78
|
min_delta_e
|
float
|
The smallest acceptable CIE76 colour difference, used for the colour and
greyscale separability checks. Defaults to 5, matching
:func: |
5
|
min_text_pt
|
float
|
The smallest acceptable printed text size, in points. Defaults to 6, a common publisher floor for figure text. |
6
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
One row per check, with columns |
See Also
depictr.palette_safety : the palette in the abstract, rather than a figure.
Examples:
>>> import depictr as dp
>>> from plotnine import aes, geom_point, ggplot, scale_colour_manual
>>> cy = dp.crop_yield()
>>> good = (ggplot(cy, aes("rainfall", "yield", colour="treatment",
... shape="treatment"))
... + geom_point()
... + scale_colour_manual(values=["#005b96", "#d55e00"])
... + dp.theme_depictr())
>>> report = dp.check_figure(good)
>>> set(report["verdict"])
{'pass'}
The same figure destined for an 8.9 cm journal column, where the text is half the size it looks on screen.
>>> shrunk = dp.check_figure(good, width_cm=8.9)
>>> shrunk.loc[shrunk["check"] == "text_size", "verdict"].item()
'fail'
Source code in src/depictr/audit.py
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 | |
palette_safety ¶
palette_safety(colours=None, threshold=5.0)
Check that a palette stays distinguishable under each deficiency.
For normal vision and each deficiency at full severity, the palette's colours
are converted to CIE Lab* and the smallest pairwise colour difference
(CIE76 Delta-E) is found. The lower this minimum, the more likely two
categories are to be confused. A palette is reported safe when the minimum
across all conditions is at least threshold.
The default threshold of 5.0 is calibrated against the reference
colourblind-safe palette: the Okabe-Ito set's tightest pair (reddish-purple
against grey) sits at Delta-E 7.4 under full deuteranopia, so the cut must lie
below that to pass the recommended palette, while still flagging colours that
become near-identical under a deficiency. The difference includes lightness,
which survives colour-vision deficiency, so two colours that share a hue but
differ in lightness are correctly treated as distinguishable. Full severity
is the worst case; most colour-vision deficiency is milder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
colours
|
list of str
|
The palette to test. Defaults to the depictr qualitative palette. Needs at least two colours: a pairwise distance over fewer than two has no value, not an infinitely safe one. |
None
|
threshold
|
float
|
The smallest acceptable Delta-E. |
5.0
|
Returns:
| Type | Description |
|---|---|
dict
|
|
See Also
depictr.check_figure : the same question asked of a finished figure, which uses only as many colours as it has groups and has text and a background besides.
Examples:
>>> import depictr as dp
>>> dp.palette_safety()['safe']
True
Source code in src/depictr/cvd.py
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 | |
simulate_cvd ¶
simulate_cvd(colours, deficiency, severity=1.0)
Simulate how a palette appears under a colour-vision deficiency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
colours
|
list of str
|
Colours (any matplotlib-readable form) to transform. |
required |
deficiency
|
('protan', 'deutan', 'tritan')
|
The deficiency to simulate (red-, green- or blue-weak vision). |
"protan"
|
severity
|
float
|
Severity in [0, 1]; 0 leaves the colours unchanged and 1 is the full deficiency. Intermediate values interpolate the transform towards the identity, an approximation to Machado et al.'s per-severity matrices. |
1.0
|
Returns:
| Type | Description |
|---|---|
list of str
|
The simulated colours as hex strings. |
Examples:
>>> import depictr as dp
>>> dp.simulate_cvd(['#005b96', '#e69f00'], 'deutan')
['#275295', '#cab411']
Source code in src/depictr/cvd.py
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 | |
Composition and data¶
Compose several plots into one figure or save one to disk, and the reproducibly simulated datasets used throughout the documentation.
The datasets are used throughout the gallery, where every figure is drawn from one of them.
arrange_plots ¶
arrange_plots(*plots, ncol=None, nrow=None, title=None)
Arrange several plots into one composed figure.
Builds a grid by joining plots side by side (plotnine's |) into rows of
ncol, then stacking the rows (/). The result is a plotnine
composition, so it still has .draw and .save. This is the building
block behind the multi-panel reports (for example
:func:depictr.diagnostics.residual_diagnostics_plot).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*plots
|
ggplot
|
The plots to arrange. |
()
|
ncol
|
int
|
The grid shape. Give one and the other is derived from the count; give neither and a sensible default is chosen (one column for a single plot, two up to four plots, three beyond). |
None
|
nrow
|
int
|
The grid shape. Give one and the other is derived from the count; give neither and a sensible default is chosen (one column for a single plot, two up to four plots, three beyond). |
None
|
title
|
str
|
A title. Applied only when a single plot is passed: plotnine compositions cannot carry a figure-level title, so for a grid the title is dropped with a warning, and each panel should carry its own. |
None
|
Returns:
| Type | Description |
|---|---|
ggplot or Compose
|
A single plot when one is passed, otherwise a composition. |
Examples:
>>> import depictr as dp
>>> ld = dp.lexical_decision()
>>> left = dp.ecdf_plot(ld, "RT")
>>> right = dp.explore_distribution(ld, "RT")
>>> panel = dp.arrange_plots(left, right, ncol=2)
Source code in src/depictr/compose.py
9 10 11 12 13 14 15 16 17 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 | |
save_plot ¶
save_plot(plot, filename, width=7, height=4.5, dpi=300, units='in', **kwargs)
Save a depictr/plotnine plot at publication resolution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plot
|
ggplot
|
The plot to save. |
required |
filename
|
str
|
Output path; the extension sets the format ( |
required |
width
|
float
|
Figure size, in |
7
|
height
|
float
|
Figure size, in |
7
|
dpi
|
int
|
Dots per inch (300 suits print). |
300
|
units
|
str
|
Size units ( |
'in'
|
**kwargs
|
Passed to :meth: |
{}
|
Returns:
| Type | Description |
|---|---|
str
|
The filename written. |
Examples:
>>> import os, tempfile
>>> import depictr as dp
>>> ld = dp.lexical_decision()
>>> p = dp.ecdf_plot(ld, "RT")
>>> path = dp.save_plot(p, os.path.join(tempfile.mkdtemp(), "rt.png"),
... width=4, height=3, dpi=72)
>>> os.path.exists(path)
True
Source code in src/depictr/compose.py
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 | |
crop_yield ¶
crop_yield(seed=1)
A field trial with a genuine fertiliser-by-treatment interaction.
Examples:
>>> import depictr as dp
>>> dp.crop_yield().shape
(200, 5)
Source code in src/depictr/data.py
17 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 | |
wellbeing_survey ¶
wellbeing_survey(seed=2)
A cross-sectional survey with regional contrasts and informative missingness.
Examples:
>>> import depictr as dp
>>> dp.wellbeing_survey().shape
(300, 7)
Source code in src/depictr/data.py
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 | |
lexical_decision ¶
lexical_decision(seed=3)
A priming reaction-time/accuracy experiment.
Examples:
>>> import depictr as dp
>>> dp.lexical_decision().shape
(600, 5)
Source code in src/depictr/data.py
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 | |
clinical_trial ¶
clinical_trial(seed=4)
A two-arm trial with separating survival curves and a rare adverse event.
Examples:
>>> import depictr as dp
>>> dp.clinical_trial().shape
(300, 6)
Source code in src/depictr/data.py
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 | |
DATASETS
module-attribute
¶
DATASETS = {'crop_yield': crop_yield, 'wellbeing_survey': wellbeing_survey, 'lexical_decision': lexical_decision, 'clinical_trial': clinical_trial}