Name | Modified | Size | Downloads / Week |
---|---|---|---|
Parent folder | |||
ggplot2 4.0.0 source code.tar.gz | 2025-08-19 | 3.5 MB | |
ggplot2 4.0.0 source code.zip | 2025-08-19 | 4.3 MB | |
README.md | 2025-08-19 | 22.8 kB | |
Totals: 3 Items | 7.9 MB | 27 |
User facing
Breaking changes
- The S3 parts of ggplot2 have been replaced with S7 bits (#6352).
- (breaking)
geom_violin(quantiles)
now has actual quantiles based on the data, rather than inferred quantiles based on the computed density. Thequantiles
parameter that replacesdraw_quantiles
now belongs tostat_ydensity()
instead ofgeom_violin()
(@teunbrand, [#4120]). - (Breaking) The defaults for all geoms can be set at one in the theme.
(@teunbrand based on pioneering work by @dpseidel, [#2239])
- A new
theme(geom)
argument is used to track these defaults. - The
element_geom()
function can be used to populate that argument. - The
from_theme()
function allows access to the theme default fields from inside theaes()
function.
- A new
- Moved the following packages in the description. If your package depended on
ggplot2 to install these dependencies, you may need to list these in your
own DESCRIPTION file now (#5986).
- Moved mgcv from Imports to Suggests
- Moved tibble from Imports to Suggests
- Removed glue dependency
- Default labels are derived in
build_ggplot()
(previouslyggplot_build()
) rather than in the layer method ofupdate_ggplot()
(previouslyggplot_add.Layer()
). This may affect code that accessed theplot$labels
property (@teunbrand, [#5894]). - In binning stats, the default
boundary
is now chosen to better adhere to thenbin
argument. This may affect plots that use default binning (@teunbrand, [#5882], [#5036])
Lifecycle changes
- Deprecated functions and arguments prior to ggplot2 3.0.0 throw errors instead of warnings.
- Functions and arguments that were soft-deprecated up to ggplot2 3.4.0 now throw warnings.
annotation_borders()
replaces the now-deprecatedborders()
(@teunbrand, [#6392])- Turned off fallback for
size
tolinewidth
translation ingeom_bar()
/geom_col()
(#4848). - The
fatten
argument has been deprecated ingeom_boxplot()
,geom_crossbar()
andgeom_pointrange()
(@teunbrand, [#4881]). - The following methods have been deprecated:
fortify.lm()
,fortify.glht()
,fortify.confint.glht()
,fortify.summary.glht()
andfortify.cld()
. It is recommend to usebroom::augment()
andbroom::tidy()
instead (@teunbrand, [#3816]). geom_errorbarh()
is deprecated in favour ofgeom_errorbar(orientation = "y")
(@teunbrand, [#5961]).- Special getter and setter functions have been renamed for consistency, allowing
for better tab-completion with
get_*
- andset_*
-prefixes. The old names remain available for backward compatibility (@teunbrand, [#5568]).
New name | Old name |
---|---|
get_theme() |
theme_get() |
set_theme() |
theme_set() |
replace_theme() |
theme_replace() |
update_theme() |
theme_update() |
get_last_plot() |
last_plot() |
get_layer_data() |
layer_data() |
get_layer_grob() |
layer_grob() |
get_panel_scales() |
layer_scales() |
facet_wrap()
has new options for thedir
argument for additional control over panel directions. They absorb interactions with the now-deprecatedas.table
argument. Internallydir = "h"
ordir = "v"
is deprecated (@teunbrand, [#5212]).coord_trans()
was renamed tocoord_transform()
(@nmercadeb, [#5825]).
Improvements
Themes
- The
theme()
function offers new arguments:geom
to set defaults for layer aesthetics (#2239).spacing
/margins
as root elements that are inherited by all other spacings and (non-text) margins (@teunbrand, #5622).palette.{aes}.discrete
andpalette.{aes}.continuous
which determine the palettes used when scales havepalette = NULL
. This is the new default for generic scales likescale_colour_discrete()
orscale_fill_continuous()
, see also the 'Scales' section (#4696).panel.widths
andpanel.heights
to control the (absolute) size of the panels (#5338, @teunbrand).legend.key.justification
to control the alignment of legend keys (@teunbrand, #3669)
- Built-in
theme_*()
functions have new arguments:ink
/paper
/accent
to control foreground, background and highlight colours respectively of the whole plot (@teunbrand, #6063, @EvaMaeRey, #6438).header_family
to easily set the font for headers and titles (#5886)- To accommodate,
plot.subtitle
,plot.caption
andplot.tag
now inherit from the roottext
element instead of thetitle
element.
- To accommodate,
- New function family for setting parts of a theme. For example, you can now use
theme_sub_axis(line, text, ticks, ticks.length, line)
as a substitute fortheme(axis.line, axis.text, axis.ticks, axis.ticks.length, axis.line)
. This should allow slightly terser and more organised theme declarations (@teunbrand, [#5301]). - Adjustments to margins (#6115):
- They can have NA-units, which indicate that the value should be inherited from the parent element.
- New
margin_part()
function that comes pre-populated with NA-units, so you can change a single margin without worrying that the others look off. - New
margin_auto()
that recycles arguments in a CSS like fashion.
- The
fill
of thepanel.border
theme setting is ignored and forced to be transparent (#5782). theme_classic()
has the following changes (@teunbrand, [#5978] & [#6320]):- Axis ticks are now black (
ink
-coloured) instead of dark gray. - Axis line ends are now
"square"
. - The panel grid is now blank at the
panel.grid
hierarchy level instead of thepanel.grid.major
andpanel.grid.minor
levels.
- Axis ticks are now black (
- The
theme(legend.spacing.{x/y})
setting now acceptsnull
-units (@teunbrand, [#6417]).
Scales
- The default colour and fill scales have a new
palette
argument. The default,palette = NULL
will retrieve palettes from the theme (see the Themes section). This replaces the old options-basedtype
system, with some limited backward compatibility (@teunbrand, [#6064]). - All scales now expose the
aesthetics
parameter (@teunbrand, [#5841]) - All position scales now use the same definition of
x
andy
aesthetics. This lets uncommon aesthetics likexintercept
expand scales as usual. (#3342, [#4966], @teunbrand) - In continuous scales, when
breaks
is a function andn.breaks
is set, then.breaks
will be passed to thebreaks
function. Previously,n.breaks
only applied to the default break calculation (@teunbrand, [#5972]). - Changes in discrete scales:
- Added
palette
argument, which can be used to customise spacings between levels (@teunbrand, #5770) - Added
continuous.limits
argument to control the display range (@teunbrand, #4174, #6259). - Added
minor_breaks
argument. This only makes sense in position scales, where it affects the placement of minor ticks and minor gridlines (#5434). - Added
sec.axis
argument. Discrete scales don't support transformations so it is recommended to usedup_axis()
to set custom breaks or labels. Secondary discrete axes work with the continuous analogues of discrete breaks (@teunbrand, #3171) - When
breaks
yields a named vector, the names will be used aslabels
by default (@teunbrand, #6147).
- Added
- Changes in date/time scales:
- <POSIXct> is silently cast to <Date> in date scales. Vice versa, <Date> is cast to <POSIXct> in datetime scales (@laurabrianna, #3533)
- Bare numeric provided to date or datetime scales get inversely transformed (i.e. cast to <Date>/<POSIXct>) with a warning (@teunbrand)
- The
date_breaks
,date_minor_breaks
anddate_labels
arguments have been copied over toscale_{x/y}_time()
(@teunbrand, #4335).
- More stability for vctrs-based palettes (@teunbrand, [#6117]).
- Scale names, guide titles and aesthetic labels can now accept functions (@teunbrand, [#4313])
Coords
- Reversal of a dimension, typically 'x' or 'y', is now controlled by the
reverse
argument incoord_cartesian()
,coord_fixed()
,coord_radial()
andcoord_sf()
. Incoord_radial()
, this replaces the olderdirection
argument (#4021, @teunbrand). coord_*(expand)
can now take a logical vector to control expansion at any side of the panel (top, right, bottom, left) (@teunbrand, [#6020])- New
coord_cartesian(ratio)
argument that absorbs the aspect ratio functionality fromcoord_equal()
andcoord_fixed()
, which are now wrappers forcoord_cartesian()
. - In non-orthogonal coordinate systems (
coord_sf()
,coord_polar()
andcoord_radial()
), using 'AsIs' variables escape transformation when bothx
andy
is an 'AsIs' variable (@teunbrand, [#6205]). - Axis labels are now preserved better when using
coord_sf(expand = TRUE)
and graticule lines are straight but do not meet the edge (@teunbrand, [#2985]). coord_radial(clip = "on")
clips to the panel area when the graphics device supports clipping paths (@teunbrand, [#5952]).coord_radial(r.axis.inside)
can now take a numeric value to control placement of internally placed radius axes (@teunbrand, [#5805]).- Munching in
coord_polar()
andcoord_radial()
now adds more detail, particularly for data-points with a low radius near the center (@teunbrand, [#5023]).
Layers
- Position adjustments can now have auxiliary aesthetics (@teunbrand).
position_nudge()
gainsnudge_x
andnudge_y
aesthetics (#3026, #5445).position_dodge()
gainsorder
aesthetic (#3022, #3345)
- New
stat_connect()
to connect points via steps or other shapes (@teunbrand, [#6228]) - New stat:
stat_manual()
for arbitrary computations (@teunbrand, [#3501]) geom_boxplot()
gains additional arguments to style the colour, linetype and linewidths of the box, whiskers, median line and staples (@teunbrand, [#5126]).geom_violin()
gains additional arguments to style the colour, linetype and linewidths of the quantiles, which replace the now-deprecateddraw_quantiles
argument (#5912).- New parameters for
geom_label()
(@teunbrand and @steveharoz, [#5365]): - The
linewidth
aesthetic is now applied and replaces thelabel.size
argument. - The
linetype
aesthetic is now applied. - New
border.colour
argument to set the colour of borders. - New
text.colour
argument to set the colour of text. - New
layer(layout)
argument to interact with facets (@teunbrand, [#3062]) - New default
geom_qq_line(geom = "abline")
for better clipping in the vertical direction. In addition,slope
andintercept
are new computed variables instat_qq_line()
(@teunbrand, [#6087]). stat_ecdf()
now has an optionalweight
aesthetic (@teunbrand, [#5058]).stat_ellipse
now has an optionalweight
(@teunbrand, [#5272])stat_density()
has the new computed variable:wdensity
, which is calculated as the density times the sum of weights (@teunbrand, [#4176]).linetype = NA
is now interpreted to mean 'no line' instead of raising errors (@teunbrand, [#6269]).position_dodge()
andposition_jitterdodge()
now have areverse
argument (@teunbrand, [#3610])position_jitterdodge()
now dodges bygroup
(@teunbrand, [#3656])geom_rect()
can now derive the required corners positions fromx
/width
ory
/height
parameterisation (@teunbrand, [#5861]).position_dodge(preserve = "single")
now handles multi-row geoms better, such asgeom_violin()
(@teunbrand based on @clauswilke's work, [#2801]).geom_point()
can be dodged vertically by usingposition_dodge(..., orientation = "y")
(@teunbrand, [#5809]).- The
arrow.fill
parameter is now applied to more line-based functions:geom_path()
,geom_line()
,geom_step()
geom_function()
, line geometries ingeom_sf()
andelement_line()
. geom_raster()
now falls back to rendering asgeom_rect()
when coordinates are not linear (#5503).geom_ribbon()
can have varyingfill
oralpha
in linear coordinate systems (@teunbrand, [#4690]).- Standardised the calculation of
width
, which are now implemented as aesthetics (@teunbrand, [#2800], [#3142], [#5740], [#3722]). - All binning stats now use the
boundary
/center
parametrisation rather thanorigin
, following instat_bin()
's footsteps (@teunbrand). - Reintroduced
drop
argument tostat_bin()
(@teunbrand, [#3449]) stat_bin()
now accepts functions for argumentbreaks
(@aijordan, [#4561])after_stat()
andafter_scale()
throw warnings when the computed aesthetics are not of the correct length (#5901).geom_hline()
andgeom_vline()
now haveposition
argument (@yutannihilation, [#4285]).geom_contour()
should be able to recognise a rotated grid of points (@teunbrand, [#4320])
Other
- An attempt is made to use a variable's label attribute as default label (@teunbrand, [#4631])
guide_*()
can now accept two inside legend theme elements:legend.position.inside
andlegend.justification.inside
, allowing inside legends to be placed at different positions. Only inside legends with the same position and justification will be merged (@Yunuuuu, [#6210]).guide_bins()
,guide_colourbar()
andguide_coloursteps()
gain anangle
argument to overrule theme settings, similar toguide_axis(angle)
(@teunbrand, [#4594]).- New argument
labs(dictionary)
to label based on variable name rather than based on aesthetic (@teunbrand, [#5178]) - The
summary()
method for ggplots is now more terse about facets (@teunbrand, [#5989]). facet_wrap()
can havespace = "free_x"
with 1-row layouts andspace = "free_y"
with 1-column layouts (@teunbrand)- Layers can have names (@teunbrand, [#4066]).
- Axis labels are now justified across facet panels (@teunbrand, [#5820])
facet_grid(space = "free")
can now be combined withcoord_fixed()
(@teunbrand, [#4584]).- The ellipsis argument is now checked in
fortify()
,get_alt_text()
,labs()
and several guides. (@teunbrand, [#3196]). ggsave()
can write a multi-page pdf file when provided with a list of plots (@teunbrand, [#5093]).
Bug fixes
- Fixed a bug where the
guide_custom(order)
wasn't working (@teunbrand, [#6195]) - Fixed bug in
guide_custom()
that would throw error withtheme_void()
(@teunbrand, [#5856]). guide_colourbar()
now correctly hands offposition
andavailable_aes
parameters downstream (@teunbrand, [#5930]).guide_axis()
no longer reserves space for blank ticks (@teunbrand, [#4722], [#6069]).- Fixed regression in axes where
breaks = NULL
caused the axes to disappear instead of just rendering the axis line (@teunbrand, [#5816]). - Better handling of the
guide_axis_logticks(negative.small)
parameter when scale limits have small maximum (@teunbrand, [#6121]). - Fixed regression in
guide_bins(reverse = TRUE)
(@teunbrand, [#6183]). - Binned guides now accept expressions as labels (@teunbrand, [#6005])
- Fixed bug where binned scales wouldn't simultaneously accept transformations and function-limits (@teunbrand, [#6144]).
- Fixed bug in out-of-bounds binned breaks (@teunbrand, [#6054])
- Fixed bug where binned guides would keep out-of-bounds breaks (@teunbrand, [#5870])
- Binned scales with zero-width data expand the default limits by 0.1 (@teunbrand, [#5066])
- Date(time) scales now throw appropriate errors when
date_breaks
,date_minor_breaks
ordate_labels
are not strings (@RodDalBen, [#5880]) - Secondary axes respect
n.breaks
setting in continuous scales (@teunbrand, [#4483]). - The size of the
draw_key_polygon()
glyph now reflects thelinewidth
aesthetic which internally defaults to 0 (#4852). draw_key_rect()
replaces aNA
fill by thecolour
aesthetic (@teunbrand, [#5385], [#5756]).- Fixed bug where
na.value
was incorrectly mapped to non-NA
values (@teunbrand, [#5756]). - Missing values from discrete palettes are no longer inappropriately translated (@teunbrand, [#5929]).
- Fixed bug where empty discrete scales weren't recognised as such (@teunbrand, [#5945]).
- Fixed regression with incorrectly drawn gridlines when using
coord_flip()
(@teunbrand, [#6293]). coord_radial()
now displays no axis instead of throwing an error when a scale has no breaks (@teunbrand, [#6271]).coord_radial()
displays minor gridlines now (@teunbrand).- Position scales combined with
coord_sf()
can now use functions in thebreaks
argument. In addition,n.breaks
works as intended andbreaks = NULL
removes grid lines and axes (@teunbrand, [#4622]). coord_sf()
no longer errors when dealing with empty graticules (@teunbrand, [#6052])position_fill()
avoids stacking observations of zero (@teunbrand, [#6338])- Fix a bug in
position_jitterdodge()
where different jitters would be applied to different position aesthetics of the same axis (@teunbrand, [#5818]). - Fixed bug in
position_dodge2()
's identification of range overlaps (@teunbrand, [#5938], [#4327]). geom_ribbon()
now appropriately warns about, and removes, missing values (@teunbrand, [#6243]).- Custom and raster annotation now respond to scale transformations, and can use AsIs variables for relative placement (@teunbrand based on @yutannihilation's prior work, [#3120])
geom_sf()
now accepts shape names for point geometries (@sierrajohnson, [#5808])geom_step()
now supports theorientation
argument (@teunbrand, [#5936]).geom_rug()
prints a warning whenna.rm = FALSE
, as per documentation (@pn317, [#5905])geom_curve()
now appropriately removes missing data instead of throwing errors (@teunbrand, [#5831]).- Improved consistency of curve direction in
geom_curve()
(@teunbrand, [#5069]). geom_abline()
clips to the panel range in the vertical direction too (@teunbrand, [#6086]).- The default
se
parameter in layers withgeom = "smooth"
will beTRUE
when the data hasymin
andymax
parameters andFALSE
if these are absent. Note that this does not affect the default ofgeom_smooth()
orstat_smooth()
(@teunbrand, [#5572]). - The bounded density option in
stat_density()
uses a wider range to prevent discontinuities (#5641). - Fixed bug in
stat_function()
so x-axis title now produced automatically when no data added. (@phispu, [#5647]). stat_summary_2d()
andstat_bin_2d()
now deal with zero-range data more elegantly (@teunbrand, [#6207]).stat_summary_bin()
no longer ignoreswidth
parameter (@teunbrand, [#4647]).- Fixed bug where the
ggplot2::
-prefix did not work withstage()
(@teunbrand, [#6104]). - Passing empty unmapped aesthetics to layers raises a warning instead of throwing an error (@teunbrand, [#6009]).
- Staged expressions are handled more gracefully if legends cannot resolve them (@teunbrand, [#6264]).
theme(strip.clip)
now defaults to"on"
and is independent of Coord clipping (@teunbrand, 5952).- Fixed bug in
facet_grid(margins = TRUE)
when using expresssions (@teunbrand, [#1864]). - Prevented
facet_wrap(..., drop = FALSE)
from throwing spurious errors when a character facetting variable containedNA
s (@teunbrand, [#5485]).
Developer facing
Utilities
- New helper function
gg_par()
to translate ggplot2's interpretation of graphical parameters to {grid}'s interpretation (@teunbrand, [#5866]). - New roxygen tag
@aesthetics
that takes a Geom, Stat or Position class and generates an 'Aesthetics' section. - New
make_constructor()
function that builds a standard constructor for Geom and Stat classes (@teunbrand, [#6142]). - New
element_point()
andelement_polygon()
that can be given totheme(point, polygon)
as an extension point (@teunbrand, [#6248]). - The helper function
is_waiver()
is now exported to help extensions to work withwaiver()
objects (@arcresu, [#6173]). update_geom_defaults()
andupdate_stat_defaults()
have a reset mechanism when usingnew = NULL
and invisible return the previous defaults (#4993).- New
reset_geom_defaults()
andreset_stat_defaults()
to restore all geom or stat default aesthetics at once (@teunbrand, [#5975]). - New function
complete_theme()
to replicate how themes are handled during plot building (#5801). - New function
get_strip_labels()
to retrieve facet labels (@teunbrand, [#4979]) - The ViewScale class has a
make_fixed_copy()
method to permit copying trained position scales (#3441).
Internal changes
- Facet gains a new method
setup_panel_params
to interact with the panel_params setted by Coord object (@Yunuuuu, [#6397], [#6380]) continuous_scale()
andbinned_scale()
sort thelimits
argument internally (@teunbrand).Scale$get_labels()
format expressions as lists.- Using
after_scale()
in theGeom*$default_aes
field is now evaluated in the context of data (@teunbrand, [#6135]) - Improvements to
pal_qualitative()
(@teunbrand, [#5013]) - Panel clipping responsibility moved from Facet class to Coord class through
new
Coord$draw_panel()
method. - Rearranged the code of
Facet$draw_panels()
method (@teunbrand). - Added
gg
class tolabs()
(@phispu, [#5553]). - The plot's layout now has a coord parameter that is used to prevent setting up identical panel parameters more than once (#5427)
- Applying defaults in
geom_sf()
has moved from the internalsf_grob()
toGeomSf$use_defaults()
(@teunbrand). - New
Facet$draw_panel_content()
method for delegating panel assembly (@Yunuuuu, [#6406]). - Layer data can be attenuated with parameter attributes (@teunbrand, [#3175]).
- When facets coerce the faceting variables to factors, the 'ordered' class is dropped (@teunbrand, [#5666]).
stat_align()
skips computation when there is only 1 group and therefore alignment is not necessary (#5788).position_stack()
skips computation when allx
values are unique and therefore stacking is not necessary (#5788).- The summary function of
stat_summary()
andstat_summary_bin()
is setup once in total instead of once per group (@teunbrand, [#5971]) - Removed barriers for using 2D structures as aesthetics (@teunbrand, [#4189]).
- Stricter check on
register_theme_elements(element_tree)
(@teunbrand, [#6162]) - The
legend.key.width
andlegend.key.height
calculations are no longer precomputed before guides are drawn (@teunbrand, [#6339]) - When
validate_subclass()
fails to find a class directly, it tries to retrieve the class via constructor functions (@teunbrand).