Skip to main content

Python interface to JAGS for Bayesian analysis via MCMC

Project description

PyJAGS

CI PyPI Python License codecov

PyJAGS provides a Python interface to JAGS (Just Another Gibbs Sampler), a mature engine for Bayesian analysis via Markov Chain Monte Carlo (MCMC) simulation.

Why PyJAGS?

No compilation step. JAGS interprets models at runtime. Change your model code and re-run immediately, with no C++ compiler toolchain required. Even state-of-the-art HMC packages can take 30-60+ seconds to compile each model; JAGS models are ready in milliseconds.

Handles models that gradient-based samplers cannot. JAGS works with non-differentiable likelihoods, discrete parameters, mixture models, and change-point models that challenge HMC/NUTS. No divergence diagnostics to fight.

Incremental sampling is built in. JAGS retains chain state between sample() calls, so extending a run is a single line of code -- a capability that is unique among Python Bayesian packages.

Familiar model syntax. JAGS uses the BUGS language, the lingua franca of Bayesian modeling in the R ecosystem (WinBUGS, OpenBUGS, nimble). R users migrating to Python can use their existing models unchanged.

Lightweight. PyJAGS depends only on numpy, arviz, and h5py. Install with pip install pyjags and pre-built wheels for Linux and macOS.

Features

PyJAGS adds the following features on top of JAGS:

  • Multicore support for parallel simulation of multiple Markov chains
  • Built-in ArviZ integration via pyjags.from_pyjags() for diagnostics and visualization
  • Reproducible sampling via a single seed parameter
  • Generator-based sampling with iter_sample() for live convergence monitoring
  • Standalone model syntax validation with check_model()
  • Incremental sampling with automatic convergence detection (ESS and R-hat criteria)
  • Saving and restoring MCMC sample chains to/from HDF5 files
  • Merging samples along iterations or across chains for resumed sampling
  • PEP 561 py.typed marker for IDE and type checker support

License: GPLv2

Compatibility

Component Supported Versions
Python 3.12+
NumPy 1.x and 2.x
ArviZ 1.0+
macOS Intel and Apple Silicon (M1/M2/M3/M4)
Linux Debian/Ubuntu (tested), other distributions (untested)

Note: Python 3.10 and 3.11 were supported in earlier releases but are no longer supported because ArviZ 1.0 — a core dependency — requires Python 3.12+.

Installation

Prerequisites

A working JAGS installation, a C++ compiler, and CMake are required. PyJAGS uses CMake with pkg-config to locate the JAGS headers and libraries at build time.

macOS

1. Install JAGS via Homebrew

Apple Silicon (M1/M2/M3/M4):

Homebrew installs to /opt/homebrew on Apple Silicon Macs:

# Install Homebrew if needed (https://brew.sh)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Follow Homebrew's instructions to add it to your PATH, then:
brew install jags

Make sure pkg-config can find the JAGS installation by adding this to your shell profile (~/.zprofile or ~/.zshrc):

export PKG_CONFIG_PATH="/opt/homebrew/lib/pkgconfig:$PKG_CONFIG_PATH"

Intel Mac:

Homebrew installs to /usr/local on Intel Macs and pkg-config typically finds JAGS automatically:

brew install jags

2. Set up Python and install PyJAGS

We recommend using uv to manage Python installations and virtual environments:

# Install uv if needed
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install Python 3.12 and create a virtual environment
uv python install 3.12
uv venv --python 3.12 .venv
source .venv/bin/activate

# Install PyJAGS
uv pip install pyjags

To install from source (for development):

source .venv/bin/activate

git clone https://github.com/michaelnowotny/pyjags.git
cd pyjags

uv pip install -e .

Linux

Install JAGS using your distribution's package manager:

# Debian/Ubuntu
sudo apt-get install jags pkg-config

# Fedora/RHEL (untested — package names may differ)
sudo dnf install jags jags-devel pkgconf

Then install PyJAGS:

pip install pyjags

Or from source:

git clone https://github.com/michaelnowotny/pyjags.git
cd pyjags

pip install -e .

Windows

