scientific-skills/seaborn/references/objects_interface.md
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+.
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()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()
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, text=None, **variables)
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 widthtext - Variable for text labels**variables - Additional mappings using property namesExamples:
# 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, **kwargs)
Parameters:
config - Dict of rcParams or seaborn theme dict**kwargs - Individual rcParamsExample:
# 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)
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