v0.12.0 (September 2022)#
Introduction of the objects interface#
This release debuts the seaborn.objects
interface, an entirely new approach to making plots with seaborn. It is the product of several years of design and 16 months of implementation work. The interface aims to provide a more declarative, composable, and extensible API for making statistical graphics. It is inspired by Wilkinson’s grammar of graphics, offering a Pythonic API that is informed by the design of libraries such as ggplot2
and vega-lite
along with lessons from the past 10 years of seaborn’s development.
For more information and numerous examples, see the tutorial chapter and API reference
This initial release should be considered “experimental”. While it is stable enough for serious use, there are definitely some rough edges, and some key features remain to be implemented. It is possible that breaking changes may occur over the next few minor releases. Please be patient with any limitations that you encounter and help the development by reporting issues when you find behavior surprising.
Keyword-only arguments#
API
Seaborn’s plotting functions now require explicit keywords for most arguments, following the deprecation of positional arguments in v0.11.0. With this enforcement, most functions have also had their parameter lists rearranged so that data
is the first and only positional argument. This adds consistency across the various functions in the library. It also means that calling func(data)
will do something for nearly all functions (those that support wide-form data) and that pandas.DataFrame
can be piped directly into a plot. It is possible that the signatures will be loosened a bit in future releases so that x
and y
can be positional, but minimal support for positional arguments after this change will reduce the chance of inadvertent mis-specification (#2804).
Modernization of categorical scatterplots#
This release begins the process of modernizing the categorical plots, beginning with stripplot()
and swarmplot()
. These functions are sporting some enhancements that alleviate a few long-running frustrations (#2413, #2447):
Feature The new
native_scale
parameter allows numeric or datetime categories to be plotted with their original scale rather than converted to strings and plotted at fixed intervals.Feature The new
formatter
parameter allows more control over the string representation of values on the categorical axis. There should also be improved defaults for some types, such as dates.Enhancement It is now possible to assign
hue
when using only one coordinate variable (i.e. onlyx
ory
).Enhancement It is now possible to disable the legend.
The updates also harmonize behavior with functions that have been more recently introduced. This should be relatively non-disruptive, although a few defaults will change:
Defaults The functions now hook into matplotlib’s unit system for plotting categorical data. (Seaborn’s categorical functions actually predate support for categorical data in matplotlib.) This should mostly be transparent to the user, but it may resolve a few edge cases. For example, matplotlib interactivity should work better (e.g., for showing the data value under the cursor).
Defaults A color palette is no longer applied to levels of the categorical variable by default. It is now necessary to explicitly assign
hue
to see multiple colors (i.e., assign the same variable tox
/y
andhue
). Passingpalette
withouthue
will continue to be honored for one release cycle.Defaults Numeric
hue
variables now receive a continuous mapping by default, using the same rules asscatterplot()
. Passpalette="deep"
to reproduce previous defaults.Defaults The plots now follow the default property cycle; i.e. calling an axes-level function multiple times with the same active axes will produce different-colored artists.
API Currently, assigning
hue
and then passing acolor
will produce a gradient palette. This is now deprecated, as it is easy to request a gradient with, e.g.palette="light:blue"
.
Similar enhancements / updates should be expected to roll out to other categorical plotting functions in future releases. There are also several function-specific enhancements:
Enhancement In
stripplot()
, a “strip” with a single observation will be plotted without jitter (#2413)Enhancement In
swarmplot()
, the points are now swarmed at draw time, meaning that the plot will adapt to further changes in axis scaling or tweaks to the plot layout (#2443).Feature In
swarmplot()
, the proportion of points that must overlap before issuing a warning can now be controlled with thewarn_thresh
parameter (#2447).Fix In
swarmplot()
, the order of the points in each swarm now matches the order in the original dataset; previously they were sorted. This affects only the underlying data stored in the matplotlib artist, not the visual representation (#2443).
More flexible errorbars#
API Feature
Increased the flexibility of what can be shown by the internally-calculated errorbars for lineplot()
, barplot()
, and pointplot()
.
With the new errorbar
parameter, it is now possible to select bootstrap confidence intervals, percentile / predictive intervals, or intervals formed by scaled standard deviations or standard errors. The parameter also accepts an arbitrary function that maps from a vector to an interval. There is a new user guide chapter demonstrating these options and explaining when you might want to use each one.
As a consequence of this change, the ci
parameter has been deprecated. Note that regplot()
retains the previous API, but it will likely be updated in a future release (#2407, #2866).
Other updates#
Feature It is now possible to aggregate / sort a
lineplot()
along the y axis usingorient="y"
(#2854).Feature Made it easier to customize
FacetGrid
/PairGrid
/JointGrid
with a fluent (method-chained) style by addingapply
/pipe
methods. Additionally, fixed thetight_layout
andrefline
methods so that they returnself
(#2926).Feature Added
FacetGrid.tick_params()
andPairGrid.tick_params()
to customize the appearance of the ticks, tick labels, and gridlines of all subplots at once (#2944).Enhancement It is now possible to specify
estimator
as a string inbarplot()
andpointplot()
, in addition to a callable (#2866).Enhancement Error bars in
regplot()
now inherit the alpha value of the points they correspond to (#2540).Enhancement When using
pairplot()
withcorner=True
anddiag_kind=None
, the top left y axis label is no longer hidden (#2850).Enhancement It is now possible to plot a discrete
histplot()
as a step function or polygon (#2859).Enhancement It is now possible to customize the appearance of elements in a
boxenplot()
withbox_kws
/line_kws
/flier_kws
(#2909).Fix Improved integration with the matplotlib color cycle in most axes-level functions (#2449).
Fix Fixed a regression in 0.11.2 that caused some functions to stall indefinitely or raise when the input data had a duplicate index (#2776).
Fix Fixed a bug in
histplot()
andkdeplot()
where weights were not factored into the normalization (#2812).Fix Fixed two edgecases in
histplot()
when onlybinwidth
was provided (#2813).Fix Fixed a bug in
violinplot()
where inner boxes/points could be missing with unpaired split violins (#2814).Fix Fixed a bug in
PairGrid
where an error would be raised when defininghue
only in the mapping methods (#2847).Fix Fixed a bug in
scatterplot()
where an error would be raised whenhue_order
was a subset of the hue levels (#2848).Fix Fixed a bug in
histplot()
where dodged bars would have different widths on a log scale (#2849).Fix In
lineplot()
, allowed thedashes
keyword to set the style of a line without mapping astyle
variable (#2449).Fix Improved support in
relplot()
for “wide” data and for faceting variables passed as non-pandas objects (#2846).Fix Subplot titles will no longer be reset when calling
FacetGrid.map()
orFacetGrid.map_dataframe()
(#2705).Fix Added a workaround for a matplotlib issue that caused figure-level functions to freeze when
plt.show
was called (#2925).Fix Improved robustness to numerical errors in
kdeplot()
(#2862).Fix Fixed a bug where
rugplot()
was ignoring expand_margins=False (#2953).Defaults The
patch.facecolor
rc param is no longer set byset_palette()
(orset_theme()
). This should have no general effect, because the matplotlib default is now"C0"
(#2906).Build Made
scipy
an optional dependency and addedpip install seaborn[stats]
as a method for ensuring the availability of compatiblescipy
andstatsmodels
libraries at install time. This has a few minor implications for existing code, which are explained in the Github pull request (#2398).Build Example datasets are now stored in an OS-specific cache location (as determined by
appdirs
) rather than in the user’s home directory. Users should feel free to remove~/seaborn-data
if desired (#2773).Build The unit test suite is no longer part of the source or wheel distribution. Seaborn has never had a runtime API for exercising the tests, so this should not have workflow implications (#2833).
Build Following NEP29, dropped support for Python 3.6 and bumped the minimally-supported versions of the library dependencies.
API Removed the previously-deprecated
factorplot
along with several previously-deprecated utility functions (iqr
,percentiles
,pmf_hist
, andsort_df
).API Removed the (previously-unused) option to pass additional keyword arguments to
pointplot()
.