PyJAGS is not natively supported on Windows. Windows users should use WSL2 (Windows Subsystem for Linux) with an Ubuntu distribution, then follow the Linux installation instructions above.

Notebooks

The notebooks/ directory contains Jupyter notebooks demonstrating PyJAGS features:

Notebook Description
Getting Started Beginner-friendly introduction to Bayesian inference with PyJAGS
New in v2.3.0 Showcase of all v2.3.0 features: iter_sample(), seed=, check_model(), and more
Trading Cost Estimation Bayesian estimation of bid-ask spreads using Hasbrouck's model (with and without a market factor)
Logistic Regression Bayesian logistic regression with MCMC diagnostics
Eight Schools Classic hierarchical model with prior/posterior analysis, warmup splitting, and LOO
Advanced Functionality Parallel chains, HDF5 persistence, chain merging, and incremental sampling until convergence

If you have a native installation (macOS or Linux with JAGS and .venv set up as described above), you can run Jupyter Lab directly without Docker:

./scripts/jagslab lab

On first run, this installs notebook dependencies (JupyterLab, seaborn, scikit-learn) into your .venv and registers a "Python 3.12 (pyjags)" Jupyter kernel that points to the correct Python environment. The notebooks are pre-configured to use this kernel.

ArviZ Integration

PyJAGS includes a built-in converter for ArviZ 1.0+. Use pyjags.from_pyjags() to convert sample dictionaries returned by Model.sample() into ArviZ DataTree objects for diagnostics and visualization:

import pyjags
import arviz as az

model = pyjags.Model(code=model_code, data=data, chains=4)
model.sample(1000, vars=[])                     # burn-in
samples = model.sample(5000, vars=['mu', 'sigma'])

idata = pyjags.from_pyjags(samples)             # -> xarray.DataTree
az.summary(idata)
az.plot_trace(idata)

The converter also supports prior samples, log-likelihood extraction, and warmup splitting. See the Eight Schools notebook for a complete example.

Development Environment (jagslab)

PyJAGS also includes a Docker-based development environment managed by the jagslab CLI script. This provides a reproducible setup with JAGS, Python 3.12, and Jupyter Lab without requiring a local JAGS installation.

Quick Start (Docker)

# 1. Copy the environment configuration
cp .env.example .env          # Edit .env to customize (e.g., Jupyter port)

# 2. Build the Docker image
./scripts/jagslab build

# 3. Run the test suite
./scripts/jagslab test

# 4. Start Jupyter Lab
./scripts/jagslab start       # Opens at http://localhost:8888

jagslab Commands

Command Description
start Start Jupyter Lab via Docker (auto-starts container and installs pyjags)
lab Start Jupyter Lab natively from .venv (no Docker required)
stop Stop the Docker container
test [args] Run the test suite
install Install/reinstall pyjags (recompiles C++ extension)
shell Open a bash shell in the container
python [args] Start Python REPL or run a script in the container
build Build the Docker image
rebuild Rebuild image from scratch (no Docker cache)
status Show container status
logs Tail container logs
clean Remove build artifacts
version Show pyjags, JAGS, Python, and numpy versions

Running Tests

./scripts/jagslab test                                           # All tests
./scripts/jagslab test test.test_model                           # One module
./scripts/jagslab test test.test_model.TestModel.test_samples_shape  # Single test

Pre-commit Hooks

PyJAGS uses pre-commit to run ruff linting and formatting checks before each commit, preventing CI failures:

pip install pre-commit
pre-commit install

After installation, ruff will automatically check and fix files in src/ and test/ on every git commit. To run manually against all files:

pre-commit run --all-files

Working with the C++ Extension

PyJAGS includes a C++ extension (src/pyjags/console.cc) that wraps the JAGS library using pybind11. When editing Python files under src/pyjags/, changes take effect immediately thanks to the editable install. However, after editing src/pyjags/console.cc, you must recompile:

./scripts/jagslab install

Configuration

The .env file (created from .env.example) controls environment settings:

  • JAGSLAB_PORT — Host port for Jupyter Lab (default: 8888)

If .env does not exist when you run a jagslab command, it is automatically created from .env.example.

Troubleshooting

macOS: symbol not found '_JAGS_NA' or missing JAGS symbols at runtime

