Faceted Plots (Python)

Authors

[Editor] Shixiang Wang;

[Contributors] Claude Code โ€” AI-generated, independently AI-reviewed;

Modified

2026-10-19

๐Ÿค– AI Skill โ€” Download the Bizard unified skill for your AI assistant โฌ‡๏ธ Download Skill ZIP
๐Ÿ”Œ MCP Server โ€” Let AI agents (Claude Code, Cursor, โ€ฆ) query Bizard live: claude mcp add bizard -- npx @openbiox/bizard-mcp โ€” or the free hosted instance (no install, faster from mainland China): claude mcp add --transport http bizard http://biotree.top:38123/bizard-mcp/mcp ๐Ÿ“– MCP Docs
๐Ÿ“– Cite Bizard โ€” if Bizard helps your research, please cite: Li, K., Zheng, H., Huang, K., et al. (2026). Bizard: A Community-Driven Platform for Accelerating and Enhancing Biomedical Data Visualization. iMetaMed, e70038. ๐Ÿ”— DOI / BibTeX

Faceting splits one dataset into a grid of panels by categorical variables, holding every panel on identical axes so differences between groups read as differences in shape, not scale. It replaces the most error-prone figure type in biomedical papers โ€” hand-assembled panel grids. seaborn provides the figure-level functions (relplot, catplot, displot) and the composable FacetGrid.

Example

Setup

  • System Requirements: Cross-platform (Linux/MacOS/Windows)
  • Programming Language: Python
  • Dependencies: matplotlib, seaborn, pandas, numpy
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

Data Preparation

We simulate a longitudinal treatment study in long format โ€” 4 genotypes ร— 2 arms ร— 6 weekly measurements โ€” the shape seabornโ€™s figure-level functions expect (one row per observation).

np.random.seed(201)

genotypes = ['WT', 'HET', 'KO', 'RES']
rows = []
for gi, geno in enumerate(genotypes):
    for arm, rate in [('Vehicle', 0.10), ('Treatment', 0.10 + 0.08 * (3 - gi))]:
        for mouse in range(8):
            for week in range(0, 6):
                rows.append({
                    'Genotype': geno, 'Arm': arm, 'Week': week,
                    'Mouse': f'{geno}_{arm[:2]}_{mouse}',
                    'Score': 1 + 0.35 * (0.10 + 0.08 * (3 - gi)) * week
                             + np.random.normal(0, 0.12)})
long = pd.DataFrame(rows)

Visualization

Relational Facets (relplot)

col lays panels out left-to-right and col_wrap controls the grid; identical y-limits across panels are what make the genotype contrast legitimate.

g = sns.relplot(data=long, x='Week', y='Score', hue='Arm',
                col='Genotype', col_wrap=2,
                kind='line', estimator='mean', errorbar=('ci', 95),
                palette={'Vehicle': '#457b9d', 'Treatment': '#e63946'},
                height=2.6, aspect=1.15, facet_kws=dict(sharey=True))
g.set_titles('{col_name}')
g.set_axis_labels('Week', 'Mean score')
g.legend.set_frame_on(False)
plt.show()
Figureย 1: Response trajectories faceted by genotype, coloured by arm

Categorical Facets (catplot)

catplot swaps the per-panel plot type via kind; box plots per week expose the within-genotype spread that means hide.

g = sns.catplot(data=long[long.Arm == 'Treatment'], x='Week', y='Score',
                col='Genotype', col_wrap=2, kind='box',
                color='#8da0cb', width=0.55, linewidth=0.9,
                height=2.6, aspect=1.15)
g.set_titles('{col_name}')
g.set_axis_labels('Week', 'Score')
plt.show()
Figureย 2: Score distributions by week, faceted by genotype

Custom Panels with FacetGrid

FacetGrid.map_dataframe puts any plotting function in every panel โ€” here the per-genotype score distribution with rugs, the pattern for bespoke panel functions.

def hist_kde(data, color, **kwargs):
    ax = plt.gca()
    sns.histplot(data.Score, kde=True, stat='density',
                 color=color, alpha=0.45, bins=14, ax=ax)
    ax.axvline(data.Score.median(), color='0.25', linewidth=0.9,
               linestyle='--')

g = sns.FacetGrid(long, col='Genotype', col_wrap=2, hue='Genotype',
                  palette='Set2', height=2.6, aspect=1.15)
g.map_dataframe(hist_kde)
g.set_titles('{col_name}')
g.set_axis_labels('Score', 'Density')
plt.show()
Figureย 3: FacetGrid mapping a custom histogram+KDE panel function

References

  1. Waskom, M. L. (2021). seaborn: statistical data visualization. Journal of Open Source Software, 6(60), 3021.
  2. Hunter, J. D. (2007). Matplotlib: A 2D graphics environment. Computing in Science & Engineering, 9(3), 90-95.