Seaborn Objects Interface
The seaborn.objects interface provides a modern, declarative API for building visualizations through composition. This guide covers the complete objects interface introduced in seaborn 0.12+.
Core Concept
The objects interface separates what you want to show (data and mappings) from how to show it (marks, stats, and moves). Build plots by:
- Creating a
Plotobject with data and aesthetic mappings - Adding layers with
.add()combining marks and statistical transformations - Customizing with
.scale(),.label(),.limit(),.theme(), etc. - Rendering with
.show()or.save()
Basic Usage
from seaborn import 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()
Plot Class
The Plot class is the foundation of the objects interface.
Initialization
so.Plot(data=None, x=None, y=None, color=None, alpha=None,
fill=None, fillalpha=None, fillcolor=None, marker=None,
pointsize=None, stroke=None, text=None, **variables)
Parameters:
- data - DataFrame or dict of data vectors
- x, y - Variables for position
- color - Variable for color encoding
- alpha - Variable for transparency
- marker - Variable for marker shape
- pointsize - Variable for point size
- stroke - Variable for line width
- text - Variable for text labels
- **variables - Additional mappings using property names
Examples:
# 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
Methods
add()
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 transformation
- orient - "x", "y", or "v"/"h" for orientation
- legend - Include in legend (True/False)
- data - Override data for this layer
- **variables - Override or add variable mappings
Examples:
# 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)
facet()
Create subplots from categorical variables.
Plot.facet(col=None, row=None, order=None, wrap=None)
Parameters:
- col - Variable for column facets
- row - Variable for row facets
- order - Dict with facet orders (keys: variable names)
- wrap - Wrap columns after this many
Example:
p.facet(col='time', row='sex')
p.facet(col='category', wrap=3)
p.facet(col='day', order={'day': ['Thur', 'Fri', 'Sat', 'Sun']})
pair()
Create pairwise subplots for multiple variables.
Plot.pair(x=None, y=None, wrap=None, cross=True)
Parameters:
- x - Variables for x-axis pairings
- y - Variables for y-axis pairings (if None, uses x)
- wrap - Wrap after this many columns
- cross - 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)
scale()
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
)
limit()
Set axis limits.
Plot.limit(x=None, y=None)
Parameters:
- x - Tuple of (min, max) for x-axis
- y - Tuple of (min, max) for y-axis
Example:
p.limit(x=(0, 100), y=(0, 50))
label()
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'
)
theme()
Apply matplotlib style settings.
Plot.theme(config, **kwargs)
Parameters:
- config - Dict of rcParams or seaborn theme dict
- **kwargs - Individual rcParams
Example:
# Seaborn theme
p.theme({**sns.axes_style('whitegrid'), **sns.plotting_context('talk')})
# Custom rcParams
p.theme({'axes.facecolor': 'white', 'axes.grid': True})
# Individual parameters
p.theme(axes_facecolor='white', font_scale=1.2)
layout()
Configure subplot layout.
Plot.layout(size=None, extent=None, engine=None)
Parameters:
- size - (width, height) in inches
- extent - (left, bottom, right, top) for subplots
- engine - "tight", "constrained", or None
Example:
p.layout(size=(10, 6), engine='constrained')
share()
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
on()
Plot on existing matplotlib figure or axes.
Plot.on(target)
Parameters:
- target - matplotlib Figure or Axes object
Example:
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])
show()
Render and display the plot.
Plot.show(**kwargs)
Parameters: Passed to matplotlib.pyplot.show()
save()
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')
Mark Objects
Marks define how data is visually represented.
Dot
Points/markers for individual observations.
so.Dot(artist_kws=None, **kwargs)
Properties:
- color - Fill color
- alpha - Transparency
- fillcolor - Alternate color property
- fillalpha - Alternate alpha property
- edgecolor - Edge color
- edgealpha - Edge transparency
- edgewidth - Edge line width
- marker - Marker style
- pointsize - Marker size
- stroke - Edge width
Example:
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))
Line
Lines connecting observations.
so.Line(artist_kws=None, **kwargs)
Properties:
- color - Line color
- alpha - Transparency
- linewidth - Line width
- linestyle - Line style ("-", "--", "-.", ":")
- marker - Marker at data points
- pointsize - Marker size
- edgecolor - Marker edge color
- edgewidth - Marker edge width
Example:
so.Plot(df, x='x', y='y').add(so.Line())
so.Plot(df, x='x', y='y', color='cat').add(so.Line(linewidth=2))
Path
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())
Bar
Rectangular bars.
so.Bar(artist_kws=None, **kwargs)
Properties:
- color - Fill color
- alpha - Transparency
- edgecolor - Edge color
- edgealpha - Edge transparency
- edgewidth - Edge line width
- width - 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))
Bars
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())
Area
Filled area between line and baseline.
so.Area(artist_kws=None, **kwargs)
Properties:
- color - Fill color
- alpha - Transparency
- edgecolor - Edge color
- edgealpha - Edge transparency
- edgewidth - Edge line width
- baseline - 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())
Band
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())
Range
Line with markers at endpoints (for ranges).
so.Range(artist_kws=None, **kwargs)
Properties:
- color - Line and marker color
- alpha - Transparency
- linewidth - Line width
- marker - Marker style at endpoints
- pointsize - Marker size
- edgewidth - Marker edge width
Example:
so.Plot(df, x='x', y='y').add(so.Range(), so.Est())
Dash
Short horizontal/vertical lines (for distribution marks).
so.Dash(artist_kws=None, **kwargs)
Properties:
- color - Line color
- alpha - Transparency
- linewidth - Line width
- width - Dash length (data units)
Example:
so.Plot(df, x='category', y='value').add(so.Dash())
Text
Text labels at data points.
so.Text(artist_kws=None, **kwargs)
Properties:
- color - Text color
- alpha - Transparency
- fontsize - Font size
- halign - Horizontal alignment: "left", "center", "right"
- valign - Vertical alignment: "bottom", "center", "top"
- offset - (x, y) offset from point
Requires 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)))
Stat Objects
Stats transform data before rendering. Compose with marks in .add().
Agg
Aggregate observations by group.
so.Agg(func='mean')
Parameters:
- func - Aggregation function: "mean", "median", "sum", "min", "max", "count", or callable
Example:
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'))
Est
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 callable
- errorbar - Error representation:
- ("ci", level) - Confidence interval via bootstrap
- ("pi", level) - Percentile interval
- ("se", scale) - Standard error scaled by factor
- "sd" - Standard deviation
- n_boot - Bootstrap iterations
- seed - Random seed
Example:
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())
Hist
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 edges
- binwidth - Width of bins
- binrange - (min, max) range for binning
- common_norm - Normalize across groups together
- common_bins - Use same bins for all groups
- cumulative - Cumulative histogram
Example:
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))
KDE
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 scalar
- bw_adjust - Bandwidth multiplier
- gridsize - Resolution of density curve
- cut - Extension beyond data range (in bandwidth units)
- cumulative - Cumulative density
Example:
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
Count observations per group.
so.Count()
Example:
so.Plot(df, x='category').add(so.Bar(), so.Count())
PolyFit
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))
Perc
Compute percentiles.
so.Perc(k=5, method='linear')
Parameters:
- k - Number of percentile intervals
- method - Interpolation method
Example:
so.Plot(df, x='x', y='y').add(so.Band(), so.Perc())
Move Objects
Moves adjust positions to resolve overlaps or create specific layouts.
Dodge
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
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())
Jitter
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 direction
- seed - Random seed
Example:
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
Shift positions by constant amount.
so.Shift(x=0, y=0)
Parameters:
- x - Shift in x direction (data units)
- y - Shift in y direction
Example:
so.Plot(df, x='x', y='y').add(so.Dot(), so.Shift(x=1))
Norm
Normalize values.
so.Norm(func='max', where=None, by=None, percent=False)
Parameters:
- func - Normalization: "max", "sum", "area", or callable
- where - Apply to which axis: "x", "y", or None
- by - Grouping variables for separate normalization
- percent - Show as percentage
Example:
so.Plot(df, x='x', y='y', color='group').add(so.Area(), so.Norm())
Scale Objects
Scales control how data values map to visual properties.
Continuous
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 labels
Parameters:
- values - Explicit value range (min, max)
- norm - Normalization function
- trans - Transformation: "log", "sqrt", "symlog", "logit", "pow10", or callable
Example:
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
)
Nominal
For categorical data.
so.Nominal(values=None, order=None)
Parameters:
- values - Explicit values (e.g., colors, markers)
- order - Category order
Example:
p.scale(
color=so.Nominal(['#1f77b4', '#ff7f0e', '#2ca02c']),
marker=so.Nominal(['o', 's', '^']),
x=so.Nominal(order=['Low', 'Medium', 'High'])
)
Temporal
For datetime data.
so.Temporal(values=None, trans=None)
Methods:
- .tick(every=None, between=None) - Configure ticks
- .label(concise=False) - Format labels
Example:
p.scale(x=so.Temporal().tick(every=('month', 1)).label(concise=True))
Complete Examples
Layered Plot with Statistics
(
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')})
)
Faceted Distribution
(
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)
)
Grouped Bar Chart
(
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')
)
Complex Multi-Layer
(
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')
)
Migration from Function Interface
Scatter Plot
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())
Line Plot with CI
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())
)
Histogram
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())
)
Bar Plot with Error Bars
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())
)
Tips and Best Practices
- Method chaining: Each method returns a new Plot object, enabling fluent chaining
- Layer composition: Combine multiple
.add()calls to overlay different marks - Transform order: In
.add(mark, stat, move), stat applies first, then move - Variable priority: Layer-specific mappings override Plot-level mappings
- Scale shortcuts: Use tuples for simple ranges:
color=(min, max)vs full Scale object - Jupyter rendering: Plots render automatically when returned; use
.show()otherwise - Saving: Use
.save()rather thanplt.savefig()for proper handling - Matplotlib access: Use
.on(ax)to integrate with matplotlib figures