This usually means the compiled extension was not linked against libjags. Verify that pkg-config finds your JAGS installation:

pkg-config --libs --cflags jags

If this fails or points to the wrong location, set PKG_CONFIG_PATH as described in the installation instructions above, then reinstall PyJAGS.

macOS: found architecture 'x86_64', required architecture 'arm64'

This occurs on Apple Silicon Macs when JAGS was installed via an Intel (Rosetta) Homebrew at /usr/local but Python is running natively as ARM64. The fix is to install JAGS using the native ARM Homebrew at /opt/homebrew:

# Check which Homebrew you are using
which brew
# /opt/homebrew/bin/brew  -> ARM (correct for Apple Silicon)
# /usr/local/bin/brew     -> Intel/Rosetta (will cause architecture mismatch)

# If needed, install ARM Homebrew and then:
/opt/homebrew/bin/brew install jags

Make sure PKG_CONFIG_PATH points to the ARM Homebrew pkgconfig directory (/opt/homebrew/lib/pkgconfig) so that the build picks up the correct library.

CMake errors during build

PyJAGS uses CMake (via scikit-build-core) to find and link against JAGS. If the build fails with CMake errors, ensure CMake is installed:

# macOS
brew install cmake

# Debian/Ubuntu
sudo apt-get install cmake

# pip
pip install cmake

Useful Links

