One line, not ten
Matplotlib gave you the engine and the control. Seaborn gives you the shortcut. Where matplotlib made you count values, bin them, and place bars by hand, seaborn takes data=df plus the column names and does the statistics for you - it groups, computes confidence intervals, builds the legend, and picks sensible defaults. It's not a replacement for matplotlib; it sits on top of it. That means everything you learned last session - fig, ax, set_title, savefig - still works, and now the hard parts get one-liners.
Why seaborn, and figure- vs axes-level 5 min live
Seaborn has two families of functions, and knowing which family you're calling is the one concept that saves the most confusion. Learn it now.
LiveData-aware, and two function families3 min▶
Two things make seaborn feel like a level-up:
- It speaks DataFrame. You pass
data=dfand the column names as strings -x="experience_level", y="salary_year", hue="remote". Seaborn does the grouping, the aggregation, the confidence intervals, and the legend. No more counting and binning by hand. - It has two function families. Axes-level functions (
scatterplot,histplot,boxplot,barplot) draw onto anaxyou pass in - they slot into the matplotlib workflow you already know. Figure-level functions (relplot,displot,catplot) create and manage their own figure, and can split your data into a grid of small multiples withcol=androw=.
Rule of thumb: reach for axes-level when you're placing one chart into a layout you control; reach for figure-level when you want faceting done for you.
Self-studyWhich family, when2 min read▶
| You want... | Family | Function |
|---|---|---|
| one chart inside my own fig, ax | axes-level | boxplot, histplot, scatterplot, barplot |
| the same chart split across categories | figure-level | catplot, displot, relplot with col= / row= |
| fine control over a multi-panel layout | axes-level | draw each panel onto its own ax |
ax= argument - they own the figure. If you try to drop relplot into a subplot grid it won't fit. That single fact explains most "why won't my seaborn chart go where I put it" confusion.
The core plots on real data 5 min live
A handful of seaborn plots answer most job-market questions. Each maps to a question - pick the plot by what you're asking.
LiveThe plot-to-question map3 min▶
- histplot / kdeplot - the spread of one number (salary_year), smooth curve optional.
- boxplot / violinplot - a numeric column split by a category (salary by experience_level). Box shows median and quartiles; violin adds the full shape.
- barplot - the mean of a value per category, with a confidence-interval whisker seaborn computes for free (mean salary by role).
- scatterplot - two numbers, with an optional
hue=to color a third categorical dimension (salary vs company size, colored by remote). - countplot - just how many rows per category, the seaborn one-liner for a frequency bar.
A boxplot of salary by experience_level tells the whole seniority-pay story in one glance: you see the median step up from entry to senior, and the boxes show how much the ranges overlap. That single chart often answers the loudest question in any "state of the job market" post - "does seniority actually pay?" - with evidence instead of a vibe.
Self-studyhue, and how seaborn does stats for you2 min read▶
Two things seaborn quietly handles that you'd hand-code in matplotlib:
- hue= splits any plot by a categorical column and builds the color legend automatically. One argument, and a boxplot of salary by experience becomes salary by experience and remote status.
- Confidence intervals -
barplotandlineplotaggregate and draw the CI whisker by default, so a "mean salary by role" chart honestly shows how uncertain each mean is. That's statistics baked into the plotting call.
Heatmaps, themes, and polish 4 min live
Two finishing moves: the correlation heatmap that scans your whole numeric frame at once, and the theme that makes every chart in the report look like one family.
LiveThe heatmap, and one theme to rule them2 min▶
df.corr() gives you the pairwise correlation matrix; sns.heatmap(..., annot=True) shades and numbers every cell so a reader sees strength and sign at a glance. And sns.set_theme() at the top of the notebook sets style, palette, and context (label sizing) for every chart after it - one line, one consistent look.
Self-studyPalette discipline and despine2 min read▶
- One meaning per color. If blue means "remote" in one chart, it means "remote" in every chart - and you add a legend so the reader never guesses. This is the workspace encoding rule, and seaborn's
palette=makes it easy to keep. - set_theme(style, palette, context) -
styleis the background (whitegrid, ticks...),paletteis the color set,contextscales fonts for a deck vs a paper. - sns.despine() removes the top and right spines for a cleaner, more modern frame.
- Saving is unchanged from Session 6 - grab the figure and
savefig(dpi=300)as PNG and SVG.
A correlation heatmap of your numeric columns is the fastest "what relates to what" scan there is. On the job data it might show salary moving with company size but barely with view count - a finding you'd never spot scrolling rows, and one that earns a line in the Session 8 report.
Salary by experience, then split by remote ★ 7 min · everyone codes
Set the theme once so the whole session looks consistent.
Draw a boxplot of salary_year across experience_level - read the seniority-pay story.
Add hue="remote" and watch seaborn split each box and build the legend for free.
violinplot or drop the smallest categories.
A correlation heatmap of the numbers ★ 8 min · everyone codes
Pick your numeric columns - salary, company size, applies, views.
Compute .corr(), then heatmap it with annotations on.
Interpret: which pairs move together, which don't, and what that means for the market.
Reading it: a strong positive cell (dark) between views and applies just says popular postings get more clicks - not surprising. The interesting cell is salary vs company_size: if it's moderate and positive, "bigger companies advertise higher pay" becomes a defensible line in your report. The heatmap turned four columns into one scannable claim.
Faceted small multiples with displot ★ 7 min · everyone codes
Use a figure-level function to split the salary distribution across role buckets in one call.
col= makes a panel per category - small multiples without a subplot loop.
Apply the theme, then save the figure for the report.
g.figure to set a super-title or save. That's the practical payoff of the Part 1 distinction - now you know exactly why the save line looks different here.
This week ◐ 40 min total
- Work Kaggle's Data Visualization L1-L6 - Hello Seaborn, Line, Bar & Heatmap, Scatter, Distributions, and Choosing plot types & styles. It's the same ground with graded reps.
- Rebuild your report's key charts in seaborn on YOUR data - the boxplot, the heatmap, the faceted distribution. Compare them to your Session 6 matplotlib versions.
- Pick one cohesive theme and palette with
set_themeand apply it to every chart. One meaning per color, legend on. - Save the final chart set as PNG and SVG. This is the visual half of the Session 8 report - next week you write the words around it.
Three questions before you go 🎯 ◐ 90 seconds
1 · What's the main advantage of seaborn over raw matplotlib?
Seaborn sits on top of matplotlib. You pass data=df plus column names and it handles the grouping, confidence intervals, legend, and defaults - the statistics come baked in.
2 · What's the difference between figure-level and axes-level functions?
Figure-level functions own the whole figure and do faceting for you - so they don't take ax=. Axes-level functions slot into a fig, ax layout you control.
3 · What does sns.heatmap(df.corr(), annot=True) show?
df.corr() builds the correlation matrix; the heatmap shades and labels each cell so you see the strength and sign of every pair at a glance.
Official sources covered
This session teaches the working content of the official seaborn tutorial and Kaggle's free Data Visualization micro-course. Certificates and the graded final project stay on those platforms - links provided.