Skip to content

Get started

This guide works through a short analysis with depictr, from a first look at the data to a fitted model and its diagnostics. Every function returns a plotnine object, so anything shown here can be refined further with the usual + syntax.

Install

pip install depictr            # core: plotnine, pandas, numpy, matplotlib, scipy
pip install depictr[all]       # plus the optional computation back-ends

The exploratory, theme and accessibility tools work with the core install, and so do the model and time-series plots: they delegate to statsmodels, which plotnine itself requires. The classification and survival plots delegate to scikit-learn and lifelines, each an optional extra (depictr[classification], depictr[survival]). The depictr[models] extra remains to pin the tested statsmodels floor.

The idea

The whole workflow gets one theme, one colourblind-safe palette (the Okabe-Ito set) and one calling convention. Specialist computations stay with the packages that do them well, and each result is redrawn under the shared theme, so a ROC curve, a coefficient plot and a survival curve read as parts of one figure set.

import depictr as dp

Each call returns a plotnine object. In a Jupyter notebook it renders on display. In a script, call .show(), or save it with dp.save_plot(p, "fig.png").

A first look at the data

depictr ships a few reproducibly simulated datasets. Here is a lexical-decision experiment with reaction times in two priming conditions.

ld = dp.lexical_decision()
dp.explore_distribution(ld, "RT", group="condition", kind="density",
                        legend_inside=True)

The legend sits inside the panel, in the corner the distribution leaves empty. For a wider survey, a correlation heatmap and a missing-data map give a quick overview:

wb = dp.wellbeing_survey()
dp.correlation_heatmap(wb)
dp.missingness_map(wb, legend_inside=True)

Fitting and reading a model

depictr does not fit models. It reads a model you have fitted, or a tidy table of estimates. Fit an ordinary least-squares model with statsmodels, then read it from several angles.

import statsmodels.formula.api as smf

cy = dp.crop_yield()
# Q() quotes "yield" because it is a Python keyword.
model = smf.ols('Q("yield") ~ fertiliser + rainfall + soil_ph + treatment',
                cy).fit()

dp.coefficient_plot(model, title="Drivers of crop yield")
dp.effects_plot(model, "fertiliser")
dp.residual_diagnostics_plot(model)

coefficient_plot also accepts a plain data frame of estimates (with columns term, estimate, conf_low, conf_high), so estimates from any source (a Bayesian fit, a bootstrap, a table copied from a paper) plot the same way. tidy_estimates is the shared converter that produces that standard table from any fitted model, and every model-family plot accepts either the model or that table.

dp.tidy_estimates(model)

Survival and classification

These families delegate to lifelines and scikit-learn. Kaplan-Meier curves with a log-rank test and a number-at-risk table are one call:

ct = dp.clinical_trial()
dp.survival_plot(ct["time"], ct["event"], group=ct["arm"],
                 risk_table=True, legend_inside=True)
dp.roc_curve_plot(ct["adverse_event"], ct["biomarker"])

Checking the accessibility claim

The default palette is the Okabe-Ito set, and the claim behind that choice is testable. A simulator of colour-vision deficiency, based on the model of Machado, Oliveira and Fernandes (2009), and a CIE-Lab distance test measure how far apart the palette's colours stay under each form of deficiency.

dp.palette_safety()
# {'min_delta_e': ..., 'safe': True, 'by_condition': {...}, ...}

A safe palette is not a safe figure, though, so check_figure audits a finished plot. It measures how separable the encoding colours are under each dichromacy and in greyscale, how small the text becomes at the width the figure will be printed at, how well text and geometry contrast with their backgrounds under WCAG, and whether any distinction rests on colour alone. Each row reports the value it measured beside the threshold, so a verdict can be argued with.

dp.check_figure(dp.explore_distribution(ld, "RT", group="condition"),
                width_cm=8.9)

The gallery's accessibility page renders both reports in full, and states the one limitation worth knowing: the colourblind-safety guarantee covers hue confusion alone, and two of the palette's colours print as the same grey.

Extending and composing

Because every function returns a plotnine object, the grammar-of-graphics extensions apply:

from plotnine import labs

dp.roc_curve_plot(
    ct["adverse_event"], ct["biomarker"]
) + labs(title="Adverse event")

To place several plots in one figure, use arrange_plots:

dp.arrange_plots(dp.qq_plot(model), dp.influence_plot(model), ncol=2)

theme_depictr, scale_colour_depictr and depictr_palette style your own plots too, so a figure depictr did not draw still matches the set:

from plotnine import ggplot, aes, geom_point

(ggplot(cy, aes("fertiliser", "yield", colour="treatment"))
 + geom_point(alpha=0.7)
 + dp.scale_colour_depictr()
 + dp.theme_depictr())

Where next

The gallery renders a worked example from every family, and the API reference documents each function and its options.