Visualization Cheat Sheet
matplotlib and seaborn essentials. The full explanation is in Data visualization .
Setup and the object model
import matplotlib.pyplot as plt
import seaborn as sns
sns . set_theme ( style = "whitegrid" , palette = "colorblind" ) # optional global style
fig , ax = plt . subplots ( figsize = ( 7 , 4 )) # one plot
fig , axes = plt . subplots ( 2 , 3 , figsize = ( 12 , 6 ), # a grid: axes[row, col]
sharex = True , sharey = True )
fig . tight_layout () # fix overlapping labels
fig . savefig ( "chart.png" , dpi = 150 , bbox_inches = "tight" ) # .svg/.pdf for vector
plt . show ()
pyplot (implicit)
Object-oriented (explicit)
plt.plot(x, y)
ax.plot(x, y)
plt.title("t")
ax.set_title("t")
plt.xlabel("x")
ax.set_xlabel("x")
plt.xlim(0, 10)
ax.set_xlim(0, 10)
plt.xticks(...)
ax.set_xticks(...)
plt.legend()
ax.legend()
Core matplotlib plots
Plot
Call
Key options
Line
ax.plot(x, y)
lw, ls="--", marker="o", label
Scatter
ax.scatter(x, y)
s (size), c (color values), alpha, cmap
Bar
ax.bar(cats, vals) / ax.barh(...)
width, color, yerr
Histogram
ax.hist(x, bins=30)
density=True, alpha, histtype="step"
Box
ax.boxplot([a, b])
labels, showfliers
Image / matrix
ax.imshow(M)
cmap, vmin, vmax, aspect
Fill band
ax.fill_between(x, lo, hi)
alpha (for confidence bands)
Reference line
ax.axhline(y) / ax.axvline(x)
color, ls
Shaded span
ax.axvspan(x0, x1)
alpha
Text
ax.text(x, y, "s") / ax.annotate("s", xy, xytext)
ha, va, arrowprops
Styling details
ax . set_title ( "Takeaway goes here" , loc = "left" , fontweight = "bold" )
ax . set ( xlabel = "Distance (km)" , ylabel = "Time (min)" , ylim = ( 0 , None ))
ax . spines [[ "top" , "right" ]] . set_visible ( False ) # remove chart junk
ax . set_xscale ( "log" ) # log axis
ax . tick_params ( axis = "x" , rotation = 45 )
ax . legend ( frameon = False , loc = "upper left" )
ax . grid ( axis = "y" , alpha = 0.3 )
ax . yaxis . set_major_formatter ( " {x:,.0f} " ) # thousands separators
twin = ax . twinx () # second y-axis (use sparingly)
seaborn: axes-level functions
These draw on one Axes. Pass ax= to choose which.
Purpose
Function
Example
Histogram / KDE
histplot, kdeplot
sns.histplot(df, x="v", hue="g", kde=True, stat="density")
Scatter
scatterplot
sns.scatterplot(df, x="a", y="b", hue="g", size="n", alpha=.6)
Line with CI
lineplot
sns.lineplot(df, x="t", y="v", hue="g", errorbar=("ci", 95))
Category means
barplot, pointplot
sns.barplot(df, x="g", y="v", errorbar=("ci", 95))
Counts
countplot
sns.countplot(df, y="cat", order=df["cat"].value_counts().index)
Distributions by group
boxplot, violinplot, stripplot
sns.boxplot(df, x="g", y="v")
Matrix
heatmap
sns.heatmap(corr, annot=True, fmt=".2f", cmap="vlag", center=0)
Regression fit
regplot
sns.regplot(df, x="a", y="b", ci=None)
These create their own figure and return a FacetGrid. Use col=, row=, and col_wrap=.
Function
Wraps
Example
relplot
scatter, line
sns.relplot(df, x="a", y="b", col="g", kind="scatter")
displot
hist, kde, ecdf
sns.displot(df, x="v", col="g", row="h", bins=20)
catplot
box, bar, violin, strip
sns.catplot(df, x="g", y="v", col="h", kind="box")
lmplot
regplot
sns.lmplot(df, x="a", y="b", col="g", col_wrap=3)
pairplot
all pairs
sns.pairplot(df[cols + ["target"]], hue="target")
g = sns . relplot ( df , x = "a" , y = "b" , col = "g" , height = 3 , aspect = 1.2 )
g . set_titles ( " {col_name} " )
g . set_axis_labels ( "A (units)" , "B (units)" )
g . figure . suptitle ( "Title" , y = 1.03 )
Which chart for which question
Question
Chart
Change over time
line; add a rolling mean for noisy series
Compare categories
bar (horizontal for long labels), sorted, starting at 0
One distribution
histogram (try several bin counts), KDE, ECDF
Distributions across groups
box, violin, overlaid density, small multiples
Relationship of two numbers
scatter (alpha for overplotting, hexbin for very many points)
Many pairwise relationships
pair plot, correlation heatmap
Parts of a whole
stacked bar, or a sorted bar of shares; pie only for 2–3 parts
Model results
predicted vs actual scatter, residual plot, confusion matrix heatmap
Color
Data type
Colormap kind
Good choices
Ordered values
sequential
viridis, cividis, rocket, Blues
Values around a midpoint
diverging
vlag, RdBu, coolwarm, with center=
Categories
qualitative
sns.color_palette("colorblind"), tab10
palette = sns . color_palette ( "colorblind" , 3 )
sns . palplot ( palette ) # preview a palette
ax . scatter ( x , y , c = values , cmap = "viridis" ); fig . colorbar ( ax . collections [ 0 ], ax = ax )
Avoid jet and rainbow maps, and don't rely on red versus green alone. Add markers, line styles, or direct labels as a second cue.
pandas plotting shortcuts
df [ "col" ] . hist ( bins = 30 )
df . hist ( bins = 30 , figsize = ( 12 , 8 )) # every numeric column
df [ "cat" ] . value_counts () . plot . barh ()
df . plot ( x = "date" , y = [ "a" , "b" ], figsize = ( 10 , 4 )) # lines
df . plot . scatter ( x = "a" , y = "b" , alpha = 0.5 )
df . boxplot ( column = "v" , by = "g" )
All of these return a matplotlib Axes, so you can keep customizing.
Plotly (interactive)
import plotly.express as px
fig = px . scatter ( df , x = "a" , y = "b" , color = "g" , hover_data = [ "id" ], log_x = True )
fig = px . line ( df , x = "date" , y = "v" , color = "g" )
fig = px . histogram ( df , x = "v" , color = "g" , barmode = "overlay" , nbins = 40 )
fig . update_layout ( title = "Title" , template = "plotly_white" )
fig . show ()
fig . write_html ( "chart.html" )
Explanatory chart checklist