Plotting: plotly & plotnine

Every plotting function in moderndive takes an engine= argument:

  • engine="plotly" (default) — interactive figures (plotly.graph_objects.Figure).

  • engine="plotnine" — grammar-of-graphics figures (plotnine.ggplot).

The composition syntax is identical across engines, so you can switch a whole analysis by changing one argument.

Note

The figures on this page are static images so they render in the docs. In a notebook or script, the default engine="plotly" produces interactive figures (hover, zoom, pan).

import moderndive as md
from moderndive import (
    specify, observe, get_confidence_interval,
    visualize, shade_confidence_interval, shade_p_value,
)

boot = (
    md.load_almonds_sample_100().specify(response="weight")
    .generate(reps=1000, type="bootstrap", seed=1)
    .calculate(stat="mean")
)
ci = get_confidence_interval(boot, level=0.95, type="percentile")
ci
shape: (1, 2)
lower_ciupper_ci
f64f64
3.6069753.75

visualize() returns an InferPlot

visualize() returns a small InferPlot wrapper that you compose with shading via + in both engines. The underlying figure is on .figure (and, for plotnine, the raw ggplot on .gg).

visualize(boot) + shade_confidence_interval(ci)
../_images/a273216777edd2d44d46c0b5746fe52bdeb43e370fdf9d484e44c44cfd60293e.png
# the same plot via the plotnine engine
visualize(boot, engine="plotnine") + shade_confidence_interval(ci)

Keyword form

If you’d rather not use +, pass the shading inline (handy for plotly):

visualize(boot, shade_ci=ci)
../_images/a273216777edd2d44d46c0b5746fe52bdeb43e370fdf9d484e44c44cfd60293e.png

Shading p-values

spotify = md.load_spotify_metal_deephouse()
obs = observe(spotify, formula="popular_or_not ~ track_genre", success="popular",
              stat="diff in props", order=("metal", "deep-house"))
null = (
    spotify.specify(formula="popular_or_not ~ track_genre", success="popular")
    .hypothesize(null="independence")
    .generate(reps=1000, type="permute", seed=76)
    .calculate(stat="diff in props", order=("metal", "deep-house"))
)
visualize(null) + shade_p_value(obs_stat=obs, direction="right")
../_images/740bf8671170f1b5361f3ad35be67c52f9ce7c9f19b3daff3e4152648e08beb7.png

Simulation vs. theory overlays

visualize(boot, method="theoretical")   # normal-approximation curve
../_images/5a74e8e46e0f37cb65054b705c08dc15f20d50e75b5372736f04007d0f586c35.png
visualize(boot, method="both")          # histogram + curve overlaid
../_images/e5e3f6acb3e6bf251fdeb64b77796ff0342cc41a441cc46196c0a69a12112afd.png

Faceted regression-coefficient plots

visualize_fit shows one panel per term, and shading is per-facet:

from moderndive.infer.viz import visualize_fit

houses = md.load_saratoga_houses()
boot_fit = (
    houses.specify(formula="price ~ living_area + bedrooms")
    .generate(reps=1000, type="bootstrap", seed=1)
    .fit()
)
visualize_fit(boot_fit) + shade_confidence_interval(boot_fit.get_confidence_interval())
../_images/9e52fba067346ffecc1b5b29589de5714f25231d660c4db47a2717e90e2bfcf8.png

Model plots

from moderndive import gg_parallel_slopes

evals = md.load_evals()
gg_parallel_slopes(evals, response="score", explanatory="age", by="gender")
../_images/0ffc2b69d5db1519a915b9481e98ecb7d2cc9ccaa12a5b0098c2761098e977ed.png
from moderndive import gg_categorical_model

gg_categorical_model(evals, response="score", explanatory="rank")
../_images/e1033ced41fd633d891010cfbeb7e94f3e5963b40c701f09b10335574af609c3.png
from moderndive import pairplot

# Scatterplot matrix (~ GGally::ggpairs)
pairplot(md.load_coffee_quality(), columns=["total_cup_points", "aroma", "flavor"])
../_images/1d05ff79bf2202eaec21c4823fcebbdcfae96e81a8a5be3e22d71a0f2a919461.png

Saving figures

p = visualize(boot)            # plotly
p.save("dist.html")            # interactive HTML (no extra deps)
p.save("dist.png")             # static image — needs: pip install "moderndive[image]"

g = visualize(boot, engine="plotnine")
g.save("dist.png", width=6, height=4, dpi=150)

pairplot(..., engine="seaborn") (alias "plotnine") returns a Matplotlib figure if you prefer the seaborn-backed scatterplot matrix.