Box Plot Examples

This example demonstrates box plot functionality in PubliPlots, including simple box plots, grouped box plots, and combined box+swarm plots.

Examples

import publiplots as pp
import pandas as pd
import numpy as np

Simple Box Plot

Basic box plot showing distribution by category.

# Create sample data
np.random.seed(42)
n = 200
box_data = pd.DataFrame({
    'category': np.repeat(['A', 'B', 'C', 'D'], n // 4),
    'value': np.concatenate([
        np.random.normal(10, 2, n // 4),
        np.random.normal(15, 3, n // 4),
        np.random.normal(12, 2.5, n // 4),
        np.random.normal(18, 4, n // 4)
    ])
})

# Create simple box plot
ax = pp.boxplot(
    data=box_data,
    x='category',
    y='value',
    title='Simple Box Plot',
    xlabel='Category',
    ylabel='Value',
)
pp.show()
Simple Box Plot

Box Plot with Hue Grouping

Use the hue parameter to create grouped box plots.

# Add group variable
box_data['group'] = np.tile(['Group 1', 'Group 2'], n // 2)

# Create grouped box plot
ax = pp.boxplot(
    data=box_data,
    x='category',
    y='value',
    hue='group',
    gap=0.1,
    title='Grouped Box Plot',
    xlabel='Category',
    ylabel='Value',
    palette={'Group 1': '#8E8EC1', 'Group 2': '#75B375'},
)
pp.show()
Grouped Box Plot

Horizontal Box Plot

Create horizontal box plots by swapping x and y.

ax = pp.boxplot(
    data=box_data[box_data['group'] == 'Group 1'],
    x='value',
    y='category',
    title='Horizontal Box Plot',
    xlabel='Value',
    ylabel='Category',
)
pp.show()
Horizontal Box Plot

Univariate (1D) Box Plot

Pass only x= or only y= to summarize a single distribution. A constant categorical axis is synthesized internally so all 2D features (hue=, annotate=, alpha, border_radius) remain available. The synthetic axis ticks and spine are hidden so the result reads cleanly as a single-distribution summary. This is the form used by pp.JointGrid.plot_marginals() to put boxes on the marginal panels of a joint plot.

fig, axes = pp.subplots(1, 2, axes_size=(40, 50))
pp.boxplot(data=box_data, y='value', ax=axes[0], title='Vertical (y= only)')
pp.boxplot(data=box_data, x='value', ax=axes[1], title='Horizontal (x= only)')
pp.show()
Vertical (y= only), Horizontal (x= only)

Combined Box and Swarm Plot

Overlay swarm plot on box plot to show both summary statistics and individual data points.

fig, ax = pp.subplots(axes_size=(80, 65))

# First, create the box plot
pp.boxplot(
    data=box_data[box_data['group'] == 'Group 1'],
    x='category',
    y='value',
    ax=ax,
    showfliers=False,
)

# Then overlay the swarm plot
pp.swarmplot(
    data=box_data[box_data['group'] == 'Group 1'],
    x='category',
    y='value',
    ax=ax,
    alpha=1,
    legend=False,
)

ax.set_title('Combined Box and Swarm Plot')
ax.set_xlabel('Category')
ax.set_ylabel('Value')
pp.show()
Combined Box and Swarm Plot

Customization

Box Plot with Custom Alpha

Adjust transparency of box fill.

ax = pp.boxplot(
    data=box_data,
    x='category',
    y='value',
    hue='group',
    gap=0.1,
    title='Box Plot with Custom Alpha',
    xlabel='Category',
    ylabel='Value',
    alpha=0.3,
)
pp.show()
Box Plot with Custom Alpha

Box Plot Without Outliers

Hide outliers when you plan to overlay with swarm plot.

ax = pp.boxplot(
    data=box_data,
    x='category',
    y='value',
    showfliers=False,
    title='Box Plot Without Outliers',
    xlabel='Category',
    ylabel='Value',
)
pp.show()
Box Plot Without Outliers

Annotated box stats

annotate=True labels the median by default. Pass stats=["median", "q1", "q3", ...] to label multiple statistics per box. See the dedicated annotations gallery for the full option set.

ax = pp.boxplot(
    data=box_data,
    x='category', y='value',
    annotate={"stats": ["median", "q1", "q3"], "fmt": ".1f"},
    title="annotate={'stats': ['median', 'q1', 'q3']}",
)
pp.show()
annotate={'stats': ['median', 'q1', 'q3']}

Rounded boxes — border_radius

New in 0.10.6: pp.boxplot(..., border_radius=1.5) rounds all four corners of the IQR box. Units are millimeters (print-consistent, independent of the data-axis range). Pass a 2-tuple to round top and bottom independently — border_radius=(1.5, 0) keeps the Q1 edge square, useful when the box is visually paired with a density cloud (e.g. inside publiplots.raincloudplot()).

fig, axes = pp.subplots(1, 3, axes_size=(35, 35))
pp.boxplot(data=box_data, x='category', y='value',
           ax=axes[0], title='flat (default)')
pp.boxplot(data=box_data, x='category', y='value',
           ax=axes[1], border_radius=1.5, title='symmetric')
pp.boxplot(data=box_data, x='category', y='value',
           ax=axes[2], border_radius=(1.5, 0), title='top only')
pp.show()
flat (default), symmetric, top only

Total running time of the script: (0 minutes 4.616 seconds)

Gallery generated by Sphinx-Gallery