skills/seaborn/references/objects_interface.md
The seaborn.objects interface provides a modern, declarative API for building visualizations through composition. This guide covers the objects interface introduced in seaborn 0.12+ and checked against seaborn 0.13.2. Upstream still labels this interface experimental and incomplete, so prefer it when composition helps and keep conservative production workflows on the function API when needed.
The objects interface separates what you want to show (data and mappings) from how to show it (marks, stats, and moves). Build plots by:
Plot object with data and aesthetic mappings.add() combining marks and statistical transformations.scale(), .label(), .limit(), .theme(), etc..show() or .save()import seaborn.objects as so
import pandas as pd
# Create plot with data and mappings
p = so.Plot(data=df, x='x_var', y='y_var')
# Add mark (visual representation)
p = p.add(so.Dot())
# Display (automatic in Jupyter)
p.show()
The Plot class is the foundation of the objects interface.
so.Plot(data=None, x=None, y=None, color=None, alpha=None,
fill=None, fillalpha=None, fillcolor=None, marker=None,
pointsize=None, stroke=None, linewidth=None, linestyle=None,
edgewidth=None, edgecolor=None, text=None, group=None)
Parameters:
data - DataFrame or dict of data vectorsx, y - Variables for positioncolor - Variable for color encodingalpha - Variable for transparencymarker - Variable for marker shapepointsize - Variable for point sizestroke - Variable for line widthlinewidth, linestyle - Variables for line appearanceedgewidth, edgecolor - Variables for mark edge appearancetext - Variable for text labelsgroup - Variable for grouping observationsExamples:
# Basic mapping
so.Plot(df, x='total_bill', y='tip')
# Multiple mappings
so.Plot(df, x='total_bill', y='tip', color='day', pointsize='size')
# All variables in Plot
p = so.Plot(df, x='x', y='y', color='cat')
p.add(so.Dot()) # Uses all mappings
# Some variables in add()
p = so.Plot(df, x='x', y='y')
p.add(so.Dot(), color='cat') # Only this layer uses color
Add a layer to the plot with mark and optional stat/move.
Plot.add(mark, *transforms, orient=None, legend=True, data=None,
**variables)
Parameters:
mark - Mark object defining visual representation*transforms - Stat and/or Move objects for data transformationorient - "x", "y", or "v"/"h" for orientationlegend - Include in legend (True/False)data - Override data for this layer**variables - Override or add variable mappingsExamples:
# Simple mark
p.add(so.Dot())
# Mark with stat
p.add(so.Line(), so.PolyFit(order=2))
# Mark with multiple transforms
p.add(so.Bar(), so.Agg(), so.Dodge())
# Layer-specific mappings
p.add(so.Dot(), color='category')
p.add(so.Line(), so.Agg(), color='category')
# Layer-specific data
p.add(so.Dot())
p.add(so.Line(), data=summary_df)
Create subplots from categorical variables.
Plot.facet(col=None, row=None, order=None, wrap=None)
Parameters:
col - Variable for column facetsrow - Variable for row facetsorder - Dict with facet orders (keys: variable names)wrap - Wrap columns after this manyExample:
p.facet(col='time', row='sex')
p.facet(col='category', wrap=3)
p.facet(col='day', order={'day': ['Thur', 'Fri', 'Sat', 'Sun']})
Create pairwise subplots for multiple variables.
Plot.pair(x=None, y=None, wrap=None, cross=True)
Parameters:
x - Variables for x-axis pairingsy - Variables for y-axis pairings (if None, uses x)wrap - Wrap after this many columnscross - Include all x/y combinations (vs. only diagonal)Example:
# Pairs of all variables
p = so.Plot(df).pair(x=['a', 'b', 'c'])
p.add(so.Dot())
# Rectangular grid
p = so.Plot(df).pair(x=['a', 'b'], y=['c', 'd'])
p.add(so.Dot(), alpha=0.5)
Customize how data maps to visual properties.
Plot.scale(**scales)
Parameters: Keyword arguments with property names and Scale objects
Example:
p.scale(
x=so.Continuous().tick(every=5),
y=so.Continuous().label(like='{x:.1f}'),
color=so.Nominal(['#1f77b4', '#ff7f0e', '#2ca02c']),
pointsize=(5, 10) # Shorthand for range
)
Set axis limits.
Plot.limit(x=None, y=None)
Parameters:
x - Tuple of (min, max) for x-axisy - Tuple of (min, max) for y-axisExample:
p.limit(x=(0, 100), y=(0, 50))
Set axis labels and titles.
Plot.label(x=None, y=None, color=None, title=None, **labels)
Parameters: Keyword arguments with property names and label strings
Example:
p.label(
x='Total Bill ($)',
y='Tip Amount ($)',
color='Day of Week',
title='Restaurant Tips Analysis'
)
Apply matplotlib style settings.
Plot.theme(config, /)
Parameters:
config - Dict of matplotlib rcParams, passed positionallyExample:
# Seaborn theme
p.theme({**sns.axes_style('whitegrid'), **sns.plotting_context('talk')})
# Custom rcParams
p.theme({'axes.facecolor': 'white', 'axes.grid': True})
Configure subplot layout.
Plot.layout(size=None, extent=None, engine=None)
Parameters:
size - (width, height) in inchesextent - (left, bottom, right, top) for subplotsengine - "tight", "constrained", or NoneExample:
p.layout(size=(10, 6), engine='constrained')
Control axis sharing across facets.
Plot.share(x=None, y=None)
Parameters:
x - Share x-axis: True, False, or "col"/"row"y - Share y-axis: True, False, or "col"/"row"Example:
p.share(x=True, y=False) # Share x across all, independent y
p.share(x='col') # Share x within columns only
Plot on existing matplotlib figure or axes.
Plot.on(target)
Parameters:
target - matplotlib Figure or Axes objectExample:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 2, figsize=(10, 10))
so.Plot(df, x='x', y='y').add(so.Dot()).on(axes[0, 0])
so.Plot(df, x='x', y='z').add(so.Line()).on(axes[0, 1])
Render and display the plot.
Plot.show(**kwargs)
Parameters: Passed to matplotlib.pyplot.show()
Save the plot to file.
Plot.save(filename, **kwargs)
Parameters:
filename - Output filename**kwargs - Passed to matplotlib.figure.Figure.savefig()Example:
p.save('plot.png', dpi=300, bbox_inches='tight')
p.save('plot.pdf')
Marks define how data is visually represented.
Points/markers for individual observations.
so.Dot(artist_kws=None, **kwargs)
Properties:
color - Fill coloralpha - Transparencyfillcolor - Alternate color propertyfillalpha - Alternate alpha propertyedgecolor - Edge coloredgealpha - Edge transparencyedgewidth - Edge line widthmarker - Marker stylepointsize - Marker sizestroke - Edge widthExample:
so.Plot(df, x='x', y='y').add(so.Dot(color='blue', pointsize=10))
so.Plot(df, x='x', y='y', color='cat').add(so.Dot(alpha=0.5))
Lines connecting observations.
so.Line(artist_kws=None, **kwargs)
Properties:
color - Line coloralpha - Transparencylinewidth - Line widthlinestyle - Line style ("-", "--", "-.", ":")marker - Marker at data pointspointsize - Marker sizeedgecolor - Marker edge coloredgewidth - Marker edge widthExample:
so.Plot(df, x='x', y='y').add(so.Line())
so.Plot(df, x='x', y='y', color='cat').add(so.Line(linewidth=2))
Like Line but connects points in data order (not sorted by x).
so.Path(artist_kws=None, **kwargs)
Properties same as Line.
Example:
# For trajectories, loops, etc.
so.Plot(trajectory_df, x='x', y='y').add(so.Path())
Rectangular bars.
so.Bar(artist_kws=None, **kwargs)
Properties:
color - Fill coloralpha - Transparencyedgecolor - Edge coloredgealpha - Edge transparencyedgewidth - Edge line widthwidth - Bar width (data units)Example:
so.Plot(df, x='category', y='value').add(so.Bar())
so.Plot(df, x='x', y='y').add(so.Bar(color='#1f77b4', width=0.5))
Multiple bars (for aggregated data with error bars).
so.Bars(artist_kws=None, **kwargs)
Properties same as Bar. Used with Agg() or Est() stats.
Example:
so.Plot(df, x='category', y='value').add(so.Bars(), so.Agg())
Filled area between line and baseline.
so.Area(artist_kws=None, **kwargs)
Properties:
color - Fill coloralpha - Transparencyedgecolor - Edge coloredgealpha - Edge transparencyedgewidth - Edge line widthbaseline - Baseline value (default: 0)Example:
so.Plot(df, x='x', y='y').add(so.Area(alpha=0.3))
so.Plot(df, x='x', y='y', color='cat').add(so.Area())
Filled band between two lines (for ranges/intervals).
so.Band(artist_kws=None, **kwargs)
Properties same as Area. Requires ymin and ymax mappings or used with Est() stat.
Example:
so.Plot(df, x='x', ymin='lower', ymax='upper').add(so.Band())
so.Plot(df, x='x', y='y').add(so.Band(), so.Est())
Line with markers at endpoints (for ranges).
so.Range(artist_kws=None, **kwargs)
Properties:
color - Line and marker coloralpha - Transparencylinewidth - Line widthmarker - Marker style at endpointspointsize - Marker sizeedgewidth - Marker edge widthExample:
so.Plot(df, x='x', y='y').add(so.Range(), so.Est())
Short horizontal/vertical lines (for distribution marks).
so.Dash(artist_kws=None, **kwargs)
Properties:
color - Line coloralpha - Transparencylinewidth - Line widthwidth - Dash length (data units)Example:
so.Plot(df, x='category', y='value').add(so.Dash())
Text labels at data points.
so.Text(artist_kws=None, **kwargs)
Properties:
color - Text coloralpha - Transparencyfontsize - Font sizehalign - Horizontal alignment: "left", "center", "right"valign - Vertical alignment: "bottom", "center", "top"offset - (x, y) offset from pointRequires text mapping.
Example:
so.Plot(df, x='x', y='y', text='label').add(so.Text())
so.Plot(df, x='x', y='y', text='value').add(so.Text(fontsize=10, offset=(0, 5)))
Stats transform data before rendering. Compose with marks in .add().
Aggregate observations by group.
so.Agg(func='mean')
Parameters:
func - Aggregation function: "mean", "median", "sum", "min", "max", "count", or callableExample:
so.Plot(df, x='category', y='value').add(so.Bar(), so.Agg('mean'))
so.Plot(df, x='x', y='y', color='group').add(so.Line(), so.Agg('median'))
Estimate central tendency with error intervals.
so.Est(func='mean', errorbar=('ci', 95), n_boot=1000, seed=None)
Parameters:
func - Estimator: "mean", "median", "sum", or callableerrorbar - Error representation:
("ci", level) - Confidence interval via bootstrap("pi", level) - Percentile interval("se", scale) - Standard error scaled by factor"sd" - Standard deviationn_boot - Bootstrap iterationsseed - Random seedExample:
so.Plot(df, x='category', y='value').add(so.Bar(), so.Est())
so.Plot(df, x='x', y='y').add(so.Line(), so.Est(errorbar='sd'))
so.Plot(df, x='x', y='y').add(so.Line(), so.Est(errorbar=('ci', 95)))
so.Plot(df, x='x', y='y').add(so.Band(), so.Est())
Bin observations and count/aggregate.
so.Hist(stat='count', bins='auto', binwidth=None, binrange=None,
common_norm=True, common_bins=True, cumulative=False)
Parameters:
stat - "count", "density", "probability", "percent", "frequency"bins - Number of bins, bin method, or edgesbinwidth - Width of binsbinrange - (min, max) range for binningcommon_norm - Normalize across groups togethercommon_bins - Use same bins for all groupscumulative - Cumulative histogramExample:
so.Plot(df, x='value').add(so.Bars(), so.Hist())
so.Plot(df, x='value').add(so.Bars(), so.Hist(bins=20, stat='density'))
so.Plot(df, x='value', color='group').add(so.Area(), so.Hist(cumulative=True))
Kernel density estimate.
so.KDE(bw_method='scott', bw_adjust=1, gridsize=200,
cut=3, cumulative=False)
Parameters:
bw_method - Bandwidth method: "scott", "silverman", or scalarbw_adjust - Bandwidth multipliergridsize - Resolution of density curvecut - Extension beyond data range (in bandwidth units)cumulative - Cumulative densityExample:
so.Plot(df, x='value').add(so.Line(), so.KDE())
so.Plot(df, x='value', color='group').add(so.Area(alpha=0.5), so.KDE())
so.Plot(df, x='x', y='y').add(so.Line(), so.KDE(bw_adjust=0.5))
Count observations per group.
so.Count()
Example:
so.Plot(df, x='category').add(so.Bar(), so.Count())
Polynomial regression fit.
so.PolyFit(order=1)
Parameters:
order - Polynomial order (1 = linear, 2 = quadratic, etc.)Example:
so.Plot(df, x='x', y='y').add(so.Dot())
so.Plot(df, x='x', y='y').add(so.Line(), so.PolyFit(order=2))
Compute percentiles.
so.Perc(k=5, method='linear')
Parameters:
k - Number of percentile intervalsmethod - Interpolation methodExample:
so.Plot(df, x='x', y='y').add(so.Band(), so.Perc())
Moves adjust positions to resolve overlaps or create specific layouts.
Shift positions side-by-side.
so.Dodge(empty='keep', gap=0)
Parameters:
empty - How to handle empty groups: "keep", "drop", "fill"gap - Gap between dodged elements (proportion)Example:
so.Plot(df, x='category', y='value', color='group').add(so.Bar(), so.Dodge())
so.Plot(df, x='cat', y='val', color='hue').add(so.Dot(), so.Dodge(gap=0.1))
Stack marks vertically.
so.Stack()
Example:
so.Plot(df, x='x', y='y', color='category').add(so.Bar(), so.Stack())
so.Plot(df, x='x', y='y', color='group').add(so.Area(), so.Stack())
Add random noise to positions.
so.Jitter(width=None, height=None, seed=None)
Parameters:
width - Jitter in x direction (data units or proportion)height - Jitter in y directionseed - Random seedExample:
so.Plot(df, x='category', y='value').add(so.Dot(), so.Jitter())
so.Plot(df, x='cat', y='val').add(so.Dot(), so.Jitter(width=0.2))
Shift positions by constant amount.
so.Shift(x=0, y=0)
Parameters:
x - Shift in x direction (data units)y - Shift in y directionExample:
so.Plot(df, x='x', y='y').add(so.Dot(), so.Shift(x=1))
Normalize values.
so.Norm(func='max', where=None, by=None, percent=False)
Parameters:
func - Normalization: "max", "sum", "area", or callablewhere - Apply to which axis: "x", "y", or Noneby - Grouping variables for separate normalizationpercent - Show as percentageExample:
so.Plot(df, x='x', y='y', color='group').add(so.Area(), so.Norm())
Scales control how data values map to visual properties.
For numeric data.
so.Continuous(values=None, norm=None, trans=None)
Methods:
.tick(at=None, every=None, between=None, minor=None) - Configure ticks.label(like=None, base=None, unit=None) - Format labelsParameters:
values - Explicit value range (min, max)norm - Normalization functiontrans - Transformation: "log", "sqrt", "symlog", "logit", "pow10", or callableExample:
p.scale(
x=so.Continuous().tick(every=10),
y=so.Continuous(trans='log').tick(at=[1, 10, 100]),
color=so.Continuous(values=(0, 1)),
pointsize=(5, 20) # Shorthand for Continuous range
)
For categorical data.
so.Nominal(values=None, order=None)
Parameters:
values - Explicit values (e.g., colors, markers)order - Category orderExample:
p.scale(
color=so.Nominal(['#1f77b4', '#ff7f0e', '#2ca02c']),
marker=so.Nominal(['o', 's', '^']),
x=so.Nominal(order=['Low', 'Medium', 'High'])
)
For datetime data.
so.Temporal(values=None, trans=None)
Methods:
.tick(every=None, between=None) - Configure ticks.label(concise=False) - Format labelsExample:
p.scale(x=so.Temporal().tick(every=('month', 1)).label(concise=True))
(
so.Plot(df, x='total_bill', y='tip', color='time')
.add(so.Dot(), alpha=0.5)
.add(so.Line(), so.PolyFit(order=2))
.scale(color=so.Nominal(['#1f77b4', '#ff7f0e']))
.label(x='Total Bill ($)', y='Tip ($)', title='Tips Analysis')
.theme({**sns.axes_style('whitegrid')})
)
(
so.Plot(df, x='measurement', color='treatment')
.facet(col='timepoint', wrap=3)
.add(so.Area(alpha=0.5), so.KDE())
.add(so.Dot(), so.Jitter(width=0.1), y=0)
.scale(x=so.Continuous().tick(every=5))
.label(x='Measurement (units)', title='Treatment Effects Over Time')
.share(x=True, y=False)
)
(
so.Plot(df, x='category', y='value', color='group')
.add(so.Bar(), so.Agg('mean'), so.Dodge())
.add(so.Range(), so.Est(errorbar='se'), so.Dodge())
.scale(color=so.Nominal(order=['A', 'B', 'C']))
.label(y='Mean Value', title='Comparison by Category and Group')
)
(
so.Plot(df, x='date', y='value')
.add(so.Dot(color='gray', pointsize=3), alpha=0.3)
.add(so.Line(color='blue', linewidth=2), so.Agg('mean'))
.add(so.Band(color='blue', alpha=0.2), so.Est(errorbar=('ci', 95)))
.facet(col='sensor', row='location')
.scale(
x=so.Temporal().label(concise=True),
y=so.Continuous().tick(every=10)
)
.label(
x='Date',
y='Measurement',
title='Sensor Measurements by Location'
)
.layout(size=(12, 8), engine='constrained')
)
Function interface:
sns.scatterplot(data=df, x='x', y='y', hue='category', size='value')
Objects interface:
so.Plot(df, x='x', y='y', color='category', pointsize='value').add(so.Dot())
Function interface:
sns.lineplot(data=df, x='time', y='measurement', hue='group', errorbar='ci')
Objects interface:
(
so.Plot(df, x='time', y='measurement', color='group')
.add(so.Line(), so.Est())
)
Function interface:
sns.histplot(data=df, x='value', hue='category', stat='density', kde=True)
Objects interface:
(
so.Plot(df, x='value', color='category')
.add(so.Bars(), so.Hist(stat='density'))
.add(so.Line(), so.KDE())
)
Function interface:
sns.barplot(data=df, x='category', y='value', hue='group', errorbar='ci')
Objects interface:
(
so.Plot(df, x='category', y='value', color='group')
.add(so.Bar(), so.Agg(), so.Dodge())
.add(so.Range(), so.Est(), so.Dodge())
)
.add() calls to overlay different marks.add(mark, stat, move), stat applies first, then movecolor=(min, max) vs full Scale object.show() otherwise.save() rather than plt.savefig() for proper handling.on(ax) to integrate with matplotlib figures