| 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 | 0 | |
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. Thequantilesparameter that replacesdraw_quantilesnow 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$labelsproperty (@teunbrand, [#5894]). - In binning stats, the default
boundaryis now chosen to better adhere to thenbinargument. 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
sizetolinewidthtranslation ingeom_bar()/geom_col()(#4848). - The
fattenargument 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 thedirargument for additional control over panel directions. They absorb interactions with the now-deprecatedas.tableargument. Internallydir = "h"ordir = "v"is deprecated (@teunbrand, [#5212]).coord_trans()was renamed tocoord_transform()(@nmercadeb, [#5825]).
Improvements
Themes
- The
theme()function offers new arguments:geomto set defaults for layer aesthetics (#2239).spacing/marginsas root elements that are inherited by all other spacings and (non-text) margins (@teunbrand, #5622).palette.{aes}.discreteandpalette.{aes}.continuouswhich 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.widthsandpanel.heightsto control the (absolute) size of the panels (#5338, @teunbrand).legend.key.justificationto control the alignment of legend keys (@teunbrand, #3669)
- Built-in
theme_*()functions have new arguments:ink/paper/accentto control foreground, background and highlight colours respectively of the whole plot (@teunbrand, #6063, @EvaMaeRey, #6438).header_familyto easily set the font for headers and titles (#5886)- To accommodate,
plot.subtitle,plot.captionandplot.tagnow inherit from the roottextelement instead of thetitleelement.
- 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
fillof thepanel.bordertheme 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.gridhierarchy level instead of thepanel.grid.majorandpanel.grid.minorlevels.
- 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
paletteargument. The default,palette = NULLwill retrieve palettes from the theme (see the Themes section). This replaces the old options-basedtypesystem, with some limited backward compatibility (@teunbrand, [#6064]). - All scales now expose the
aestheticsparameter (@teunbrand, [#5841]) - All position scales now use the same definition of
xandyaesthetics. This lets uncommon aesthetics likexinterceptexpand scales as usual. (#3342, [#4966], @teunbrand) - In continuous scales, when
breaksis a function andn.breaksis set, then.breakswill be passed to thebreaksfunction. Previously,n.breaksonly applied to the default break calculation (@teunbrand, [#5972]). - Changes in discrete scales:
- Added
paletteargument, which can be used to customise spacings between levels (@teunbrand, #5770) - Added
continuous.limitsargument to control the display range (@teunbrand, #4174, #6259). - Added
minor_breaksargument. This only makes sense in position scales, where it affects the placement of minor ticks and minor gridlines (#5434). - Added
sec.axisargument. 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
breaksyields a named vector, the names will be used aslabelsby 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_breaksanddate_labelsarguments 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
reverseargument incoord_cartesian(),coord_fixed(),coord_radial()andcoord_sf(). Incoord_radial(), this replaces the olderdirectionargument (#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 bothxandyis 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_xandnudge_yaesthetics (#3026, #5445).position_dodge()gainsorderaesthetic (#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_quantilesargument (#5912).- New parameters for
geom_label()(@teunbrand and @steveharoz, [#5365]): - The
linewidthaesthetic is now applied and replaces thelabel.sizeargument. - The
linetypeaesthetic is now applied. - New
border.colourargument to set the colour of borders. - New
text.colourargument 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,slopeandinterceptare new computed variables instat_qq_line()(@teunbrand, [#6087]). stat_ecdf()now has an optionalweightaesthetic (@teunbrand, [#5058]).stat_ellipsenow 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 = NAis now interpreted to mean 'no line' instead of raising errors (@teunbrand, [#6269]).position_dodge()andposition_jitterdodge()now have areverseargument (@teunbrand, [#3610])position_jitterdodge()now dodges bygroup(@teunbrand, [#3656])geom_rect()can now derive the required corners positions fromx/widthory/heightparameterisation (@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.fillparameter 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 varyingfilloralphain 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/centerparametrisation rather thanorigin, following instat_bin()'s footsteps (@teunbrand). - Reintroduced
dropargument 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 havepositionargument (@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.insideandlegend.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 anangleargument 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 offpositionandavailable_aesparameters downstream (@teunbrand, [#5930]).guide_axis()no longer reserves space for blank ticks (@teunbrand, [#4722], [#6069]).- Fixed regression in axes where
breaks = NULLcaused 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_breaksordate_labelsare not strings (@RodDalBen, [#5880]) - Secondary axes respect
n.breakssetting in continuous scales (@teunbrand, [#4483]). - The size of the
draw_key_polygon()glyph now reflects thelinewidthaesthetic which internally defaults to 0 (#4852). draw_key_rect()replaces aNAfill by thecolouraesthetic (@teunbrand, [#5385], [#5756]).- Fixed bug where
na.valuewas incorrectly mapped to non-NAvalues (@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 thebreaksargument. In addition,n.breaksworks as intended andbreaks = NULLremoves 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 theorientationargument (@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
separameter in layers withgeom = "smooth"will beTRUEwhen the data hasyminandymaxparameters andFALSEif 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 ignoreswidthparameter (@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 containedNAs (@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
@aestheticsthat 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 = NULLand 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_paramsto interact with the panel_params setted by Coord object (@Yunuuuu, [#6397], [#6380]) continuous_scale()andbinned_scale()sort thelimitsargument internally (@teunbrand).Scale$get_labels()format expressions as lists.- Using
after_scale()in theGeom*$default_aesfield 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
ggclass 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 allxvalues 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.widthandlegend.key.heightcalculations 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).