How do I plot with seaborn and how does it relate to matplotlib?
Short answer
Seaborn is a layer on top of matplotlib that plots directly from a DataFrame with far less code. It returns matplotlib objects, so you use matplotlib to fine-tune titles, limits and saving.
The short version
Seaborn sits on top of matplotlib. It takes a DataFrame and column names, and handles the grouping, colouring and legend for you, so a grouped bar or scatter takes one line instead of a loop. It returns ordinary matplotlib objects, so you still use matplotlib to adjust titles, limits and to save the figure.
One line instead of a loop
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({
"city": ["Leeds", "Leeds", "Bath", "Bath"],
"amount": [1, 2, 3, 4],
"kind": ["online", "shop", "online", "shop"],
})
fig, ax = plt.subplots()
sns.barplot(data=df, x="city", y="amount", hue="kind", ax=ax)
ax.set_title("Amount by city")
fig.savefig("chart.png")
The hue="kind" argument splits and colours the bars by category and builds the legend automatically. In pure matplotlib you would filter the frame per category, plot each in a loop, offset the bar positions by hand and build the legend yourself.
The data-first interface
Seaborn's key idea is that you pass the whole DataFrame plus the column names, and it works out the rest. This suits long (tidy) data, one row per observation, which is another good reason to reshape to long form before plotting. If your data is wide, melt it first and seaborn becomes much easier to use.
It returns matplotlib objects
A seaborn call draws onto a matplotlib Axes, and returns it. So everything you know about matplotlib still applies for the finishing touches.
ax = sns.scatterplot(data=df, x="amount", y="amount")
ax.set_xlabel("Amount")
ax.set_ylim(0, 10)
This is the main thing to understand: seaborn is not a separate plotting world. Use seaborn for the heavy lifting and matplotlib for the fine control, passing ax=ax to place a seaborn plot into a figure you built.
Figure-level versus axes-level plots
Some seaborn functions (scatterplot, barplot, lineplot) draw onto one axes and accept ax=. Others (relplot, catplot, displot) create the whole figure themselves, often a grid of panels split by a variable, and do not accept ax=. Passing ax= to a figure-level function is a common error. Use the axes-level ones when you are composing a figure yourself, and the figure-level ones when you want seaborn to build a multi-panel grid.
Statistical plots for free
Seaborn's real value is the plots that would be tedious by hand: boxplot and violinplot for distributions, heatmap for a correlation matrix, regplot for a scatter with a fitted line, and pairplot for every pairwise relationship at once. These encode a statistical summary rather than just drawing points.
When to use plain matplotlib
For a simple line or bar from arrays, matplotlib alone is fine and adds no dependency. Reach for seaborn when you are plotting from a DataFrame, splitting by category, or want a statistical plot without writing the maths yourself.