Mixed-type generalized pair plots for Python.
Project description
mixpairs
Mixed-type generalized pair plots for Python. Fast exploratory pair plots for mixed tabular data.
Status: active development. The package is published on PyPI.
Why mixpairs
mixpairs is designed for exploratory analysis where numeric and categorical features appear in the same table. Standard pair plots often focus on continuous variables, while many real workflows in data science and geospatial feature engineering require mixed-type comparisons.
Motivation:
- Provide one consistent pair-plot interface for continuous, categorical, and mixed variable pairs.
- Keep defaults interpretable for rapid feature screening and diagnostics.
- Support publication-ready figure generation with minimal plotting boilerplate.
Methodology:
- Build a grid where each cell selects a renderer based on variable type pairing.
- Use dedicated diagonal summaries and configurable upper/lower triangle renderers.
- Expose a simple API (
ggpairs) with presets and custom renderer hooks for domain-specific adaptation.
Typical use cases:
- Early-stage feature diagnostics before classification/regression modeling.
- Identifying class overlap/separation patterns with
hue. - Comparing relationships across many features with optional subsampling for scalability.
Installation
pip install mixpairs
Quickstart
import numpy as np
import pandas as pd
from mixpairs import ggpairs
rng = np.random.default_rng(42)
df = pd.DataFrame(
{
"x1": rng.normal(0, 1, 300),
"x2": rng.normal(2, 1.5, 300),
"x3": rng.normal(-1, 0.7, 300),
"class": rng.choice(["forest", "crop", "urban"], size=300),
}
)
fig, axes = ggpairs(df, columns=["x1", "x2", "x3", "class"], hue="class", corner=True)
fig.savefig("mixpairs_iris.png", dpi=200, bbox_inches="tight")
Example datasets and plots
The examples/ folder contains reproducible scripts and output figures. Each plot shows how mixpairs.ggpairs handles continuous, categorical, and mixed-variable combinations.
1) Iris baseline (examples/01_basic_iris.py)
What this plot shows:
- Pairwise relationships among classic iris measurements (
sepal_length,sepal_width,petal_length,petal_width). - Diagonal panels show each variable's marginal distribution.
- Off-diagonal panels reveal correlation structure; petal variables are strongly associated, while sepal relationships are weaker.
- Use this example as a clean baseline for continuous-only data.
2) Mixed numeric/categorical tips data (examples/02_mixed_types.py)
What this plot shows:
- A mixed feature set: continuous (
total_bill,tip,size) and categorical (sex,day) withhue="time". - Numeric-numeric panels help compare lunch/dinner tipping behavior through overlap and spread.
- Numeric-categorical panels summarize how bill and tip distributions shift across categories.
- Categorical-categorical panels show co-occurrence counts (for example how
dayandsexcombinations differ by service time).
3) Custom renderer example (examples/03_custom_renderers.py)
What this plot shows:
- The lower triangle uses a custom hexbin renderer, replacing default scatter panels.
- Hexbin density makes structure clearer in dense regions where many points overlap.
- This is useful for larger datasets where point clouds become saturated.
- The example demonstrates the minimal custom renderer contract needed to plug in domain-specific plotting logic.
4) Corner mode with class coloring (examples/04_corner_mode.py)
What this plot shows:
corner=Truedisplays only the lower triangle and diagonal, reducing visual duplication.hue="species"highlights class separation patterns directly in pairwise feature space.- This is a compact option for publication-style layouts or reports where space matters.
- The
minimalpreset keeps styling light while preserving interpretability.
5) Large mixed grid stress test (examples/05_large_grid.py)
What this plot shows:
- Eight continuous variables plus two categorical variables create a high-dimensional mixed grid.
subsample=400keeps render time and visual density manageable while preserving global patterns.hue="cat_b"allows quick comparison between two groups across many variable pairs.- This example demonstrates scalability behavior and practical settings (
height,aspect,subsample) for larger tables.
6) Geospatial workflow (external repository)
Geospatial feature plotting examples will be maintained in a separate repository to keep this package focused.
Planned external integration:
- Repository:
geospatial feature plotting companion repository (link will be added in a later release) - Documentation section:
external geospatial workflow guide (coming soon) - Planned scope: end-to-end geospatial feature engineering and visualization examples built around
mixpairs.
To regenerate all figures:
cd examples
../.venv/bin/python 01_basic_iris.py
../.venv/bin/python 02_mixed_types.py
../.venv/bin/python 03_custom_renderers.py
../.venv/bin/python 04_corner_mode.py
../.venv/bin/python 05_large_grid.py
API
fig, axes = ggpairs(
data,
columns=None,
hue=None,
palette=None,
upper=None,
lower=None,
diag=None,
corner=False,
height=2.0,
aspect=1.0,
cardinality_threshold=15,
column_labels=None,
dtypes=None,
sort_by_type=False,
subsample=None,
dropna_hue=True,
title=None,
legend_position="right",
font_scale=1.0,
preset="default",
**kwargs,
)
Built-in presets
default: corr/scatter + mixed-type defaultsminimal: sparse upper panel + compact stylingkde: density-focused continuous panelsregression: lower panels with trend lines
Custom renderer contract
- Bivariate renderer signature:
fn(ax, data, x_col, y_col, hue_col, palette, orient, **kwargs) - Diagonal renderer signature:
fn(ax, data, col, hue_col, palette, **kwargs)
Use custom renderers by passing callables in upper, lower, or diag.
Notes
- Runtime errors in individual cells are isolated so the full grid can still render.
- If one or more renderers fail,
ggpairsemits a warning and marks failed cells withX.
Inspiration and citation
mixpairs is inspired by the ggpairs concept from R's GGally package and adapts that idea to a Python-first mixed-type workflow.
Reference:
- Schloerke B, Crowley J, Cook D, et al. GGally: Extension to
ggplot2. R package version 2.4.0. https://ggobi.github.io/ggally/
For citing this package, use the metadata in CITATION.cff.
Project files
- License:
LICENSE - Citation metadata:
CITATION.cff - Contribution guide:
CONTRIBUTING.md - Changelog:
CHANGELOG.md
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mixpairs-0.1.3.tar.gz.
File metadata
- Download URL: mixpairs-0.1.3.tar.gz
- Upload date:
- Size: 20.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
768292dca923a5cd95082617b60a03b5c6479891c196e37cd43450e3d621cb52
|
|
| MD5 |
63d0464dd3c23e825e166e5ee16aff5d
|
|
| BLAKE2b-256 |
a6f0344064f15928ab617e1341013d6ab23cfb3f1d183db5317ee3ac82dd8273
|
Provenance
The following attestation bundles were made for mixpairs-0.1.3.tar.gz:
Publisher:
ci.yml on paulhosch/mixpairs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mixpairs-0.1.3.tar.gz -
Subject digest:
768292dca923a5cd95082617b60a03b5c6479891c196e37cd43450e3d621cb52 - Sigstore transparency entry: 1262657723
- Sigstore integration time:
-
Permalink:
paulhosch/mixpairs@9202f1905d4ec83cb8ab09e68285da02cbd2e3ca -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/paulhosch
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@9202f1905d4ec83cb8ab09e68285da02cbd2e3ca -
Trigger Event:
push
-
Statement type:
File details
Details for the file mixpairs-0.1.3-py3-none-any.whl.
File metadata
- Download URL: mixpairs-0.1.3-py3-none-any.whl
- Upload date:
- Size: 16.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63ea70e0629393c02120860a4344ae7f7b89547338f7cebb978eb8ab5f37a089
|
|
| MD5 |
c8f4c0afa9cfc411f9040ba69c5f2328
|
|
| BLAKE2b-256 |
95c9aa7b304c58e4b458490603ca0c14098a4690f2017c78db1d40e38b99e086
|
Provenance
The following attestation bundles were made for mixpairs-0.1.3-py3-none-any.whl:
Publisher:
ci.yml on paulhosch/mixpairs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mixpairs-0.1.3-py3-none-any.whl -
Subject digest:
63ea70e0629393c02120860a4344ae7f7b89547338f7cebb978eb8ab5f37a089 - Sigstore transparency entry: 1262657734
- Sigstore integration time:
-
Permalink:
paulhosch/mixpairs@9202f1905d4ec83cb8ab09e68285da02cbd2e3ca -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/paulhosch
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@9202f1905d4ec83cb8ab09e68285da02cbd2e3ca -
Trigger Event:
push
-
Statement type: