v0.13.0 (September 2023)#
This is a major release with a number of important new features and changes. The highlight is a major overhaul to seaborn’s categorical plotting functions, providing them with many new capabilities and better aligning their API with the rest of the library. There is also provisional support for alternate dataframe libraries like polars, a new theme and display configuration system for objects.Plot
, and many smaller bugfixes and enhancements.
Updating is recommended, but users are encouraged to carefully check the outputs of existing code that uses the categorical functions, and they should be aware of some deprecations and intentional changes to the default appearance of the resulting plots (see notes below with API and Defaults tags).
Major enhancements to categorical plots#
Seaborn’s categorical functions have been completely rewritten for this release. This provided the opportunity to address some longstanding quirks as well as to add a number of smaller but much-desired features and enhancements.
Support for numeric and datetime data#
Feature
The categorical functions have historically treated all data as categorical, even when it has a numeric or datetime type. This can now be controlled with the new native_scale
parameter. The default remains False
to preserve existing behavior. But with native_scale=True
, values will be treated as they would by other seaborn or matplotlib functions. Element widths will be derived from the minimum distance between two unique values on the categorical axis.
Additionally, while seaborn previously determined the mapping from categorical values to ordinal positions internally, this is now delegated to matplotlib. The change should mostly be transparent to the user, but categorical plots (even with native_scale=False
) will better align with artists added by other seaborn or matplotlib functions in most cases, and matplotlib’s interactive machinery will work better.
Changes to color defaults and specification#
API Defaults
The categorical functions now act more like the rest of seaborn in that they will produce a plot with a single main color unless the hue
variable is assigned. Previously, there would be an implicit redundant color mapping (e.g., each box in a boxplot would get a separate color from the default palette). To retain the previous behavior, explicitly assign a redundant hue
variable (e.g., boxplot(data, x="x", y="y", hue="x")
).
Two related idiosyncratic color specifications are deprecated, but they will continue to work (with a warning) for one release cycle:
Passing a
palette
without explicitly assigninghue
is no longer supported (add an explicitly redundanthue
assignment instead).Passing a
color
while assigninghue
to produce a gradient is no longer supported (usepalette="dark:{color}"
orpalette="light:{color}"
instead).
Finally, like other seaborn functions, the default palette now depends on the variable type, and a sequential palette will be used with numeric data. To retain the previous behavior, pass the name of a qualitative palette (e.g., palette="deep"
for seaborn’s default). Accordingly, the functions have gained a parameter to control numeric color mappings (hue_norm
).
Other features, enhancements, and changes#
The following updates apply to multiple categorical functions.
Feature All functions now accept a
legend
parameter, which can be a boolean (to suppress the legend) or one of{"auto", "brief", "full"}
to control the amount of information shown in the legend for a numerical color mapping.Feature All functions now accept a callable
formatter
parameter to control the string representation of the data.Feature All functions that draw a solid patch now accept a boolean
fill
parameter, which when set toFalse
will draw line-art elements.Feature All functions that support dodging now have an additional
gap
parameter that can be set to a non-zero value to leave space between dodged elements.Feature The
boxplot()
,boxenplot()
, andviolinplot()
functions now support a singlelinecolor
parameter.Enhancement The default value for
dodge
has changed fromTrue
to"auto"
. With"auto"
, elements will dodge only when at least one set of elements would otherwise overlap.Enhancement When the value axis of the plot has a non-linear scale, the statistical operations (e.g. an aggregation in
pointplot()
or the kernel density fit inviolinplot()
) are now applied in that scale space.Enhancement All functions now accept a
log_scale
parameter. With a single argument, this will set the scale on the “value” axis (opposite the categorical axis). A tuple will set each axis directly (although setting a log scale categorical axis also requiresnative_scale=True
).Enhancement The
orient
parameter now accepts"x"/"y"
to specify the categorical axis, matching the objects interface.Enhancement The categorical functions are generally more deferential to the user’s additional matplotlib keyword arguments.
API Using
"gray"
to select an automatic gray value that complements the main palette is now deprecated in favor of"auto"
.
The following updates are function-specific.
API Feature In
pointplot()
, a singlematplotlib.lines.Line2D
artist is now used rather than adding separatematplotlib.collections.PathCollection
artist for the points. As a result, it is now possible to pass additional keyword arguments for complete customization the appearance of both the lines and markers; additionally, the legend representation is improved. Accordingly, parameters that previously allowed only partial customization (scale
,join
, anderrwidth
) are now deprecated. The old parameters will now trigger detailed warning messages with instructions for adapting existing code.API Feature The bandwidth specification in
violinplot()
better aligns withkdeplot()
, as thebw
parameter is now deprecated in favor ofbw_method
andbw_adjust
.API Enhancement In
boxenplot()
, the boxen are now drawn with separate patch artists in each tail. This may have consequences for code that works with the underlying artists, but it produces a better result for low-alpha / unfilled plots and enables proper area/density scaling.API Enhancement In
barplot()
, theerrcolor
anderrwidth
parameters are now deprecated in favor of a more generalerr_kws`
dictionary. The existing parameters will continue to work for two releases.API In
violinplot()
, thescale
andscale_hue
parameters have been renamed todensity_norm
andcommon_norm
for clarity and to reflect the fact that common normalization is now applied over both hue and faceting variables incatplot()
.API In
boxenplot()
, thescale
parameter has been renamed towidth_method
as part of a broader effort to de-confound the meaning of “scale” in seaborn parameters.Defaults Enhancement When passing a vector to the
data
parameter ofbarplot()
orpointplot()
, a bar or point will be drawn for each entry in the vector rather than plotting a single aggregated value. To retain the previous behavior, assign the vector to they
variable.Defaults Enhancement In
boxplot()
, the default flier marker now follows the matplotlib rcparams so that it can be globally customized.Defaults Enhancement When using
split=True
andinner="box"
inviolinplot()
, a separate mini-box is now drawn for each split violin.Defaults Enhancement In
boxenplot()
, all plots now use a consistent luminance ramp for the different box levels. This leads to a change in the appearance of existing plots, but reduces the chances of a misleading result.Defaults Enhancement The
"area"
scaling inboxenplot()
now approximates the density of the underlying observations, including for asymmetric distributions. This produces a substantial change in the appearance of plots withwidth_method="area"
, although the existing behavior was poorly defined.Feature In
countplot()
, the newstat
parameter can be used to apply a normalization (e.g to show a"percent"
or"proportion"
).Feature The
split
parameter inviolinplot()
is now more general and can be set toTrue
regardless of the number ofhue
variable levels (or even withouthue
). This is probably most useful for showing half violins.Feature In
violinplot()
, the newinner_kws
parameter allows additional control over the interior artists.Enhancement It is no longer required to use a
DataFrame
incatplot()
, as data vectors can now be passed directly.Enhancement In
boxplot()
, the artists that comprise each box plot are now packaged in aBoxPlotContainer
for easier post-plotting access.
Support for alternate dataframe libraries#
Feature Nearly all functions / objects now use the dataframe exchange protocol to accept
DataFrame
objects from libraries other thanpandas
(e.g.polars
). Note that seaborn will still convert the data object to pandas internally, but this feature will simplify code for users of other dataframe libraries (#3369).
Improved configuration for the objects interface#
Feature Added control over the default theme to
objects.Plot
(#3223)Feature Added control over the default notebook display to
objects.Plot
(#3225).Feature Added the concept of a “layer legend” in
objects.Plot
via the newlabel
parameter inobjects.Plot.add()
(#3456).Enhancement In
objects.Plot.scale()
,objects.Plot.limit()
, andobjects.Plot.label()
thex
/y
parameters can be used to set a common scale / limit / label for paired subplots (#3458).
Other updates#
Enhancement Improved the legend display for relational and categorical functions to better represent the user’s additional keyword arguments (#3467).
Enhancement In
ecdfplot()
,stat="percent"
is now a valid option (#3336).Enhancement Data values outside the scale transform domain (e.g. non-positive values with a log scale) are now dropped prior to any statistical operations (#3488).
Enhancement In
histplot()
, infinite values are now ignored when choosing the default bin range (#3488).Enhancement There is now generalized support for performing statistics in the appropriate space based on axes scales; previously support for this was spotty and at best worked only for log scales (#3440).
Enhancement Updated
load_dataset()
to use an approach more compatible withpyiodide
(#3234).API Support for array-typed palettes is now deprecated. This was not previously documented as supported, but it worked by accident in a few places (#3452).
API Fix In
histplot()
, treatment of thebinwidth
parameter has changed such that the actual bin width will be only approximately equal to the requested width when that value does not evenly divide the bin range. This fixes an issue where the largest data value was sometimes dropped due to floating point error (#3489).Fix Fixed
objects.Bar
andobjects.Bars
widths when using a nonlinear scale (#3217).Fix Worked around an issue in matplotlib that caused incorrect results in
move_legend()
whenlabels
were provided (#3454).Fix Fixed a bug introduced in v0.12.0 where
histplot()
added a stray emptyBarContainer
(#3246).Fix Fixed a bug where
objects.Plot.on()
would override a figure’s layout engine (#3216).Fix Fixed a bug introduced in v0.12.0 where
lineplot()
with a list of tuples for the keyword argument dashes caused a TypeError (#3316).Fix Fixed a bug in
PairGrid
that caused an exception when the input dataframe had a column multiindex (#3407).Fix Improved a few edge cases when using pandas nullable dtypes (#3394).