import matplotlib.pyplot as plt
# Just import maidr package: plt.show() now renders accessible output
import maidr Accessible Box, Boxen and Violin Plots in matplotlib and seaborn with py-maidr
A box plot is read as its five-number summary: moving along one box walks the minimum, lower quartile, median, upper quartile and maximum, with outliers announced as their own stops, and moving across the chart switches between the groups being compared. A violin plot combines a density curve with box statistics, so py-maidr exposes it as two layers (switch with Page Up and Page Down): the KDE outline is read as a smooth curve and the inner box as a box plot. A boxen plot extends the box to a ladder of quantile pairs, and each rung is announced as the percentile it actually is.
BOX, VIOLIN_BOX and VIOLIN_KDE are in the stable set. BOXEN is experimental and may change without a deprecation period: see Plot Type Stability.
Setup
Every example on this page needs only the import below. The plot cells repeat it so each one can be copied on its own.
Box Plot
import matplotlib.pyplot as plt
import seaborn as sns
from seaborn import load_dataset
import maidr
# Load the iris dataset
iris = load_dataset("iris")
# Create the horizontal boxplot
fig, ax = plt.subplots()
horz_box_plot = sns.boxplot(x="petal_length", y="species", data=iris, orient="h", ax=ax)
ax.set_ylabel("Species")
ax.set_xlabel("Petal Length (cm)")
ax.set_title("Petal Length by Species from Iris Dataset")
# Add number formatter for better screen reader output
ax.xaxis.set_major_formatter("{x:.1f}")
# Show the plot
plt.show() Boxen Plot (Letter-Value Plot)
This is one of the experimental plot types. It has not been through a user study, and it may change without a deprecation period. See Plot type stability.
import matplotlib.pyplot as plt
import seaborn as sns
from seaborn import load_dataset
import maidr
diamonds = load_dataset("diamonds")
fig, ax = plt.subplots()
sns.boxenplot(data=diamonds, x="cut", y="price", ax=ax)
ax.set_xlabel("Cut")
ax.set_ylabel("Price (USD)")
ax.set_title("Diamond Price by Cut Quality")
plt.show() A boxen plot is a box plot whose tails keep resolving: instead of one quartile box and a cloud of outliers, it draws a ladder of quantile pairs, and a larger sample earns more rungs. maidr announces each rung as the percentile it actually is – “the 12.5th percentile” rather than a rung number – and moving outward from the median walks the ladder in value order. k_depth= controls how deep it goes, and the announcement follows it.
Violin Plot
Seaborn Violin Plot (Horizontal)
import matplotlib.pyplot as plt
import seaborn as sns
import maidr
# Load the diamonds dataset
diamonds = sns.load_dataset("diamonds")
# Create horizontal violin plot comparing price across cut quality
v = sns.violinplot(
x="price", # numeric values on x-axis
y="cut", # 5 categories on y-axis
data=diamonds,
orient="h", # horizontal orientation
inner="box", # show box plot inside violin
hue="cut", # color by cut quality
palette="Set2", # distinct colors
legend=False,
)
# Customize the plot
plt.title("Diamond Price Distribution by Cut Quality")
plt.xlabel("Price (USD)")
plt.ylabel("Cut Quality")
# Add number formatter for better screen reader output
plt.gca().xaxis.set_major_formatter("{x:,.0f}")
# Show the plot
plt.show() Matplotlib Violin Plot
import matplotlib.pyplot as plt
import seaborn as sns
import maidr
# Load dataset
diamonds = sns.load_dataset("diamonds")
# Prepare data grouped by cut (5 categories)
groups = []
values = []
for cut, gdf in diamonds.groupby("cut", observed=False):
groups.append(cut)
values.append(gdf["price"].dropna().values)
fig, ax = plt.subplots(figsize=(10, 6))
# Matplotlib violin plot with mean, median, and extrema
violins = ax.violinplot(
values,
showmeans=True,
showmedians=True,
showextrema=True,
)
# Set x-ticks to match group labels
ax.set_xticks(range(1, len(groups) + 1))
ax.set_xticklabels(groups)
ax.set_title("Diamond Price Distribution by Cut Quality (Matplotlib Violin)")
ax.set_xlabel("Cut Quality")
ax.set_ylabel("Price (USD)")
# Add number formatter for better screen reader output
ax.yaxis.set_major_formatter("{x:,.0f}")
plt.show()