

Picture by Editor
# Introduction
Seaborn is a statistical visualization library for Python that sits on prime of Matplotlib. It provides you clear defaults, tight integration with Pandas DataFrames, and high-level features that scale back boilerplate. For those who already know Matplotlib and wish quicker, extra informative plots, this information is for you.
The main focus right here is intermediate to superior utilization. You’ll work with relational, categorical, distribution, and regression plots, then transfer into grid layouts and matrix visuals that reply actual analytical questions. Count on quick code blocks, exact explanations, and sensible parameter decisions that have an effect on readability and accuracy.
What this information covers:
- Arrange themes and palettes you possibly can reuse throughout tasks
- Plots that matter for evaluation: scatterplot, lineplot, boxplot, violinplot, histplot, kdeplot, regplot, lmplot
- Excessive-dimensional layouts with FacetGrid, PairGrid, relplot, and catplot
- Correlation and heatmaps with right colour scales, masking, and annotation
- Exact management by Matplotlib hooks for titles, ticks, legends, and annotations
- Efficiency suggestions for big datasets and fixes for widespread pitfalls
You’ll study when to make use of confidence intervals, methods to handle legends in crowded visuals, methods to hold class colours constant, and when to change again to Matplotlib for high quality management. The purpose is evident, correct plots that talk findings with out further work.
# Setup and Styling Baseline
This part units a constant visible baseline so each plot within the article appears to be like skilled and export-ready. We’ll set up, import, set a world theme, select sensible palettes, and lock in determine sizing and DPI for clear outputs.
// Set up and import
Use a clear surroundings and set up Seaborn and Matplotlib.
pip set up seaborn matplotlib
Commonplace imports:
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
Two fast checks that assist keep away from surprises:
// Mission-wide theme in a single line
Set a default model as soon as, then give attention to the evaluation as a substitute of fixed styling tweaks.
sns.set_theme(
context="speak", # textual content measurement scaling: paper, pocket book, speak, poster
model="whitegrid", # clear background with mild grid
palette="deep" # readable, colorblind conscious categorical palette
)
Why this issues:
context="speak"
provides readable axis labels and titles for slides and storiesmodel="whitegrid"
improves worth studying for line and bar plots with out heavy visible noisepalette="deep"
offers distinct class colours that maintain up when printed or projected
You may override any of those per plot, however setting them globally retains the look uniform.
// Palettes you’ll truly use
Select palettes that talk the information sort. Use discrete palettes for classes and colormaps for steady values.
1. Viridis for steady scales
# Discrete colours for classes
cats = sns.color_palette("viridis", n_colors=5)
# Steady colormap for heatmaps and densities
viridis_cmap = sns.color_palette("viridis", as_cmap=True)
- Viridis preserves element throughout mild and darkish backgrounds and is perceptually uniform
- Use
n_colors=
for discrete classes. Useas_cmap=True
when mapping a numeric vary
2. Cubehelix for ordered classes or low-ink plots
# Gentle-to-dark sequence that prints nicely
dice = sns.cubehelix_palette(
begin=0.5, # hue begin
rot=-0.75, # hue rotation
gamma=1.0, # depth curve
mild=0.95,
darkish=0.15,
n_colors=6
)
Cubehelix stays readable in grayscale and helps ordered classes the place development issues.
3. Mix a customized model ramp
# Mix two model colours right into a clean ramp
mix = sns.blend_palette(["#0F766E", "#60A5FA"], n_colors=7, as_cmap=False)
# For those who want a steady colormap as a substitute
blend_cmap = sns.blend_palette(["#0F766E", "#60A5FA"], as_cmap=True)
Mixing helps align visuals with a design system whereas protecting numerical gradients constant.
Set a palette globally once you decide to a scheme for an entire determine or report
sns.set_palette(cats) # or dice, or mix
Preview a palette rapidly
sns.palplot(cats)
plt.present()
// Determine sizing and DPI for export
Management measurement and backbone from the begin to keep away from fuzzy labels or cramped axes.
Set a wise default as soon as
# World defaults through Matplotlib rcParams
plt.rcParams["figure.figsize"] = (8, 5) # width, peak in inches
plt.rcParams["figure.dpi"] = 150 # on-screen readability with out enormous recordsdata
You may nonetheless measurement particular person figures explicitly when wanted:
fig, ax = plt.subplots(figsize=(8, 5))
Save high-quality outputs
# Raster export for net or slide decks
plt.savefig("determine.png", dpi=300, bbox_inches="tight")
# Vector export for print or journals
plt.savefig("determine.svg", bbox_inches="tight")
plt.savefig("determine.pdf", bbox_inches="tight")
dpi=300
is an efficient goal for crisp net photographs and displaysbbox_inches="tight"
trims empty margins, which retains multi-panel layouts compact- Desire SVG or PDF when editors will resize figures or once you want sharp textual content at any scale
# Plots That Matter for Actual Work
On this part, we’ll give attention to plot sorts that reply evaluation questions rapidly. Every subsection explains when to make use of the plot, the important thing parameters that management that means, and a brief code pattern you possibly can adapt. The examples assume you already set the theme and baseline from the earlier part.
// Relational plots: scatterplot
, relplot(form="line")
Use relational plots to indicate relationships between numeric variables and to match teams with colour, marker, and measurement encodings. Add readability by mapping a categorical variable to hue and model, and a numeric variable to measurement.
import seaborn as sns
import matplotlib.pyplot as plt
penguins = sns.load_dataset("penguins").dropna(
subset=["bill_length_mm", "bill_depth_mm", "body_mass_g", "species", "sex"]
)
# Scatter with a number of encodings
ax = sns.scatterplot(
information=penguins,
x="bill_length_mm",
y="bill_depth_mm",
hue="species",
model="intercourse",
measurement="body_mass_g",
sizes=(30, 160),
alpha=0.8,
edgecolor="w",
linewidth=0.5
)
ax.set_title("Invoice size vs depth with species, intercourse, and mass encodings")
ax.legend(title="Species")
plt.tight_layout()
plt.present()
For traces, want the figure-level API once you want markers per group and straightforward faceting.
flights = sns.load_dataset("flights") # 12 months, month, passengers
g = sns.relplot(
information=flights,
form="line",
x="12 months",
y="passengers",
hue="month",
markers=True, # marker on every level
dashes=False, # strong traces for all teams
peak=4, side=1.6
)
g.set_axis_labels("Yr", "Passengers")
g.determine.suptitle("Month-to-month passenger pattern by 12 months", y=1.02)
plt.present()
Notes:
- Use
model
for a second categorical channel whenhue
just isn’t sufficient - Hold
alpha
barely beneath 1.0 on dense scatters to disclose overlap - Use
sizes=(min, max)
to constrain level sizes so the legend stays readable
// Categorical plots: boxplot
, violinplot
, barplot
Categorical plots present distributions and group variations. Select field or violin once you care about unfold and outliers. Select bar once you need aggregated values with intervals.
import numpy as np
suggestions = sns.load_dataset("suggestions")
# Boxplot: strong abstract of unfold
ax = sns.boxplot(
information=suggestions,
x="day",
y="total_bill",
hue="intercourse",
order=["Thur", "Fri", "Sat", "Sun"],
dodge=True,
showfliers=False
)
ax.set_title("Complete invoice by day and intercourse (boxplot, fliers hidden)")
plt.tight_layout()
plt.present()
# Violin: form of the distribution with quartiles
ax = sns.violinplot(
information=suggestions,
x="day",
y="total_bill",
hue="intercourse",
order=["Thur", "Fri", "Sat", "Sun"],
dodge=True,
inside="quartile",
minimize=0,
scale="width"
)
ax.set_title("Complete invoice by day and intercourse (violin with quartiles)")
plt.tight_layout()
plt.present()
# Bar: imply tip with percentile intervals
ax = sns.barplot(
information=suggestions,
x="day",
y="tip",
hue="intercourse",
order=["Thur", "Fri", "Sat", "Sun"],
estimator=np.imply,
errorbar=("pi", 95), # percentile interval for skewed information
dodge=True
)
ax.set_title("Imply tip by day and intercourse with 95% PI")
plt.tight_layout()
plt.present()
Notes:
order
fixes class sorting for constant comparisons- For big samples the place intervals add noise, set
errorbar=None
(orci=None
on older Seaborn) - Conceal fliers on boxplots when excessive factors distract from the group comparability
// Distribution plots:histplot
Distribution plots reveal form, multimodality, and group variations. Use stacking once you need totals, and fill once you need composition.
# Single distribution with a clean density overlay
ax = sns.histplot(
information=penguins,
x="body_mass_g",
bins=30,
kde=True,
ingredient="step"
)
ax.set_title("Physique mass distribution with KDE")
plt.tight_layout()
plt.present()
# Grouped comparability: composition throughout species
ax = sns.histplot(
information=penguins,
x="body_mass_g",
hue="species",
bins=25,
a number of="fill", # fraction per bin (composition)
ingredient="step",
stat="proportion",
common_norm=False
)
ax.set_title("Physique mass composition by species")
plt.tight_layout()
plt.present()
# Grouped comparability: whole counts by stacking
ax = sns.histplot(
information=penguins,
x="body_mass_g",
hue="species",
bins=25,
a number of="stack",
ingredient="step",
stat="rely"
)
ax.set_title("Physique mass counts by species (stacked)")
plt.tight_layout()
plt.present()
Notes:
- Use
a number of="fill"
to match relative composition throughout bins - Use
common_norm=False
when teams differ in measurement and also you need within-group densities - Select
ingredient="step"
for clear edges and straightforward overlaying
// Regression plots: regplot
, lmplot
Regression plots add fitted relationships and intervals. Use regplot
for a single axes. Use lmplot
once you want hue, row, or col faceting with out guide grid work.
Let’s check out an lmplot
. Simply make sure the dataset has no lacking values within the mapped columns.
penguins = sns.load_dataset("penguins").dropna(
subset=["bill_length_mm", "bill_depth_mm", "species", "sex"]
)
g = sns.lmplot(
information=penguins,
x="bill_length_mm",
y="bill_depth_mm",
hue="species",
col="intercourse",
peak=4,
side=1,
scatter_kws=dict(s=25, alpha=0.7),
line_kws=dict(linewidth=2)
)
g.set_titles(col_template="{col_name}")
g.determine.suptitle("Invoice dimensions by species and intercourse", y=1.02)
plt.present()
Notes:
- On newer Seaborn variations, want
errorbar=("ci", 95)
on features that help it. Ifci
remains to be accepted in your model, you possibly can hold utilizing it for now. - For those who see comparable errors, test for different unique pairs like
lowess=True
,logistic=True
, orlogx=True
used collectively.
// Interval decisions on massive information
On massive samples, interval bands can obscure the sign. Two choices enhance readability:
- Use percentile intervals for skewed distributions:
- Take away intervals solely when variation is already apparent:
sns.barplot(information=suggestions, x="day", y="tip", errorbar=("pi", 95))
sns.lineplot(information=flights, x="12 months", y="passengers", errorbar=None)
# or on older variations:
sns.lineplot(information=flights, x="12 months", y="passengers", ci=None)
Guideline:
- Desire
errorbar=("pi", 95)
for skewed or heavy-tailed information - Desire
errorbar=None
(orci=None
) when the viewers cares extra about pattern form than exact uncertainty on a really massive N
# Excessive-Dimensional Views with Grids
Grids make it easier to examine patterns throughout teams with out guide subplot juggling. You outline rows, columns, and colour as soon as, then apply a plotting perform to every subset. This retains construction constant and makes variations apparent.
// FacetGrid and catplot
/ relplot
Use a FacetGrid once you need full management over what will get mapped to every side. Use catplot
and relplot
once you desire a fast, figure-level API that builds the grid for you. The core concept is similar: break up information by row
, col
, and colour
with hue
.
Earlier than the code: hold side counts life like. 4 to 6 small multiples are straightforward to scan. Past that, wrap columns or filter classes. Management sharing with sharex
and sharey
so comparisons stay legitimate.
import seaborn as sns
import matplotlib.pyplot as plt
suggestions = sns.load_dataset("suggestions").dropna()
# 1) Full management with FacetGrid + regplot
g = sns.FacetGrid(
information=suggestions,
row="time", # Lunch vs Dinner
col="day", # Thur, Fri, Sat, Solar
hue="intercourse", # Male vs Feminine
margin_titles=True,
sharex=True,
sharey=True,
peak=3,
side=1
)
g.map_dataframe(
sns.regplot,
x="total_bill",
y="tip",
scatter_kws=dict(s=18, alpha=0.6),
line_kws=dict(linewidth=2),
ci=None
)
g.add_legend(title="Intercourse")
g.set_axis_labels("Complete invoice", "Tip")
g.fig.suptitle("Tipping patterns by day and time", y=1.02)
plt.present()
# 2) Fast grids with catplot (constructed on FacetGrid)
sns.catplot(
information=suggestions,
form="field",
x="day", y="total_bill",
row="time", hue="intercourse",
order=["Thur", "Fri", "Sat", "Sun"],
peak=3, side=1.1, dodge=True
).set_axis_labels("Day", "Complete invoice")
plt.present()
# 3) Fast relational grids with relplot
penguins = sns.load_dataset("penguins").dropna()
sns.relplot(
information=penguins,
form="scatter",
x="bill_length_mm", y="bill_depth_mm",
row="intercourse", col="island", hue="species",
peak=3.2, side=1
)
plt.present()
Key factors:
- Use
order
to repair class sorting - Use
col_wrap
when you’ve got one side dimension with many ranges - Add a
suptitle
to summarize the comparability; hold axis labels constant throughout sides
// PairGrid and pairplot
Pairwise plots reveal relationships throughout many numeric variables. pairplot
is the quick path. PairGrid
provides you per-region management. For dense datasets, restrict variables and think about nook=True
to drop redundant higher panels.
Earlier than the code: select variables which might be informative collectively. Combine scales solely when you’ve got a motive, then standardize or log-transform first.
# Fast pairwise view
num_cols = ["bill_length_mm", "bill_depth_mm", "flipper_length_mm", "body_mass_g"]
sns.pairplot(
information=penguins[num_cols + ["species"]].dropna(),
vars=num_cols,
hue="species",
nook=True, # solely decrease triangle + diagonal
diag_kind="hist", # or "kde"
plot_kws=dict(s=18, alpha=0.6),
diag_kws=dict(bins=20, ingredient="step")
)
plt.present()
Suggestions:
nook=True
reduces litter and quickens rendering- Hold marker measurement modest so overlaps stay readable
- For very totally different scales, apply
np.log10
to skewed measures earlier than plotting
// Blended layers on a PairGrid
A combined mapping helps you examine scatter patterns and density construction in a single view. Use scatter on the higher triangle, bivariate KDE on the decrease triangle, and histograms on the diagonal. This mix is compact and informative.
Earlier than the code: density layers can get heavy. Scale back ranges and keep away from too many bins. Add a legend as soon as and hold it exterior the grid if house is tight.
from seaborn import PairGrid
g = PairGrid(
information=penguins[num_cols + ["species"]].dropna(),
vars=num_cols,
hue="species",
peak=2.6, side=1
)
# Higher triangle: scatter
g.map_upper(
sns.scatterplot,
s=16, alpha=0.65, linewidth=0.3, edgecolor="w"
)
# Decrease triangle: bivariate KDE
g.map_lower(
sns.kdeplot,
fill=True, thresh=0.05, ranges=5
)
# Diagonal: histograms
g.map_diag(
sns.histplot,
bins=18, ingredient="step"
)
g.add_legend(title="Species")
for ax in g.axes.flat:
if ax just isn't None:
ax.tick_params(axis="x", labelrotation=30)
g.fig.suptitle("Pairwise construction of penguin measurements", y=1.02)
plt.present()
Tips:
- Begin with 4 numeric variables. Add extra provided that every provides a definite sign
- For uneven group sizes, give attention to proportions fairly than uncooked counts once you examine distributions
- If rendering slows down, pattern rows earlier than plotting or drop
fill
from the KDE layer
# Correlation, Heatmaps, and Matrices
Correlation heatmaps are a compact technique to scan relationships throughout many numeric variables. The purpose is a readable matrix that highlights actual sign, retains noise out of the way in which, and exports cleanly.
// Construct a correlation matrix and masks redundant cells
Begin by deciding on numeric columns and selecting a correlation methodology. Pearson is normal for linear relationships. Spearman is best for ranked or monotonic patterns. A triangular masks removes duplication so the attention focuses on distinctive pairs.
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# Knowledge
penguins = sns.load_dataset("penguins").dropna()
# Select numeric columns and compute correlation
num_cols = penguins.select_dtypes(embrace="quantity").columns
corr = penguins[num_cols].corr(methodology="pearson")
# Masks the higher triangle (hold decrease + diagonal)
masks = np.triu(np.ones_like(corr, dtype=bool))
# Heatmap with diverging palette centered at zero
ax = sns.heatmap(
corr,
masks=masks,
annot=True,
fmt=".2f",
cmap="vlag",
middle=0,
vmin=-1, vmax=1,
sq.=True,
cbar_kws={"shrink": 0.8, "label": "Pearson r"},
linewidths=0.5, linecolor="white"
)
ax.set_title("Correlation matrix of penguin measurements")
plt.tight_layout()
plt.present()
Notes:
- Use
methodology="spearman"
when variables are usually not on comparable scales or include outliers that have an effect on Pearson - Hold
vmin
andvmax
symmetric so the colour scale treats destructive and constructive values equally
// Management visibility with scale and colorbar choices
As soon as the matrix is in place, tune what the reader sees. Symmetric limits, a centered palette, and a labeled colorbar
forestall misreads. You may also disguise weak correlations or the diagonal to scale back litter.
# Elective: disguise weak correlations beneath a threshold
threshold = 0.2
weak = corr.abs() < threshold
mask2 = np.triu(np.ones_like(corr, dtype=bool)) | weak # mix masks
ax = sns.heatmap(
corr,
masks=mask2,
annot=False, # let sturdy colours carry the message
cmap="vlag",
middle=0,
vmin=-1, vmax=1,
sq.=True,
cbar_kws={"shrink": 0.8, "ticks": [-1, -0.5, 0, 0.5, 1], "label": "Correlation"},
linewidths=0.4, linecolor="#F5F5F5"
)
ax.set_title("Robust correlations solely (|r| ≥ 0.20)")
plt.tight_layout()
plt.present()
Suggestions:
cbar_kws
controls readability of the legend. Set ticks that match your viewers- Flip
annot=True
again on once you want precise values for a report. Hold it off for dashboards the place form and colour are sufficient
// Giant matrices: hold labels and edges readable
Huge matrices want self-discipline. Skinny or rotate tick labels, add grid traces between cells, and think about reordering variables to group associated blocks. If the matrix could be very broad, present each nth tick to keep away from label collisions.
# Artificial broad instance: 20 numeric columns
rng = np.random.default_rng(0)
broad = pd.DataFrame(rng.regular(measurement=(600, 20)),
columns=[f"f{i:02d}" for i in range(1, 21)])
corr_wide = broad.corr()
fig, ax = plt.subplots(figsize=(10, 8), dpi=150)
hm = sns.heatmap(
corr_wide,
cmap="vlag",
middle=0,
vmin=-1, vmax=1,
sq.=True,
cbar_kws={"shrink": 0.7, "label": "Correlation"},
linewidths=0.3, linecolor="white"
)
# Rotate x labels and skinny ticks
ax.set_xticklabels(ax.get_xticklabels(), rotation=40, ha="proper")
ax.set_yticklabels(ax.get_yticklabels(), rotation=0)
ax.tick_params(axis="each", labelsize=8)
# Present each 2nd tick on each axes
xt = ax.get_xticks()
yt = ax.get_yticks()
ax.set_xticks(xt[::2])
ax.set_yticks(yt[::2])
ax.set_title("Correlation matrix with tick thinning and grid traces")
plt.tight_layout()
plt.present()
When construction issues greater than precise order, attempt a clustered view that teams comparable variables:
# Clustered matrix for sample discovery
g = sns.clustermap(
corr_wide,
cmap="vlag",
middle=0,
vmin=-1, vmax=1,
linewidths=0.2, linecolor="white",
figsize=(10, 10),
cbar_kws={"shrink": 0.6, "label": "Correlation"},
methodology="common", # linkage
metric="euclidean" # distance on correlations
)
g.fig.suptitle("Clustered correlation matrix", y=1.02)
plt.present()
Tips:
- Improve determine measurement fairly than shrinking font till it turns into unreadable
- Add
linewidths
andlinecolor
to outline cell boundaries on dense matrices - Use clustering once you need to floor block construction. Hold a plain ordered matrix once you want steady positions throughout stories
# Precision Management with Matplotlib Hooks
Seaborn handles the heavy lifting, however last polish comes from Matplotlib. These hooks allow you to set clear titles, management axes exactly, handle legends in tight areas, and annotate essential factors with out litter.
// Titles, labels, legends
Good plots learn themselves. Set titles that state the query, label axes with items, and hold the legend compact and informative. Place the legend the place it helps the attention, not the place it hides information.
Earlier than the code: want axis-level strategies over plt.*
so settings keep hooked up to the precise subplot. Use a legend title and think about shifting the legend exterior the axes when you’ve got many teams.
import seaborn as sns
import matplotlib.pyplot as plt
penguins = sns.load_dataset("penguins").dropna()
ax = sns.scatterplot(
information=penguins,
x="bill_length_mm",
y="bill_depth_mm",
hue="species",
model="intercourse",
s=60,
alpha=0.8,
edgecolor="w",
linewidth=0.5
)
# Titles and labels
ax.set_title("Invoice size vs depth by species")
ax.set_xlabel("Invoice size (mm)")
ax.set_ylabel("Invoice depth (mm)")
# Legend with title, positioned exterior to the precise
leg = ax.legend(
title="Species",
loc="middle left",
bbox_to_anchor=(1.02, 0.5), # exterior the axes
frameon=True,
borderaxespad=0.5
)
# Elective legend styling
for textual content in leg.get_texts():
textual content.set_fontsize(9)
leg.get_title().set_fontsize(10)
plt.tight_layout()
plt.present()
Notes
bbox_to_anchor
provides you high quality management over legend placement exterior the axes- Hold legend fonts barely smaller than axis tick labels to scale back visible weight
- For those who want a customized legend order, cross
hue_order=
within the plotting name
// Axis management
Axis limits, ticks, and rotation enhance readability greater than any colour alternative. Set solely the ticks your viewers wants. Use rotation when labels collide. Add small margins to cease markers from touching the body.
Earlier than the code: determine which ticks matter. For time or evenly spaced integers, present fewer ticks. For skewed information, think about log scales and customized formatters.
import numpy as np
flights = sns.load_dataset("flights") # columns: 12 months, month, passengers
ax = sns.lineplot(
information=flights,
x="12 months",
y="passengers",
estimator=None,
errorbar=None,
marker="o",
dashes=False
)
ax.set_title("Airline passengers by 12 months")
ax.set_xlabel("Yr")
ax.set_ylabel("Passengers")
# Present a tick each 5 years
years = np.type(flights["year"].distinctive())
ax.set_xticks(years[::5])
# Tidy the view
ax.margins(x=0.02, y=0.05) # small padding inside axes
ax.set_ylim(0, None) # begin at zero for clearer pattern
# Rotate if wanted
plt.xticks(rotation=0)
plt.tight_layout()
plt.present()
Extras you possibly can add when required
- Symmetric limits:
ax.set_xlim(left, proper)
andax.set_ylim(backside, prime)
for honest comparisons - Log scaling:
ax.set_xscale("log")
orax.set_yscale("log")
for lengthy tails - Fewer ticks:
ax.xaxis.set_major_locator(matplotlib.ticker.MaxNLocator(nbins=6))
// Annotations, traces, and spans
Annotations name out the explanation the plot exists. Use a brief label, a transparent arrow, and constant styling. Traces and spans mark thresholds or durations that matter.
Earlier than the code: place annotations close to the information they seek advice from, however keep away from protecting factors. Think about using a semi-transparent span for ranges.
import matplotlib as mpl
suggestions = sns.load_dataset("suggestions")
ax = sns.regplot(
information=suggestions,
x="total_bill",
y="tip",
ci=None,
scatter_kws=dict(s=28, alpha=0.6),
line_kws=dict(linewidth=2)
)
ax.set_title("Tip vs whole invoice with callouts")
ax.set_xlabel("Complete invoice ($)")
ax.set_ylabel("Tip ($)")
# Threshold line for a tipping rule of thumb
ax.axhline(3, colour="#444", linewidth=1, linestyle="--")
ax.textual content(ax.get_xlim()[0], 3.1, "Reference: $3 tip", fontsize=9, colour="#444")
# Spotlight a invoice vary with a span
ax.axvspan(20, 40, colour="#fde68a", alpha=0.25, linewidth=0) # gentle spotlight
# Annotate a consultant level
pt = suggestions.loc[tips["total_bill"].between(20, 40)].iloc[0]
ax.annotate(
"Instance test",
xy=(pt["total_bill"], pt["tip"]),
xytext=(pt["total_bill"] + 10, pt["tip"] + 2),
arrowprops=dict(
arrowstyle="->",
colour="#111",
shrinkA=0,
shrinkB=0,
linewidth=1.2
),
fontsize=9,
bbox=dict(boxstyle="spherical,pad=0.2", fc="white", ec="#ddd", alpha=0.9)
)
plt.tight_layout()
plt.present()
Tips:
- Hold annotations quick. The plot ought to nonetheless learn with out them
- Use
axvline
,axhline
,axvspan
, andaxhspan
for thresholds and ranges - If labels overlap, regulate with small offsets or scale back font measurement, not by eradicating the annotation that carries that means
# Wrapping Up
You now have a whole baseline for quick, constant Seaborn work: pattern or mixture when scale calls for it, management legends and axes with Matplotlib hooks, hold colours steady throughout figures, and repair labels earlier than export. Mix these with the grid patterns and statistical plots from earlier sections and you may cowl most evaluation wants with out customized subplot code.
The place to study extra:
Shittu Olumide is a software program engineer and technical author enthusiastic about leveraging cutting-edge applied sciences to craft compelling narratives, with a eager eye for element and a knack for simplifying complicated ideas. You may also discover Shittu on Twitter.