By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
(For Data Scientists Who Need to Visualize Data Fast—Without the Theory Overload)
You’re a data scientist at a startup, and your PM just dropped a last-minute request: "We need to compare user engagement across three A/B test groups by tomorrow. Show distributions, outliers, and correlations—visually, not in a spreadsheet."
You could: - Waste 2 hours tweaking matplotlib to make a half-decent plot.- Use Seaborn and generate publication-ready statistical graphics in 5 lines of code.
matplotlib
Seaborn is Python’s batteries-included statistical visualization library. It sits on top of matplotlib but handles: - Automatic statistical aggregation (e.g., KDE smoothing, confidence intervals).- Built-in themes (no more plt.rcParams hacking).- Complex plots in one line (e.g., sns.pairplot(df) for a full correlation matrix).
plt.rcParams
sns.pairplot(df)
Why this matters in production:- Faster iteration: Stakeholders don’t care about your figsize tweaks—they care about insights. Seaborn lets you explore data visually in seconds.- Reproducibility: No more "How did you make that plot?" Slap sns.set_theme() at the top of your notebook, and every plot looks consistent.- Statistical rigor: Seaborn’s defaults (e.g., confidence intervals in barplot, KDE in distplot) prevent misleading visualizations (unlike Excel’s "trendline" nonsense).
figsize
sns.set_theme()
barplot
distplot
Real-world scenario:You’re analyzing customer churn. Your boss asks: "Are high-spending users leaving because of long support wait times?" With Seaborn, you can: 1. Plot a boxplot of wait times by churn status.2. Overlay a distplot to see the full distribution.3. Use a heatmap to check correlations between spend, wait time, and churn.All in 10 lines of code.
histplot
kdeplot
boxplot
heatmap
annot=True
pairplot
df.shape[0] > 10k
hue
style
FacetGrid
context="talk"
plt.style.use()
palette
"viridis"
"pastel"
sns.color_palette("colorblind")
ci
ci=None
seaborn
pandas
bash pip install seaborn pandas matplotlib
import seaborn as sns import pandas as pd import numpy as np # Generate synthetic A/B test data np.random.seed(42) n_users = 1000 df = pd.DataFrame({ "group": np.random.choice(["A", "B", "C"], size=n_users), "engagement": np.concatenate([ np.random.normal(50, 10, n_users//3), # Group A np.random.normal(60, 15, n_users//3), # Group B np.random.normal(45, 8, n_users//3) # Group C ]), "spend": np.concatenate([ np.random.exponential(50, n_users//3), np.random.exponential(70, n_users//3), np.random.exponential(30, n_users//3) ]), "churn": np.random.binomial(1, 0.2, size=n_users) # 20% churn rate }) # Set Seaborn theme (do this ONCE at the top of your notebook) sns.set_theme( context="talk", # Larger fonts for presentations style="whitegrid", # Clean gridlines palette="colorblind", # Accessible colors font_scale=1.2 # Bigger text )
Verify:
df.head()
Output:
group engagement spend churn 0 C 44.32156 12.345678 0 1 A 52.12345 45.678901 1 2 B 63.45678 89.012345 0
Goal: See how engagement scores differ across groups.
# Replace deprecated distplot with histplot + kdeplot sns.histplot( data=df, x="engagement", hue="group", kde=True, # Add KDE line element="step", # Cleaner histogram edges stat="density", # Normalize to compare shapes common_norm=False # Normalize each group separately )
Output: (Group B has higher engagement, but Group C has a tighter distribution.)
Production insight:- KDE smoothing helps spot bimodal distributions (e.g., two user segments).- common_norm=False prevents larger groups from dominating the plot.
common_norm=False
Goal: Identify extreme values in engagement and spend.
# Boxplot for engagement by group sns.boxplot( data=df, x="group", y="engagement", hue="churn", # Split by churn status showfliers=True, # Show outliers fliersize=5 # Bigger outlier dots )
Output: (Group B has more high-engagement users, but also more outliers. Churners have lower engagement.)
Production insight:- Outliers ≠ bad data. Check if they’re: - Errors (e.g., negative spend). - Edge cases (e.g., VIP users).- hue="churn" reveals that churners cluster in the lower quartiles.
hue="churn"
Goal: Check if engagement and spend are related.
# Compute correlations corr = df[["engagement", "spend"]].corr() # Heatmap with annotations sns.heatmap( corr, annot=True, # Show values cmap="coolwarm", # Red = negative, blue = positive vmin=-1, vmax=1, # Fix color scale linewidths=0.5 # Add gridlines )
Output: (Engagement and spend are weakly correlated (0.12).)
Production insight:- annot=True is critical—stakeholders won’t guess values from colors.- vmin/vmax ensures consistent color scales across plots.
vmin/vmax
Goal: Explore all numeric relationships at once.
# Sample data if >10k rows (pairplot is slow) sample_df = df.sample(500, random_state=42) if len(df) > 1000 else df sns.pairplot( sample_df, hue="group", # Color by group corner=True, # Show only lower triangle (avoid redundancy) diag_kind="kde", # KDE on diagonal plot_kws={"alpha": 0.6} # Transparency for overlapping points )
Output: (Group B has higher spend and engagement, but no clear linear relationship.)
Production insight:- corner=True saves space by removing duplicate plots.- Sample your data—pairplot is O(n²) and will crash on large datasets.
corner=True
df.sample(1000)
scatterplot
sns.relplot
kde=False
palette="colorblind"
sns.color_palette("viridis")
sns.color_palette("Set2")
plt.savefig("plot.png", dpi=300, bbox_inches="tight")
random_state
df.sample(1000, random_state=42)
plt.xlabel("Engagement Score (0-100)")
plt.title("A/B Test: Engagement by Group")
sns.catplot
AttributeError: module 'seaborn' has no attribute 'distplot'
sns.histplot(data=df, x="col", kde=True)
alpha=0.5
sns.kdeplot
hue_order=["Control", "Variant"]
stat="density"
df[df["engagement"] > 100]
sns.heatmap(..., vmin=-1, vmax=1)
relplot
"colorblind"
plt.title("My Title")
hue="group", style="churn"
violinplot
vmin
vmax
Challenge:You’re given a dataset of employee salaries (salary) and years of experience (years_exp). Your boss asks: "Are there salary outliers in each experience bracket? Show me visually."
salary
years_exp
Data:
import pandas as pd import numpy as np np.random.seed(42) df = pd.DataFrame({ "years_exp": np.random.choice([1, 3, 5, 10, 15], size=500), "salary": np.concatenate([ np.random.normal(50_000, 5_000, 100), # 1 year np.random.normal(70_000, 8_000, 100), # 3 years np.random.normal(90_000, 10_000, 100), # 5 years np.random.normal(110_000, 15_000, 100), # 10 years np.random.normal(130_000, 20_000, 100) # 15 years ]) }) # Add 5 outliers df.loc[np.random.choice(df.index, 5), "salary"] *= 3
Your task:Create a plot that: 1. Shows salary distributions by experience.2. Highlights outliers.3. Is readable for a non-technical audience.
Solution:
sns.boxplot( data=df, x="years_exp", y="salary", showfliers=True, fliersize=8, palette="pastel" ) plt.title("Salary Outliers by Experience (Years)") plt.ylabel("Salary ($)") plt.xlabel("Years of Experience")
Why it works:- boxplot shows quartiles + outliers in one view.- fliersize=8 makes outliers stand out.- palette="pastel" is easy on the eyes for presentations.
fliersize=8
palette="pastel"
sns.set_theme(context="talk", style="whitegrid")
sns.boxplot(data=df, x="category", y="value", hue="group")
showfliers=True
sns.heatmap(corr, annot=True, cmap="coolwarm", vmin=-1, vmax=1)
sns.pairplot(df.sample(1000), hue="group")
g = sns.FacetGrid(df, col="category"); g.map(sns.histplot, "value")
sns.barplot(..., ci=None)
sns.kdeplot(..., bw_adjust=1)
bw_adjust
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.