Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/rtd-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Trigger Read the Docs build

# Build the docs on Read the Docs whenever main changes, instead of clicking
# "Build version" by hand. Requires a repo secret READTHEDOCS_TOKEN (create one
# at https://app.readthedocs.org/accounts/tokens/). If you instead connect the
# repo via the Read the Docs GitHub App / incoming webhook, that handles this
# natively and this workflow is unnecessary.
on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
trigger:
runs-on: ubuntu-latest
steps:
- name: Trigger a build of the latest version
env:
RTD_TOKEN: ${{ secrets.READTHEDOCS_TOKEN }}
run: |
if [ -z "$RTD_TOKEN" ]; then
echo "READTHEDOCS_TOKEN secret not set — skipping." && exit 0
fi
curl -fsSL -X POST \
-H "Authorization: Token ${RTD_TOKEN}" \
"https://app.readthedocs.org/api/v3/projects/moderndive/versions/latest/builds/"
51 changes: 34 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
The Python companion package for **ModernDive: Statistical Inference via Data
Science** — a faithful port of the R [`moderndive`](https://moderndive.github.io/moderndive/)
and [`infer`](https://infer.tidymodels.org) packages to a modern Python
data-science stack ([polars](https://pola.rs), [plotnine](https://plotnine.org),
[statsmodels](https://www.statsmodels.org)).
data-science stack ([polars](https://pola.rs), [plotly](https://plotly.com/python/),
[plotnine](https://plotnine.org), [statsmodels](https://www.statsmodels.org)).

📖 **Documentation (with runnable examples): <https://moderndive.readthedocs.io>**

It is intentionally **pure-Python** (no compiled extensions) so it installs under
[Pyodide](https://pyodide.org) via `micropip` for in-browser execution.
Expand All @@ -28,42 +30,57 @@ pip install git+https://github.com/moderndive/moderndive-python

- **A tidy simulation-inference grammar** mirroring R `infer`:
`specify → hypothesize → generate → calculate`, plus `fit()` for multiple
regression, `observe()`, `assume()` (theoretical t/z/F/Chisq), the
visualization layers `visualize` / `shade_p_value` / `shade_confidence_interval`,
and the getters `get_p_value` / `get_confidence_interval` (percentile, SE,
bias-corrected). British-spelling and short aliases are included.
regression, `observe()`, and `assume()` (theoretical t/z/F/Chisq). `specify()`
is also available as a DataFrame method, so you can write
`df.specify(...)` just like R's `df %>% specify(...)`. `calculate(stat=...)`
takes the full infer vocabulary **or any custom callable** test statistic.
Summaries via `get_p_value` / `get_confidence_interval` (percentile, SE,
bias-corrected); British-spelling and short aliases included.
- **Dual-engine plots**: `visualize` / `shade_p_value` / `shade_confidence_interval`
(and every plot helper) take `engine="plotly"` (default, interactive) or
`engine="plotnine"` — same code, your choice of output.
- **Theory-based wrapper tests**: `t_test`, `prop_test`, `chisq_test`,
`t_stat`, `chisq_stat`, plus the `moderndive.theory` module.
- **Regression helpers** mirroring R `moderndive`: `get_regression_table`,
`get_regression_points`, `tidy_summary` (built on `statsmodels`, returning
`polars` frames).
`get_regression_points`, `get_regression_summaries`, `get_correlation`,
`pop_sd`, `tidy_summary` (built on `statsmodels`, returning `polars` frames),
plus the model plots `gg_parallel_slopes` / `geom_parallel_slopes` and
`gg_categorical_model` / `geom_categorical_model`, and `pairplot`
(the `GGally::ggpairs` analog).
- **Sampling**: `rep_slice_sample` / `rep_sample_n` for sampling-distribution
activities.
- **Plots**: `pairplot` (a seaborn scatterplot-matrix, the `GGally::ggpairs` analog).
- **Datasets**: `load_*()` loaders returning `polars` DataFrames (the `nycflights23`,
`gapminder`, `moderndive`, ISLR2, and FiveThirtyEight datasets used in the book).
- **58 datasets**: `load_*()` loaders returning `polars` DataFrames (the
`moderndive`/`infer`, `nycflights23`, `gapminder`, ISLR2, and FiveThirtyEight
datasets used in the book).

## Quick start

```python
import moderndive as md
from moderndive import specify, get_p_value, visualize, shade_p_value
from moderndive import get_p_value, visualize, shade_p_value

spotify = md.load_spotify_metal_deephouse()

# observed difference in popularity rates (metal − deep house)
obs = specify(spotify, formula="popular_or_not ~ track_genre", success="popular") \
# Observed difference in popularity rates (metal − deep house)
obs = (
spotify
.specify(formula="popular_or_not ~ track_genre", success="popular")
.calculate(stat="diff in props", order=("metal", "deep-house"))
)

# permutation null distribution + p-value
# Permutation null distribution
null = (
specify(spotify, formula="popular_or_not ~ track_genre", success="popular")
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"))
)

get_p_value(null, obs_stat=obs, direction="right")
visualize(null, bins=25) + shade_p_value(obs_stat=obs, direction="right")

# Visualize — interactive plotly by default; engine="plotnine" for ggplot-style
visualize(null) + shade_p_value(obs_stat=obs, direction="right")
```

## Development
Expand Down
Binary file modified doc/_build/html/.doctrees/api.doctree
Binary file not shown.
Binary file modified doc/_build/html/.doctrees/coming-from-r.doctree
Binary file not shown.
Binary file modified doc/_build/html/.doctrees/environment.pickle
Binary file not shown.
Binary file modified doc/_build/html/.doctrees/getting-started.doctree
Binary file not shown.
Binary file modified doc/_build/html/.doctrees/guides/confidence-intervals.doctree
Binary file not shown.
Binary file modified doc/_build/html/.doctrees/guides/hypothesis-testing.doctree
Binary file not shown.
Binary file modified doc/_build/html/.doctrees/guides/plotting.doctree
Binary file not shown.
Binary file modified doc/_build/html/.doctrees/guides/regression.doctree
Binary file not shown.
Binary file modified doc/_build/html/.doctrees/guides/theory-based.doctree
Binary file not shown.
Binary file modified doc/_build/html/.doctrees/index.doctree
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion doc/_build/html/_sources/coming-from-r.md.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ pennies %>%
```python
# Python — verbs are methods on the returned objects
(
md.load_pennies().specify(response="year")
md.load_pennies()
.specify(response="year")
.hypothesize(null="point", mu=1995)
.generate(reps=1000, type="bootstrap", seed=1)
.calculate(stat="mean")
Expand Down
5 changes: 4 additions & 1 deletion doc/_build/html/_sources/guides/theory-based.md.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Supported distributions: `"t"`, `"z"`, `"F"` (pass `df=(df1, df2)`), and
curve, or both:

```{code-cell} python
from moderndive import specify, visualize
from moderndive import visualize

boot = (
age.specify(response="age")
Expand All @@ -83,6 +83,9 @@ boot = (
)

visualize(boot, method="both") # histogram + normal-approximation curve
```

```{code-cell} python
visualize(boot, method="theoretical") # just the curve
```

Expand Down
3 changes: 2 additions & 1 deletion doc/_build/html/coming-from-r.html
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ <h2>The infer pipeline<a class="headerlink" href="#the-infer-pipeline" title="Li
</div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Python — verbs are methods on the returned objects</span>
<span class="p">(</span>
<span class="n">md</span><span class="o">.</span><span class="n">load_pennies</span><span class="p">()</span><span class="o">.</span><span class="n">specify</span><span class="p">(</span><span class="n">response</span><span class="o">=</span><span class="s2">&quot;year&quot;</span><span class="p">)</span>
<span class="n">md</span><span class="o">.</span><span class="n">load_pennies</span><span class="p">()</span>
<span class="o">.</span><span class="n">specify</span><span class="p">(</span><span class="n">response</span><span class="o">=</span><span class="s2">&quot;year&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">hypothesize</span><span class="p">(</span><span class="n">null</span><span class="o">=</span><span class="s2">&quot;point&quot;</span><span class="p">,</span> <span class="n">mu</span><span class="o">=</span><span class="mi">1995</span><span class="p">)</span>
<span class="o">.</span><span class="n">generate</span><span class="p">(</span><span class="n">reps</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="s2">&quot;bootstrap&quot;</span><span class="p">,</span> <span class="n">seed</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="o">.</span><span class="n">calculate</span><span class="p">(</span><span class="n">stat</span><span class="o">=</span><span class="s2">&quot;mean&quot;</span><span class="p">)</span>
Expand Down
13 changes: 11 additions & 2 deletions doc/_build/html/guides/theory-based.html
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ <h2>Overlaying theory on a simulation<a class="headerlink" href="#overlaying-the
curve, or both:</p>
<div class="cell docutils container">
<div class="cell_input docutils container">
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">moderndive</span><span class="w"> </span><span class="kn">import</span> <span class="n">specify</span><span class="p">,</span> <span class="n">visualize</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">moderndive</span><span class="w"> </span><span class="kn">import</span> <span class="n">visualize</span>

<span class="n">boot</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">age</span><span class="o">.</span><span class="n">specify</span><span class="p">(</span><span class="n">response</span><span class="o">=</span><span class="s2">&quot;age&quot;</span><span class="p">)</span>
Expand All @@ -338,7 +338,16 @@ <h2>Overlaying theory on a simulation<a class="headerlink" href="#overlaying-the
<span class="p">)</span>

<span class="n">visualize</span><span class="p">(</span><span class="n">boot</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s2">&quot;both&quot;</span><span class="p">)</span> <span class="c1"># histogram + normal-approximation curve</span>
<span class="n">visualize</span><span class="p">(</span><span class="n">boot</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s2">&quot;theoretical&quot;</span><span class="p">)</span> <span class="c1"># just the curve</span>
</pre></div>
</div>
</div>
<div class="cell_output docutils container">
<img alt="../_images/177581b8d9573bde4a4ceaa582de7a5dccf9960de5b0497702711636bef64d2c.png" src="../_images/177581b8d9573bde4a4ceaa582de7a5dccf9960de5b0497702711636bef64d2c.png" />
</div>
</div>
<div class="cell docutils container">
<div class="cell_input docutils container">
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">visualize</span><span class="p">(</span><span class="n">boot</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s2">&quot;theoretical&quot;</span><span class="p">)</span> <span class="c1"># just the curve</span>
</pre></div>
</div>
</div>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions doc/_build/jupyter_execute/datasets.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"cell_type": "code",
"execution_count": 1,
"id": "2483e0f4",
"id": "a9e6fc06",
"metadata": {
"tags": [
"remove-input"
Expand All @@ -19,7 +19,7 @@
},
{
"cell_type": "markdown",
"id": "3a64ee65",
"id": "599ae5ce",
"metadata": {},
"source": [
"# Datasets\n",
Expand All @@ -31,7 +31,7 @@
{
"cell_type": "code",
"execution_count": 2,
"id": "97a618b4",
"id": "c158a621",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -82,7 +82,7 @@
},
{
"cell_type": "markdown",
"id": "90c0500c",
"id": "37ccb1db",
"metadata": {},
"source": [
"## By topic\n",
Expand Down
26 changes: 13 additions & 13 deletions doc/_build/jupyter_execute/getting-started.ipynb

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions doc/_build/jupyter_execute/guides/confidence-intervals.ipynb

Large diffs are not rendered by default.

26 changes: 13 additions & 13 deletions doc/_build/jupyter_execute/guides/hypothesis-testing.ipynb

Large diffs are not rendered by default.

54 changes: 27 additions & 27 deletions doc/_build/jupyter_execute/guides/plotting.ipynb

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions doc/_build/jupyter_execute/guides/regression.ipynb

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions doc/_build/jupyter_execute/guides/sampling.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"cell_type": "code",
"execution_count": 1,
"id": "7048d552",
"id": "7cb7bf25",
"metadata": {
"tags": [
"remove-input"
Expand All @@ -19,7 +19,7 @@
},
{
"cell_type": "markdown",
"id": "2e248f5b",
"id": "9e813f18",
"metadata": {},
"source": [
"# Sampling\n",
Expand All @@ -35,7 +35,7 @@
{
"cell_type": "code",
"execution_count": 2,
"id": "abd5d97e",
"id": "88b6a9f5",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -80,7 +80,7 @@
},
{
"cell_type": "markdown",
"id": "b0fe3200",
"id": "ef68c05a",
"metadata": {},
"source": [
"## One virtual sample"
Expand All @@ -89,7 +89,7 @@
{
"cell_type": "code",
"execution_count": 3,
"id": "44fe2a6a",
"id": "b21cd3e4",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -130,7 +130,7 @@
},
{
"cell_type": "markdown",
"id": "5661f0ec",
"id": "2d908329",
"metadata": {},
"source": [
"## Many samples → a sampling distribution\n",
Expand All @@ -141,7 +141,7 @@
{
"cell_type": "code",
"execution_count": 4,
"id": "133800e3",
"id": "bcd78396",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -189,7 +189,7 @@
},
{
"cell_type": "markdown",
"id": "b1048568",
"id": "ad89bf88",
"metadata": {},
"source": [
"That `prop_red` column is a **sampling distribution**. Visualize its spread the\n",
Expand All @@ -205,7 +205,7 @@
{
"cell_type": "code",
"execution_count": 5,
"id": "7a5431bc",
"id": "1ae71dc6",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -252,7 +252,7 @@
},
{
"cell_type": "markdown",
"id": "cbd208e1",
"id": "a1240287",
"metadata": {},
"source": [
"## Tactile samples\n",
Expand All @@ -263,7 +263,7 @@
{
"cell_type": "code",
"execution_count": 6,
"id": "ba9ee8ab",
"id": "8896d3d2",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -310,7 +310,7 @@
},
{
"cell_type": "markdown",
"id": "ad7a49b7",
"id": "6a782244",
"metadata": {},
"source": [
"```{seealso}\n",
Expand Down
86 changes: 66 additions & 20 deletions doc/_build/jupyter_execute/guides/theory-based.ipynb

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions doc/_build/jupyter_execute/index.ipynb

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion doc/coming-from-r.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ pennies %>%
```python
# Python — verbs are methods on the returned objects
(
md.load_pennies().specify(response="year")
md.load_pennies()
.specify(response="year")
.hypothesize(null="point", mu=1995)
.generate(reps=1000, type="bootstrap", seed=1)
.calculate(stat="mean")
Expand Down
5 changes: 4 additions & 1 deletion doc/guides/theory-based.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Supported distributions: `"t"`, `"z"`, `"F"` (pass `df=(df1, df2)`), and
curve, or both:

```{code-cell} python
from moderndive import specify, visualize
from moderndive import visualize

boot = (
age.specify(response="age")
Expand All @@ -83,6 +83,9 @@ boot = (
)

visualize(boot, method="both") # histogram + normal-approximation curve
```

```{code-cell} python
visualize(boot, method="theoretical") # just the curve
```

Expand Down