diff --git a/doc/_build/html/.doctrees/api.doctree b/doc/_build/html/.doctrees/api.doctree index 3ccb919..64d997a 100644 Binary files a/doc/_build/html/.doctrees/api.doctree and b/doc/_build/html/.doctrees/api.doctree differ diff --git a/doc/_build/html/.doctrees/environment.pickle b/doc/_build/html/.doctrees/environment.pickle index 06556a5..981c093 100644 Binary files a/doc/_build/html/.doctrees/environment.pickle and b/doc/_build/html/.doctrees/environment.pickle differ diff --git a/doc/_build/html/_modules/moderndive/infer/core.html b/doc/_build/html/_modules/moderndive/infer/core.html index 8170b7c..f1820d0 100644 --- a/doc/_build/html/_modules/moderndive/infer/core.html +++ b/doc/_build/html/_modules/moderndive/infer/core.html @@ -684,10 +684,14 @@
return get_fit_p_value(self, obs_stat=obs_stat, direction=direction)
- def visualize(self, bins: int = 20, *, engine: str = "plotly"):
+ def visualize(
+ self, bins: int = 20, *, engine: str = "plotly", shade_pvalue=None, shade_ci=None
+ ):
from .viz import visualize_fit
- return visualize_fit(self, bins=bins, engine=engine)
@dataclass(frozen=True)
class ShadeSpec:
- """Engine-neutral description of a shading layer (p-value tail or CI)."""
+ """Engine-neutral description of a shading layer (p-value tail or CI).
+
+ For a single-panel plot the scalar fields are used. For a faceted
+ regression-fit plot (:func:`visualize_fit`), ``per_term`` holds one value per
+ term so each facet is shaded independently — a tuple of ``(term, payload)``
+ pairs where ``payload`` is the observed statistic (p-value) or a
+ ``(lower, upper)`` pair (confidence interval).
+ """
kind: str # "p_value" | "confidence_interval"
obs_stat: float | None = None
@@ -281,6 +288,7 @@ Source code for moderndive.infer.viz
lower: float | None = None
upper: float | None = None
color: str | None = None
+ per_term: tuple | None = None
class InferPlot:
@@ -291,11 +299,15 @@ Source code for moderndive.infer.viz
raw ``ggplot`` is also available via :attr:`gg`.
"""
- def __init__(self, figure, engine: str):
+ def __init__(self, figure, engine: str, terms: list[str] | None = None):
self.figure = figure
self.engine = engine
+ # Facet terms for a regression-fit plot (enables per-facet shading).
+ self.terms = terms
def __add__(self, other):
+ if isinstance(other, ShadeSpec) and other.per_term is not None:
+ return self._add_per_facet(other)
if self.engine == "plotnine":
from . import _plotnine as P
@@ -305,19 +317,36 @@ Source code for moderndive.infer.viz
if other.kind == "p_value"
else P.shade_ci_layers(other)
)
- return InferPlot(self.figure + layers, "plotnine")
+ return InferPlot(self.figure + layers, "plotnine", self.terms)
# Any other plotnine object/layer/list.
- return InferPlot(self.figure + other, "plotnine")
+ return InferPlot(self.figure + other, "plotnine", self.terms)
from . import _plotly as PX
if isinstance(other, ShadeSpec):
- return InferPlot(PX.apply_shade_px(self.figure, other), "plotly")
+ return InferPlot(PX.apply_shade_px(self.figure, other), "plotly", self.terms)
raise TypeError(
"Only a ShadeSpec (from shade_p_value/shade_confidence_interval) can be "
"added to a plotly InferPlot."
)
+ def _add_per_facet(self, spec: ShadeSpec):
+ """Apply per-term shading to a faceted regression-fit plot (both engines)."""
+ if self.terms is None:
+ raise TypeError(
+ "Per-term shading requires a faceted fit plot from visualize_fit(); "
+ "pass a per-term obs_stat/endpoints (a FitResult or a term-keyed table)."
+ )
+ if self.engine == "plotnine":
+ from . import _plotnine as P
+
+ return InferPlot(
+ P.apply_fit_shade_gg(self.figure, spec, self.terms), "plotnine", self.terms
+ )
+ from . import _plotly as PX
+
+ return InferPlot(PX.apply_fit_shade_px(self.figure, spec, self.terms), "plotly", self.terms)
+
@property
def gg(self):
"""The underlying plotnine ``ggplot`` (only when ``engine='plotnine'``)."""
@@ -341,6 +370,23 @@ Source code for moderndive.infer.viz
return self.figure.write_html(path_str)
return self.figure.write_image(path_str)
+ def _repr_mimebundle_(self, include=None, exclude=None):
+ """Rich display for Jupyter/Quarto across both engines.
+
+ Both plotnine ``ggplot`` and plotly ``Figure`` expose
+ ``_repr_mimebundle_``, so we delegate to it and the wrapped figure renders
+ exactly as a bare figure would. We fall back to ``text/html`` and finally
+ to no output. This is required because ``_repr_html_`` alone returns
+ ``None`` for a ``ggplot`` — without this method, plotnine-engine
+ ``InferPlot``s render blank in notebooks and Quarto.
+ """
+ fig = self.figure
+ if hasattr(fig, "_repr_mimebundle_"):
+ return fig._repr_mimebundle_(include=include, exclude=exclude)
+ if hasattr(fig, "_repr_html_"):
+ return {"text/html": fig._repr_html_()}
+ return None
+
def _repr_html_(self):
fig = self.figure
return fig._repr_html_() if hasattr(fig, "_repr_html_") else None
@@ -402,16 +448,32 @@ Source code for moderndive.infer.viz
-def visualize_fit(fit, bins: int = 20, *, engine: str = "plotly") -> InferPlot:
- """Faceted histogram of a regression fit distribution, one panel per term."""
+def visualize_fit(
+ fit, bins: int = 20, *, engine: str = "plotly", shade_pvalue=None, shade_ci=None
+) -> InferPlot:
+ """Faceted histogram of a regression fit distribution, one panel per term.
+
+ Pass ``shade_pvalue=``/``shade_ci=`` to shade each facet from per-term values
+ (a ``FitResult`` of observed estimates, or a term-keyed CI/p-value table), or
+ compose the same per-term :class:`ShadeSpec` with ``+``.
+ """
engine = C.resolve_engine(engine)
+ terms = fit.data["term"].unique(maintain_order=True).to_list()
if engine == "plotnine":
from . import _plotnine as P
- return InferPlot(P.visualize_fit_gg(fit, bins), engine)
- from . import _plotly as PX
+ fig = P.visualize_fit_gg(fit, bins)
+ else:
+ from . import _plotly as PX
+
+ fig = PX.visualize_fit_px(fit, bins)
- return InferPlot(PX.visualize_fit_px(fit, bins), engine)
+ plot = InferPlot(fig, engine, terms)
+ if shade_pvalue is not None:
+ plot = plot + _coerce_pvalue_spec(shade_pvalue)
+ if shade_ci is not None:
+ plot = plot + _coerce_ci_spec(shade_ci)
+ return plot
def visualize_theoretical(theoretical, bins: int = 100, *, engine: str = "plotly") -> InferPlot:
@@ -431,16 +493,52 @@ Source code for moderndive.infer.viz
return InferPlot(PX.density_curve_px(x, density, title), engine)
+def _per_term_obs(obs_stat) -> dict | None:
+ """Extract a ``{term: observed}`` mapping for per-facet p-value shading.
+
+ Accepts an observed ``FitResult`` (term/estimate), a term-keyed polars frame
+ (``term`` + ``estimate`` or ``stat``), or a dict. Returns ``None`` for a scalar.
+ """
+ import polars as pl
+
+ if isinstance(obs_stat, pl.DataFrame) and "term" in obs_stat.columns:
+ valcol = "estimate" if "estimate" in obs_stat.columns else "stat"
+ return {r["term"]: float(r[valcol]) for r in obs_stat.iter_rows(named=True)}
+ data = getattr(obs_stat, "data", None)
+ if isinstance(data, pl.DataFrame) and {"term", "estimate"} <= set(data.columns):
+ return {r["term"]: float(r["estimate"]) for r in data.iter_rows(named=True)}
+ if isinstance(obs_stat, dict):
+ return {k: float(v) for k, v in obs_stat.items()}
+ return None
+
+
+def _per_term_ci(endpoints) -> dict | None:
+ """Extract a ``{term: (lower, upper)}`` mapping for per-facet CI shading."""
+ import polars as pl
+
+ if isinstance(endpoints, pl.DataFrame) and "term" in endpoints.columns:
+ return {
+ r["term"]: (float(r["lower_ci"]), float(r["upper_ci"]))
+ for r in endpoints.iter_rows(named=True)
+ }
+ return None
+
+
[docs]
def shade_p_value(obs_stat, direction: str, *, color: str | None = None) -> ShadeSpec:
"""A p-value shading spec; add it to a ``visualize()`` plot with ``+``.
- ``direction`` ∈ {right/greater, left/less, two-sided}.
+ ``direction`` ∈ {right/greater, left/less, two-sided}. For a faceted
+ :func:`visualize_fit` plot, pass a per-term ``obs_stat`` — an observed
+ ``FitResult``, a ``term``-keyed frame, or a dict — to shade each facet.
"""
- return ShadeSpec(
- kind="p_value", obs_stat=float(obs_stat), direction=direction, color=color
- )
+ per = _per_term_obs(obs_stat)
+ if per is not None:
+ return ShadeSpec(
+ kind="p_value", direction=direction, color=color, per_term=tuple(sorted(per.items()))
+ )
+ return ShadeSpec(kind="p_value", obs_stat=float(obs_stat), direction=direction, color=color)
@@ -449,8 +547,15 @@ Source code for moderndive.infer.viz
def shade_confidence_interval(endpoints, color: str | None = None) -> ShadeSpec:
"""A confidence-interval shading spec; add it to a ``visualize()`` plot with ``+``.
- ``endpoints`` is a CI DataFrame (``lower_ci``/``upper_ci``) or a ``(lower, upper)`` tuple.
+ ``endpoints`` is a CI DataFrame (``lower_ci``/``upper_ci``) or a ``(lower, upper)``
+ tuple. For a faceted :func:`visualize_fit` plot, pass a per-term CI table (with a
+ ``term`` column) to shade each facet from its own interval.
"""
+ per = _per_term_ci(endpoints)
+ if per is not None:
+ return ShadeSpec(
+ kind="confidence_interval", color=color, per_term=tuple(sorted(per.items()))
+ )
lower, upper = C.ci_endpoints(endpoints)
return ShadeSpec(kind="confidence_interval", lower=lower, upper=upper, color=color)
diff --git a/doc/_build/html/_static/moderndive-logo.png b/doc/_build/html/_static/moderndive-logo.png
index 4c9ae70..1c6c251 100644
Binary files a/doc/_build/html/_static/moderndive-logo.png and b/doc/_build/html/_static/moderndive-logo.png differ
diff --git a/doc/_build/html/api.html b/doc/_build/html/api.html
index ceb0340..753f6b6 100644
--- a/doc/_build/html/api.html
+++ b/doc/_build/html/api.html
@@ -587,7 +587,9 @@ Getters and visualization
moderndive.shade_p_value(obs_stat, direction, *, color=None)[source]¶
A p-value shading spec; add it to a visualize() plot with +.
-direction ∈ {right/greater, left/less, two-sided}.
+direction ∈ {right/greater, left/less, two-sided}. For a faceted
+visualize_fit() plot, pass a per-term obs_stat — an observed
+FitResult, a term-keyed frame, or a dict — to shade each facet.
- Return type:
ShadeSpec
@@ -605,7 +607,9 @@ Getters and visualization
moderndive.shade_confidence_interval(endpoints, color=None)[source]¶
A confidence-interval shading spec; add it to a visualize() plot with +.
-endpoints is a CI DataFrame (lower_ci/upper_ci) or a (lower, upper) tuple.
+endpoints is a CI DataFrame (lower_ci/upper_ci) or a (lower, upper)
+tuple. For a faceted visualize_fit() plot, pass a per-term CI table (with a
+term column) to shade each facet from its own interval.
- Return type:
ShadeSpec
diff --git a/doc/_build/html/searchindex.js b/doc/_build/html/searchindex.js
index b0f25d3..3ba6519 100644
--- a/doc/_build/html/searchindex.js
+++ b/doc/_build/html/searchindex.js
@@ -1 +1 @@
-Search.setIndex({"alltitles":{"API reference":[[0,null]],"Contents":[[1,null]],"Datasets":[[0,"datasets"]],"Getters and visualization":[[0,"getters-and-visualization"]],"Inference grammar":[[0,"inference-grammar"]],"Installation":[[1,"installation"]],"Quick start":[[1,"quick-start"]],"Regression helpers":[[0,"regression-helpers"]],"Sampling and plots":[[0,"sampling-and-plots"]],"Theory-based tests":[[0,"theory-based-tests"]],"moderndive (Python)":[[1,null]]},"docnames":["api","index"],"envversion":{"sphinx":66,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,"sphinx.ext.viewcode":1},"filenames":["api.md","index.md"],"indexentries":{},"objects":{"moderndive":[[0,0,1,"","assume"],[0,0,1,"","chisq_stat"],[0,0,1,"","chisq_test"],[0,0,1,"","geom_parallel_slopes"],[0,0,1,"","get_confidence_interval"],[0,0,1,"","get_correlation"],[0,0,1,"","get_p_value"],[0,0,1,"","get_regression_points"],[0,0,1,"","get_regression_summaries"],[0,0,1,"","get_regression_table"],[0,0,1,"","gg_categorical_model"],[0,0,1,"","gg_parallel_slopes"],[0,0,1,"","load_dataset"],[0,0,1,"","observe"],[0,0,1,"","pairplot"],[0,0,1,"","pop_sd"],[0,0,1,"","prop_test"],[0,0,1,"","rep_sample_n"],[0,0,1,"","rep_slice_sample"],[0,0,1,"","shade_confidence_interval"],[0,0,1,"","shade_p_value"],[0,0,1,"","specify"],[0,0,1,"","t_stat"],[0,0,1,"","t_test"],[0,3,0,"-","theory"],[0,0,1,"","tidy_summary"],[0,0,1,"","visualize"]],"moderndive.data":[[0,0,1,"","available_datasets"]],"moderndive.infer.core":[[0,1,1,"","Distribution"],[0,1,1,"","FitResult"],[0,1,1,"","GeneratedReplicates"],[0,1,1,"","Hypothesis"],[0,1,1,"","Specification"]],"moderndive.infer.core.GeneratedReplicates":[[0,2,1,"","fit"]],"moderndive.infer.core.Hypothesis":[[0,2,1,"","calculate"]],"moderndive.infer.core.Specification":[[0,2,1,"","assume"],[0,2,1,"","calculate"],[0,2,1,"","fit"]],"moderndive.infer.theoretical":[[0,1,1,"","TheoreticalDistribution"]],"moderndive.infer.theoretical.TheoreticalDistribution":[[0,2,1,"","get_p_value"],[0,2,1,"","visualize"]],"moderndive.theory":[[0,0,1,"","prop_test_two_sample"],[0,0,1,"","t_confidence_interval"],[0,0,1,"","t_test_one_sample"],[0,0,1,"","t_test_two_sample"]]},"objnames":{"0":["py","function","Python function"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","module","Python module"]},"objtypes":{"0":"py:function","1":"py:class","2":"py:method","3":"py:module"},"terms":{"1f77b4":[],"A":0,"All":0,"Each":0,"The":[0,1],"These":0,"_hat":0,"accept":0,"across":0,"add":0,"adj_r_squar":0,"alia":0,"also":0,"altern":0,"analog":0,"ani":0,"api":1,"approxim":0,"argument":0,"array":0,"assum":0,"augment":0,"available_dataset":0,"b":0,"back":0,"backend":0,"base":1,"befor":0,"belong":0,"bin":0,"book":0,"bool":0,"bootstrap":0,"broom":0,"c":0,"calcul":[0,1],"call":0,"can":0,"cap":0,"categor":0,"categori":0,"chapter":0,"chi":0,"chisq":0,"chisq_stat":0,"chisq_test":0,"chosen":0,"ci":0,"cis":0,"class":0,"coeffici":0,"color":0,"column":0,"common":0,"companion":[0,1],"comparison":0,"compos":0,"comput":0,"conf_level":0,"confid":0,"conveni":0,"convent":0,"cor":0,"core":0,"correl":0,"curv":0,"data":[0,1],"datafram":0,"dataset":1,"deep":1,"default":0,"degre":0,"deliber":0,"denomin":0,"densiti":0,"deviat":0,"df":0,"df1":0,"df2":0,"diagon":[],"diff":1,"differ":0,"digit":0,"direct":[0,1],"display":[],"distribut":0,"divid":0,"draw":0,"drawn":0,"drop":0,"e":0,"either":0,"endpoint":0,"engin":0,"equal":0,"equal_var":0,"equival":0,"error":0,"estim":0,"explanatori":0,"express":0,"f":0,"faith":1,"fals":0,"field":0,"figur":0,"first":0,"fit":0,"fitresult":0,"five":0,"float":0,"form":0,"formula":[0,1],"frame":0,"freedom":0,"full":[0,1],"func":0,"function":0,"g":0,"generat":1,"generatedrepl":0,"geom_categorical_model":0,"geom_parallel_slop":0,"get":0,"get_confidence_interv":0,"get_correl":0,"get_p_valu":[0,1],"get_regression_point":0,"get_regression_summari":0,"get_regression_t":0,"getter":1,"gg_categorical_model":0,"gg_parallel_slop":0,"ggalli":0,"ggpair":0,"ggplot":0,"go":0,"grammar":1,"greater":0,"group":0,"h0":0,"helper":1,"histogram":0,"hold":0,"horizont":0,"hous":1,"hue":0,"hyp_mu":0,"hyp_p":0,"hyp_sigma":0,"hypothes":[0,1],"hypothesi":0,"id":0,"identifi":0,"import":1,"independ":[0,1],"indic":0,"infer":1,"inferplot":0,"int":0,"intercept":0,"interval":0,"jitter":0,"keyword":0,"kwarg":0,"layer":0,"layout":0,"lead":0,"least":0,"left":0,"less":0,"level":0,"line":0,"list":0,"load":0,"load_":0,"load_dataset":0,"load_spotify_metal_deephous":1,"loadabl":0,"loader":0,"long":0,"lower":0,"lower_ci":0,"mark":[],"marker":0,"match":0,"materi":0,"matplotlib":0,"matrix":0,"max":0,"may":[],"md":1,"mean":0,"median":0,"metal":1,"method":0,"min":0,"mirror":0,"model":0,"modern":1,"modernd":0,"mse":0,"mu":0,"multi":0,"n":0,"name":0,"nan":0,"ndarray":0,"need":0,"nob":0,"non":0,"none":0,"normal":0,"notebook":[],"null":[0,1],"number":0,"numer":0,"numpi":0,"ob":1,"object":0,"obs_stat":[0,1],"observ":0,"observedstatist":0,"ol":0,"older":0,"one":0,"onli":0,"option":0,"order":[0,1],"ordinari":0,"output":0,"overal":0,"overlaid":0,"p":0,"p_valu":0,"packag":[0,1],"pair":0,"pairgrid":[],"pairplot":0,"pairwis":[],"parallel":0,"paramet":0,"pass":0,"pearson":0,"per":0,"percentil":0,"permut":[0,1],"pip":1,"plan":0,"plot":1,"plotnin":[0,1],"point":0,"point_estim":0,"polar":[0,1],"pop_sd":0,"popul":0,"popular":[0,1],"popular_or_not":[0,1],"port":1,"posit":0,"predictor":0,"prop":1,"prop_test":0,"prop_test_two_sampl":0,"proport":0,"provid":0,"q1":0,"q3":0,"quantil":0,"quarto":[],"r":[0,1],"r_squar":0,"refer":1,"regress":1,"rep":[0,1],"rep_sample_n":0,"rep_slice_sampl":0,"replac":0,"replic":0,"report":0,"reproduc":0,"requir":0,"resampl":0,"residu":0,"respons":0,"result":0,"return":0,"right":[0,1],"rmse":0,"row":0,"s":0,"sampl":1,"scalar":0,"scatter_matrix":0,"scatterplot":0,"scienc":1,"scipi":0,"sd":0,"se":0,"seaborn":0,"see":[0,1],"seed":[0,1],"select":0,"separ":0,"sequenc":0,"seri":0,"set":0,"shade":0,"shade_ci":0,"shade_confidence_interv":0,"shade_p_valu":[0,1],"shade_pvalu":0,"shadespec":0,"shifted_respons":0,"shortcut":0,"shuffl":0,"side":0,"sigma":0,"simul":0,"sinc":0,"singl":0,"size":0,"slope":0,"small":0,"smaller":0,"sort":0,"sourc":0,"spec":0,"specif":0,"specifi":[0,1],"splom":0,"spotifi":1,"sqrt":0,"squar":0,"stack":1,"standard":0,"stat":[0,1],"statist":[0,1],"statsmodel":[0,1],"std_error":0,"str":0,"string":0,"style":0,"success":[0,1],"summari":0,"support":0,"t":0,"t_confidence_interv":0,"t_stat":0,"t_test":0,"t_test_one_sampl":0,"t_test_two_sampl":0,"tabl":0,"tail":0,"take":0,"teach":0,"term":0,"test":1,"theoret":0,"theoreticaldistribut":0,"theori":1,"tidi":0,"tidy_summari":0,"tie":0,"total":0,"track_genr":[0,1],"tradit":0,"true":0,"tupl":0,"twice":0,"two":0,"type":[0,1],"unit":0,"unus":0,"upper":0,"upper_ci":0,"use":0,"valu":0,"variabl":0,"version":0,"via":[0,1],"visual":1,"vs":0,"weight":0,"welch":0,"wrapper":0,"x":0,"y":0,"z":0},"titles":["API reference","moderndive (Python)"],"titleterms":{"api":0,"base":0,"content":1,"dataset":0,"getter":0,"grammar":0,"helper":0,"infer":0,"instal":1,"modernd":1,"plot":0,"python":1,"quick":1,"refer":0,"regress":0,"sampl":0,"start":1,"test":0,"theori":0,"visual":0}})
\ No newline at end of file
+Search.setIndex({"alltitles":{"API reference":[[0,null]],"Contents":[[1,null]],"Datasets":[[0,"datasets"]],"Getters and visualization":[[0,"getters-and-visualization"]],"Inference grammar":[[0,"inference-grammar"]],"Installation":[[1,"installation"]],"Quick start":[[1,"quick-start"]],"Regression helpers":[[0,"regression-helpers"]],"Sampling and plots":[[0,"sampling-and-plots"]],"Theory-based tests":[[0,"theory-based-tests"]],"moderndive (Python)":[[1,null]]},"docnames":["api","index"],"envversion":{"sphinx":66,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,"sphinx.ext.viewcode":1},"filenames":["api.md","index.md"],"indexentries":{"assume() (in module moderndive)":[[0,"moderndive.assume",false]],"assume() (moderndive.infer.core.specification method)":[[0,"moderndive.infer.core.Specification.assume",false]],"available_datasets() (in module moderndive.data)":[[0,"moderndive.data.available_datasets",false]],"calculate() (moderndive.infer.core.hypothesis method)":[[0,"moderndive.infer.core.Hypothesis.calculate",false]],"calculate() (moderndive.infer.core.specification method)":[[0,"moderndive.infer.core.Specification.calculate",false]],"chisq_stat() (in module moderndive)":[[0,"moderndive.chisq_stat",false]],"chisq_test() (in module moderndive)":[[0,"moderndive.chisq_test",false]],"distribution (class in moderndive.infer.core)":[[0,"moderndive.infer.core.Distribution",false]],"fit() (moderndive.infer.core.generatedreplicates method)":[[0,"moderndive.infer.core.GeneratedReplicates.fit",false]],"fit() (moderndive.infer.core.specification method)":[[0,"moderndive.infer.core.Specification.fit",false]],"fitresult (class in moderndive.infer.core)":[[0,"moderndive.infer.core.FitResult",false]],"generatedreplicates (class in moderndive.infer.core)":[[0,"moderndive.infer.core.GeneratedReplicates",false]],"geom_parallel_slopes() (in module moderndive)":[[0,"moderndive.geom_parallel_slopes",false]],"get_confidence_interval() (in module moderndive)":[[0,"moderndive.get_confidence_interval",false]],"get_correlation() (in module moderndive)":[[0,"moderndive.get_correlation",false]],"get_p_value() (in module moderndive)":[[0,"moderndive.get_p_value",false]],"get_p_value() (moderndive.infer.theoretical.theoreticaldistribution method)":[[0,"moderndive.infer.theoretical.TheoreticalDistribution.get_p_value",false]],"get_regression_points() (in module moderndive)":[[0,"moderndive.get_regression_points",false]],"get_regression_summaries() (in module moderndive)":[[0,"moderndive.get_regression_summaries",false]],"get_regression_table() (in module moderndive)":[[0,"moderndive.get_regression_table",false]],"gg_categorical_model() (in module moderndive)":[[0,"moderndive.gg_categorical_model",false]],"gg_parallel_slopes() (in module moderndive)":[[0,"moderndive.gg_parallel_slopes",false]],"hypothesis (class in moderndive.infer.core)":[[0,"moderndive.infer.core.Hypothesis",false]],"load_dataset() (in module moderndive)":[[0,"moderndive.load_dataset",false]],"moderndive.theory":[[0,"module-moderndive.theory",false]],"module":[[0,"module-moderndive.theory",false]],"observe() (in module moderndive)":[[0,"moderndive.observe",false]],"pairplot() (in module moderndive)":[[0,"moderndive.pairplot",false]],"pop_sd() (in module moderndive)":[[0,"moderndive.pop_sd",false]],"prop_test() (in module moderndive)":[[0,"moderndive.prop_test",false]],"prop_test_two_sample() (in module moderndive.theory)":[[0,"moderndive.theory.prop_test_two_sample",false]],"rep_sample_n() (in module moderndive)":[[0,"moderndive.rep_sample_n",false]],"rep_slice_sample() (in module moderndive)":[[0,"moderndive.rep_slice_sample",false]],"shade_confidence_interval() (in module moderndive)":[[0,"moderndive.shade_confidence_interval",false]],"shade_p_value() (in module moderndive)":[[0,"moderndive.shade_p_value",false]],"specification (class in moderndive.infer.core)":[[0,"moderndive.infer.core.Specification",false]],"specify() (in module moderndive)":[[0,"moderndive.specify",false]],"t_confidence_interval() (in module moderndive.theory)":[[0,"moderndive.theory.t_confidence_interval",false]],"t_stat() (in module moderndive)":[[0,"moderndive.t_stat",false]],"t_test() (in module moderndive)":[[0,"moderndive.t_test",false]],"t_test_one_sample() (in module moderndive.theory)":[[0,"moderndive.theory.t_test_one_sample",false]],"t_test_two_sample() (in module moderndive.theory)":[[0,"moderndive.theory.t_test_two_sample",false]],"theoreticaldistribution (class in moderndive.infer.theoretical)":[[0,"moderndive.infer.theoretical.TheoreticalDistribution",false]],"tidy_summary() (in module moderndive)":[[0,"moderndive.tidy_summary",false]],"visualize() (in module moderndive)":[[0,"moderndive.visualize",false]],"visualize() (moderndive.infer.theoretical.theoreticaldistribution method)":[[0,"moderndive.infer.theoretical.TheoreticalDistribution.visualize",false]]},"objects":{"moderndive":[[0,0,1,"","assume"],[0,0,1,"","chisq_stat"],[0,0,1,"","chisq_test"],[0,0,1,"","geom_parallel_slopes"],[0,0,1,"","get_confidence_interval"],[0,0,1,"","get_correlation"],[0,0,1,"","get_p_value"],[0,0,1,"","get_regression_points"],[0,0,1,"","get_regression_summaries"],[0,0,1,"","get_regression_table"],[0,0,1,"","gg_categorical_model"],[0,0,1,"","gg_parallel_slopes"],[0,0,1,"","load_dataset"],[0,0,1,"","observe"],[0,0,1,"","pairplot"],[0,0,1,"","pop_sd"],[0,0,1,"","prop_test"],[0,0,1,"","rep_sample_n"],[0,0,1,"","rep_slice_sample"],[0,0,1,"","shade_confidence_interval"],[0,0,1,"","shade_p_value"],[0,0,1,"","specify"],[0,0,1,"","t_stat"],[0,0,1,"","t_test"],[0,3,0,"-","theory"],[0,0,1,"","tidy_summary"],[0,0,1,"","visualize"]],"moderndive.data":[[0,0,1,"","available_datasets"]],"moderndive.infer.core":[[0,1,1,"","Distribution"],[0,1,1,"","FitResult"],[0,1,1,"","GeneratedReplicates"],[0,1,1,"","Hypothesis"],[0,1,1,"","Specification"]],"moderndive.infer.core.GeneratedReplicates":[[0,2,1,"","fit"]],"moderndive.infer.core.Hypothesis":[[0,2,1,"","calculate"]],"moderndive.infer.core.Specification":[[0,2,1,"","assume"],[0,2,1,"","calculate"],[0,2,1,"","fit"]],"moderndive.infer.theoretical":[[0,1,1,"","TheoreticalDistribution"]],"moderndive.infer.theoretical.TheoreticalDistribution":[[0,2,1,"","get_p_value"],[0,2,1,"","visualize"]],"moderndive.theory":[[0,0,1,"","prop_test_two_sample"],[0,0,1,"","t_confidence_interval"],[0,0,1,"","t_test_one_sample"],[0,0,1,"","t_test_two_sample"]]},"objnames":{"0":["py","function","Python function"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","module","Python module"]},"objtypes":{"0":"py:function","1":"py:class","2":"py:method","3":"py:module"},"terms":{"1f77b4":[],"A":0,"All":0,"Each":0,"For":0,"The":[0,1],"These":0,"_hat":0,"accept":0,"across":0,"add":0,"adj_r_squar":0,"alia":0,"also":0,"altern":0,"analog":0,"ani":0,"api":1,"approxim":0,"argument":0,"array":0,"assum":0,"augment":0,"available_dataset":0,"b":0,"back":0,"backend":0,"base":1,"befor":0,"belong":0,"bin":0,"book":0,"bool":0,"bootstrap":0,"broom":0,"c":0,"calcul":[0,1],"call":0,"can":0,"cap":0,"categor":0,"categori":0,"chapter":0,"chi":0,"chisq":0,"chisq_stat":0,"chisq_test":0,"chosen":0,"ci":0,"cis":0,"class":0,"coeffici":0,"color":0,"column":0,"common":0,"companion":[0,1],"comparison":0,"compos":0,"comput":0,"conf_level":0,"confid":0,"conveni":0,"convent":0,"cor":0,"core":0,"correl":0,"curv":0,"data":[0,1],"datafram":0,"dataset":1,"deep":1,"default":0,"degre":0,"deliber":0,"denomin":0,"densiti":0,"deviat":0,"df":0,"df1":0,"df2":0,"diagon":[],"dict":0,"diff":1,"differ":0,"digit":0,"direct":[0,1],"display":[],"distribut":0,"divid":0,"draw":0,"drawn":0,"drop":0,"e":0,"either":0,"endpoint":0,"engin":0,"equal":0,"equal_var":0,"equival":0,"error":0,"estim":0,"explanatori":0,"express":0,"f":0,"facet":0,"faith":1,"fals":0,"field":0,"figur":0,"first":0,"fit":0,"fitresult":0,"five":0,"float":0,"form":0,"formula":[0,1],"frame":0,"freedom":0,"full":[0,1],"func":0,"function":0,"g":0,"generat":1,"generatedrepl":0,"geom_categorical_model":0,"geom_parallel_slop":0,"get":0,"get_confidence_interv":0,"get_correl":0,"get_p_valu":[0,1],"get_regression_point":0,"get_regression_summari":0,"get_regression_t":0,"getter":1,"gg_categorical_model":0,"gg_parallel_slop":0,"ggalli":0,"ggpair":0,"ggplot":0,"go":0,"grammar":1,"greater":0,"group":0,"h0":0,"helper":1,"histogram":0,"hold":0,"horizont":0,"hous":1,"hue":0,"hyp_mu":0,"hyp_p":0,"hyp_sigma":0,"hypothes":[0,1],"hypothesi":0,"id":0,"identifi":0,"import":1,"independ":[0,1],"indic":0,"infer":1,"inferplot":0,"int":0,"intercept":0,"interval":0,"jitter":0,"key":0,"keyword":0,"kwarg":0,"layer":0,"layout":0,"lead":0,"least":0,"left":0,"less":0,"level":0,"line":0,"list":0,"load":0,"load_":0,"load_dataset":0,"load_spotify_metal_deephous":1,"loadabl":0,"loader":0,"long":0,"lower":0,"lower_ci":0,"mark":[],"marker":0,"match":0,"materi":0,"matplotlib":0,"matrix":0,"max":0,"may":[],"md":1,"mean":0,"median":0,"metal":1,"method":0,"min":0,"mirror":0,"model":0,"modern":1,"modernd":0,"mse":0,"mu":0,"multi":0,"n":0,"name":0,"nan":0,"ndarray":0,"need":0,"nob":0,"non":0,"none":0,"normal":0,"notebook":[],"null":[0,1],"number":0,"numer":0,"numpi":0,"ob":1,"object":0,"obs_stat":[0,1],"observ":0,"observedstatist":0,"ol":0,"older":0,"one":0,"onli":0,"option":0,"order":[0,1],"ordinari":0,"output":0,"overal":0,"overlaid":0,"p":0,"p_valu":0,"packag":[0,1],"pair":0,"pairgrid":[],"pairplot":0,"pairwis":[],"parallel":0,"paramet":0,"pass":0,"pearson":0,"per":0,"percentil":0,"permut":[0,1],"pip":1,"plan":0,"plot":1,"plotnin":[0,1],"point":0,"point_estim":0,"polar":[0,1],"pop_sd":0,"popul":0,"popular":[0,1],"popular_or_not":[0,1],"port":1,"posit":0,"predictor":0,"prop":1,"prop_test":0,"prop_test_two_sampl":0,"proport":0,"provid":0,"q1":0,"q3":0,"quantil":0,"quarto":[],"r":[0,1],"r_squar":0,"refer":1,"regress":1,"rep":[0,1],"rep_sample_n":0,"rep_slice_sampl":0,"replac":0,"replic":0,"report":0,"reproduc":0,"requir":0,"resampl":0,"residu":0,"respons":0,"result":0,"return":0,"right":[0,1],"rmse":0,"row":0,"s":0,"sampl":1,"scalar":0,"scatter_matrix":0,"scatterplot":0,"scienc":1,"scipi":0,"sd":0,"se":0,"seaborn":0,"see":[0,1],"seed":[0,1],"select":0,"separ":0,"sequenc":0,"seri":0,"set":0,"shade":0,"shade_ci":0,"shade_confidence_interv":0,"shade_p_valu":[0,1],"shade_pvalu":0,"shadespec":0,"shifted_respons":0,"shortcut":0,"shuffl":0,"side":0,"sigma":0,"simul":0,"sinc":0,"singl":0,"size":0,"slope":0,"small":0,"smaller":0,"sort":0,"sourc":0,"spec":0,"specif":0,"specifi":[0,1],"splom":0,"spotifi":1,"sqrt":0,"squar":0,"stack":1,"standard":0,"stat":[0,1],"statist":[0,1],"statsmodel":[0,1],"std_error":0,"str":0,"string":0,"style":0,"success":[0,1],"summari":0,"support":0,"t":0,"t_confidence_interv":0,"t_stat":0,"t_test":0,"t_test_one_sampl":0,"t_test_two_sampl":0,"tabl":0,"tail":0,"take":0,"teach":0,"term":0,"test":1,"theoret":0,"theoreticaldistribut":0,"theori":1,"tidi":0,"tidy_summari":0,"tie":0,"total":0,"track_genr":[0,1],"tradit":0,"true":0,"tupl":0,"twice":0,"two":0,"type":[0,1],"unit":0,"unus":0,"upper":0,"upper_ci":0,"use":0,"valu":0,"variabl":0,"version":0,"via":[0,1],"visual":1,"visualize_fit":0,"vs":0,"weight":0,"welch":0,"wrapper":0,"x":0,"y":0,"z":0},"titles":["API reference","moderndive (Python)"],"titleterms":{"api":0,"base":0,"content":1,"dataset":0,"getter":0,"grammar":0,"helper":0,"infer":0,"instal":1,"modernd":1,"plot":0,"python":1,"quick":1,"refer":0,"regress":0,"sampl":0,"start":1,"test":0,"theori":0,"visual":0}})
\ No newline at end of file
diff --git a/doc/_static/moderndive-logo.png b/doc/_static/moderndive-logo.png
index 4c9ae70..1c6c251 100644
Binary files a/doc/_static/moderndive-logo.png and b/doc/_static/moderndive-logo.png differ
diff --git a/pyproject.toml b/pyproject.toml
index 7c0fcad..02b5686 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,7 +1,7 @@
[project]
name = "moderndive"
version = "0.1.0"
-description = "Python companion for ModernDive: a tidy simulation-inference grammar, regression helpers, and datasets"
+description = "Python companion for ModernDive: a tidy simulation-inference grammar, regression helpers, datasets, and dual-engine plotly/plotnine plots"
readme = "README.md"
requires-python = ">=3.11"
license = { text = "MIT" }