A strip plot displays individual data points for each category along a single axis, with random horizontal jitter applied to reduce overplotting. Unlike box plots or violin plots that show summary statistics, strip plots reveal every observation, making them ideal for small to medium datasets where individual values matter. The random jitter spreads points horizontally within each category to show density through point accumulation.

""" anyplot.ai
strip-basic: Basic Strip Plot
Library: seaborn 0.13.2 | Python 3.13.14
Quality: 91/100 | Updated: 2026-08-05
"""
import os
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
# Theme tokens
THEME = os.getenv("ANYPLOT_THEME", "light")
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
# Imprint palette — canonical order, first series always #009E73
IMPRINT = ["#009E73", "#C475FD", "#4467A3", "#BD8233"]
sns.set_theme(
style="ticks",
rc={
"figure.facecolor": PAGE_BG,
"axes.facecolor": PAGE_BG,
"axes.edgecolor": INK_SOFT,
"axes.labelcolor": INK,
"text.color": INK,
"xtick.color": INK_SOFT,
"ytick.color": INK_SOFT,
"grid.color": INK,
"grid.alpha": 0.15,
"legend.facecolor": ELEVATED_BG,
"legend.edgecolor": INK_SOFT,
},
)
# Data — employee satisfaction scores by department
np.random.seed(42)
departments = ["Engineering", "Marketing", "Sales", "HR"]
records = []
for dept in departments:
if dept == "Engineering":
scores = np.random.normal(78, 8, 35)
elif dept == "Marketing":
scores = np.random.normal(72, 12, 40)
elif dept == "Sales":
scores = np.concatenate([np.random.normal(65, 6, 25), np.random.normal(80, 5, 15)])
else: # HR
scores = np.random.normal(68, 10, 30)
scores = np.clip(scores, 40, 100)
for s in scores:
records.append({"Department": dept, "Satisfaction Score": s})
df = pd.DataFrame(records)
# Plot — see default-style-guide.md "Visual Sizing Defaults" for canvas + sizing values
fig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)
ax.set_facecolor(PAGE_BG)
sns.stripplot(
data=df,
x="Department",
y="Satisfaction Score",
hue="Department",
palette=IMPRINT,
alpha=0.6,
size=6,
jitter=0.3,
edgecolor=PAGE_BG,
linewidth=0.4,
ax=ax,
legend=False,
)
# Group means as diamond markers — seaborn pointplot overlay, no connecting line/error bars
# Background-colored edge stroke keeps the diamond from swallowing points behind it
sns.pointplot(
data=df,
x="Department",
y="Satisfaction Score",
color=INK,
markers="D",
markersize=8,
markeredgecolor=PAGE_BG,
markeredgewidth=1.5,
linestyle="none",
errorbar=None,
ax=ax,
)
# Storytelling touch — faint overall-mean reference line + callout on the top department
group_means = df.groupby("Department")["Satisfaction Score"].mean()
overall_mean = df["Satisfaction Score"].mean()
top_dept = group_means.idxmax()
top_x = departments.index(top_dept)
ax.axhline(overall_mean, color=INK_SOFT, linewidth=0.8, linestyle="--", alpha=0.4, zorder=0)
ax.annotate(
f"{top_dept} leads · {group_means[top_dept]:.0f} avg",
xy=(top_x, group_means[top_dept]),
xytext=(top_x + 0.35, group_means[top_dept] + 12),
fontsize=8,
color=INK_SOFT,
ha="left",
arrowprops={"arrowstyle": "-", "color": INK_SOFT, "linewidth": 0.8, "alpha": 0.6},
)
# Style
ax.set_xlabel("Department", fontsize=10, color=INK)
ax.set_ylabel("Satisfaction Score", fontsize=10, color=INK)
ax.set_title("strip-basic · python · seaborn · anyplot.ai", fontsize=12, fontweight="medium", color=INK)
ax.tick_params(axis="both", labelsize=8, colors=INK_SOFT, length=0)
ax.set_ylim(35, 105)
ax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)
sns.despine(ax=ax)
ax.spines["left"].set_color(INK_SOFT)
ax.spines["bottom"].set_color(INK_SOFT)
# Legend for mean reference marker
ax.plot([], [], marker="D", linestyle="none", color=INK, markersize=8, label="Group Mean")
ax.legend(fontsize=8, loc="upper right", framealpha=1)
# Save — bbox_inches MUST stay default (None); "tight" trims the canvas off-target
plt.tight_layout()
plt.savefig(f"plot-{THEME}.png", dpi=400, facecolor=PAGE_BG)
Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/strip-basic/seaborn/code. Any spec id and library id listed in llms-full.txt fit the same URL shape; every URL below is complete and callable.
{
"spec_id": "strip-basic",
"language": "python",
"library": "seaborn",
"page": "https://anyplot.ai/strip-basic/python/seaborn",
"hub": "https://anyplot.ai/strip-basic",
"code_json": "https://api.anyplot.ai/specs/strip-basic/seaborn/code",
"spec_json": "https://api.anyplot.ai/specs/strip-basic",
"render_light_png": "https://storage.googleapis.com/anyplot-images/plots/strip-basic/python/seaborn/plot-light.png",
"render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/strip-basic/python/seaborn/plot-dark.png",
"quality_score": 91.0,
"license": "MIT",
"guide": "https://anyplot.ai/llms.txt"
}Part of Basic Strip Plot on anyplot.ai.