Acknowledgements

  • JAGS was created by Martyn Plummer
  • PyJAGS was originally created by Tomasz Miasko
  • As of May 2020, PyJAGS is developed by Michael Nowotny
  • Max Schulist (PR #1) proposed migrating to scikit-build-core, pyproject.toml, and pytest, ideas that inspired the packaging modernization in version 2.1
  • Scout Jarman (PR #2) independently proposed CI/CD workflows, CMake builds, and JAGS install scripts, reinforcing the direction of the modernization effort

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyjags-2.3.1.tar.gz (130.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyjags-2.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (5.8 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

pyjags-2.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (5.7 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

pyjags-2.3.1-cp314-cp314-macosx_15_0_x86_64.whl (167.3 kB view details)

Uploaded CPython 3.14macOS 15.0+ x86-64

pyjags-2.3.1-cp314-cp314-macosx_15_0_arm64.whl (342.6 kB view details)

Uploaded CPython 3.14macOS 15.0+ ARM64

pyjags-2.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (5.8 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

pyjags-2.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (5.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

pyjags-2.3.1-cp313-cp313-macosx_15_0_x86_64.whl (167.1 kB view details)

Uploaded CPython 3.13macOS 15.0+ x86-64

pyjags-2.3.1-cp313-cp313-macosx_15_0_arm64.whl (342.2 kB view details)

Uploaded CPython 3.13macOS 15.0+ ARM64

pyjags-2.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (5.8 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

pyjags-2.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (5.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

pyjags-2.3.1-cp312-cp312-macosx_15_0_x86_64.whl (167.1 kB view details)

Uploaded CPython 3.12macOS 15.0+ x86-64

pyjags-2.3.1-cp312-cp312-macosx_15_0_arm64.whl (342.1 kB view details)

Uploaded CPython 3.12macOS 15.0+ ARM64

File details

Details for the file pyjags-2.3.1.tar.gz.

File metadata

  • Download URL: pyjags-2.3.1.tar.gz
  • Upload date:
  • Size: 130.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyjags-2.3.1.tar.gz
Algorithm Hash digest
SHA256 7b12679d75c1e5ff1508cca1a23a329998e0793263b4e8842300d81f277efafe
MD5 18de027effb8c554979b926fc58b3c47
BLAKE2b-256 60b89f536e1ac6b1eb3fc02e8d2bbb242c794080bd7d27b2d109f15df2bbcec7

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1.tar.gz:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a6b35087952e1643545c0b161ef942e1d7447319976375af5f92fdbe8056a4a0
MD5 8aeb475b45c3885eb12a246eac457f1d
BLAKE2b-256 33de1b10a54e8b5c7cef5e47d6a716a9a25c0c322f27322ff31ae709f97f7a69

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8544b625217d88b1ca85420988b109d2dd9ff9db5ccf450b59d4fd89264e5b91
MD5 c5840475d851170ae7c5d55bd2e9904f
BLAKE2b-256 d41ce3d0b2243fe2f2ce94026fd19deb12c3eac1c6bce2bb7e80bd19da60c1d1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp314-cp314-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp314-cp314-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 49c9b204b9d37421639d22b63ad2cceb12a2389cf29b0fe12260357f9f1c8964
MD5 8bbe74bf566524acc38feeea7d019a04
BLAKE2b-256 0dd3e1a0ccc1a12bed912fb7fb7059dac9b5f002aa49d0b9e5f7775e9e93b92b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp314-cp314-macosx_15_0_x86_64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp314-cp314-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp314-cp314-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 44774a59efb8040f5f3c8a188091c80c697b65b6568f7d0bdbe50d44cc17eca8
MD5 4d73cb638a27edfdcb912a08beeead80
BLAKE2b-256 ddebb94d46472e3a885bc7873d6c32f1d82d0d659324f1cddb351a6e0dce0a3a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp314-cp314-macosx_15_0_arm64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 98765d9f17cde7665aa51009e9bcc4418401f3819c6a96d1bef11d29c4ccb443
MD5 19fa1c598abc2cb1dc371ee3d5175052
BLAKE2b-256 05ea6be532714ede5660768e7d658b14b6eef155b3f1d1cab1981ff8ad67418c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5ac6b96c4d2f2caf952546a6089cab26bdaf8e293ab0c339238e9cdb7dc1dcd2
MD5 918b291cfec4e4f868d7527a190dc301
BLAKE2b-256 ae90b450a71a45d5b82cb0aa3e503cf39623d554e21431eab63021a60645c181

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp313-cp313-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp313-cp313-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 b55da2ab8ed14723e113dd170ec5ecd1d47e9dc0582632c010b83506adaeec66
MD5 aa5d54abb9da7eee78c68eed8e268e67
BLAKE2b-256 2b24dc6331c967c05677724b878a388c488f459b5ccf1056141e7972c8ef52ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp313-cp313-macosx_15_0_x86_64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp313-cp313-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp313-cp313-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 536e3384000f3591b28b3d0de464c4685f99d54bd5bf7dd516f3b8c719d0859f
MD5 40fb06cde83cab3f958538fa0ed83cf8
BLAKE2b-256 e1b20550bd3f8d98d8597545cb7c4e6054351a6035d2a4a98a3c32149125bf67

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp313-cp313-macosx_15_0_arm64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7c1dec2cb937992b2c152df017f411a63bd7a1e51b3921e54be6d7a669b1446c
MD5 814ee65dbe98ce0ef2512ef2481ed48f
BLAKE2b-256 04603b936549db0a9f2c05a4b173d531fabb09601660c36a7898f202c4e403ee

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 cd8286ef45bc41f4e5c0cc6c1ecfb06fec6dd68aa867282fbadfc7bf4cc41379
MD5 1d1e1831d0ac008f47613e7a511d54c1
BLAKE2b-256 db4baffceb4e227df5b069ba6e1d9ee69e094773ba2bca50e45c12f1887294c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp312-cp312-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp312-cp312-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 96b82b7b366147ba38975c51000c9bd2eb34b16bea0633a69a9c8fb5f9de93cf
MD5 840323f1b7130fffd654fbd989199a18
BLAKE2b-256 b2eb2065807292f534581e1db19a5a02f8c5ae014285a15fc316f5c6f3b95476

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp312-cp312-macosx_15_0_x86_64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyjags-2.3.1-cp312-cp312-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for pyjags-2.3.1-cp312-cp312-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 3bb3cefc015bf2abeea93f56879cc1a0829ec936701c5ac09900830314b72d96
MD5 ebf33a4740568670ad5a7f47b58a6b57
BLAKE2b-256 eb76351c51daafe07aad4ea78addcc1543a8ede40ab0eafc89f6e86b3e551e93

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyjags-2.3.1-cp312-cp312-macosx_15_0_arm64.whl:

Publisher: release.yml on michaelnowotny/pyjags

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page