We’re extremely pleased to announce the release of ggplot2 3.0.0. This is a major release: it was previously announced as ggplot2 2.3.0, but we decided to increment the version number because there are some big changes under the hood. Most importantly ggplot2 now supports tidy evaluation, which makes it easier to programmatically build plots with ggplot2 in the same way you can programmatically build data manipulation pipelines with dplyr.
Install ggplot2 with:
install.packages("ggplot2")
Breaking changes
In stable, long-standing packages like ggplot2, we put in a lot of effort to make sure that we don’t introduce backward incompatible changes. For this release, that involved testing on five versions of R (3.1 - 3.5) writing a new visual testing package ( vdiffr), running R CMD check on downstream packages (over 6,000 times!), and widely advertising the release to get the community’s help. However, sometimes we do decide that it’s worth breaking a small amount of existing code in the interests of improving future code.
The changes should affect relatively little user code, but have required developers to make changes. A separate post will address developer-facing changes in further detail, however, common errors and ways to work around them can be found in the Breaking changes section of ggplot2’s NEWS. If you discover something missing, please let us know so we can add it.
Tidy evaluation
You can now use
quasiquotation in aes()
, facet_wrap()
, and facet_grid()
.
To support quasiquotation in facetting we’ve added a new helper that works
similarly to aes()
: vars()
, short for variables, so instead of
facet_grid(x + y ~ a + b)
you can now write facet_grid(vars(x, y), vars(a, b))
.
The formula interface won’t go away; but the new vars()
interface is
much easier to program with.
x_var <- quo(wt)
y_var <- quo(mpg)
group_var <- quo(cyl)
ggplot(mtcars, aes(!!x_var, !!y_var)) +
geom_point() +
facet_wrap(vars(!!group_var))
New features
We only touch on a few of the new features in ggplot2 — there are many many more. For a full account of these improvements, please see NEWS. If there’s a feature you particularly like, and you write a blog post about, please share it with us using this form, and we’ll include in a round up post in a month’s time.
sf
Thanks to the help of
Edzer Pebesma and the
r-spatial team, ggplot2 now has full support for simple features through
sf using geom_sf()
and coord_sf()
; it now
automatically aligns CRS across layers, sets up the correct aspect ratio, and
draws a graticule.
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"))
#> Reading layer `nc' from data source `/Users/hadley/R/sf/shape/nc.shp' using driver `ESRI Shapefile'
#> Simple feature collection with 100 features and 14 fields
#> geometry type: MULTIPOLYGON
#> dimension: XY
#> bbox: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> epsg (SRID): 4267
#> proj4string: +proj=longlat +datum=NAD27 +no_defs
ggplot(nc) +
geom_sf() +
annotate("point", x = -80, y = 35, colour = "red", size = 4)
Calculated aesthetics
The new stat()
function offers a cleaner, and better-documented syntax for
calculated-aesthetic variables. This replaces the older approach of surrounding
the variable name with ..
. Instead of using aes(y = ..count..)
, you can use
aes(y = stat(count))
.
This is particularly nice for more complex calculations, as stat()
only needs
to be specified once; e.g. aes(y = stat(count / max(count)))
rather than
aes(y = ..count.. / max(..count..))
.
Tag
In addition to title, subtitle, and caption, a new tag label has been added, for identifying plots. Add a tag with labs(tag = "A")
, style it with the plot.tag
theme element, and control position with the plot.tag.position
theme.
ggplot(mtcars) +
geom_point(aes(disp, mpg)) +
labs(tag = 'A', title = 'Title of this plot')
Layers: geoms, stats, and position adjustments
The new
position_dodge2()
allows you to arrange the horizontal position of plots with variable widths (i.e. bars and rectangles, in addition to box plots). By default, position_dodge2()
preserves the width of each element. You can choose to preserve the total width by setting the preserve
argument to "total"
. Thank you to
Kara Woo for all of her work on this.
ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) +
geom_bar(position = position_dodge2(preserve = "single"))
ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) +
geom_bar(position = position_dodge2(preserve = "total"))
Scales and guides
Several new functions have been added to make it easy to use Viridis colour
scales: scale_colour_viridis_c()
and scale_fill_viridis_c()
for continuous,
and scale_colour_viridis_d()
and scale_fill_viridis_d()
for discrete.
Viridis is also now used as the default colour and fill scale for ordered
factors.
dsamp <- diamonds[sample(nrow(diamonds), 1000), ]
d <- ggplot(dsamp, aes(carat, price)) +
geom_point(aes(colour = clarity))
d + scale_colour_viridis_d()
scale_colour_continuous()
and scale_colour_gradient()
are now controlled by global options ggplot2.continuous.colour
and ggplot2.continuous.fill
. You can set them to "viridis"
to use the viridis colour scale by default:
options(
ggplot2.continuous.colour = "viridis",
ggplot2.continuous.fill = "viridis"
)
v <- ggplot(faithfuld) +
geom_tile(aes(waiting, eruptions, fill = density))
v + scale_fill_continuous()
guide_colorbar()
is more configurable: tick marks and color bar frame can now by styled with arguments ticks.colour
, ticks.linewidth
, frame.colour
, frame.linewidth
, and frame.linetype
.
p <- ggplot(mtcars, aes(wt, mpg))
p + geom_point(aes(colour = cyl)) +
scale_colour_gradient(
low = "white", high = "red",
guide = guide_colorbar(
frame.colour = "black",
ticks.colour = "black"
)
)
Nonstandard aesthetics
Thanks to Claus Wilke, there is significantly improved support for nonstandard aesthetics.
Aesthetics can now be specified independent of the scale name.
ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
geom_density(alpha = 0.7) +
scale_colour_brewer(type = "qual", aesthetics = "fill")
Acknowledgements
This release includes a change to the ggplot2 authors, which now includes Claus Wilke (new), and Lionel Henry, Kara Woo, Thomas Lin Pedersen, and Kohske Takahashi in recognition of their past contributions.
We’re grateful to the 391 people who contributed issues, code and comments: @achalaacharya, @adambajguz, @AdeelH, @adrfantini, @aelwan, @aetiologicCanada, @ajay-d, @alberthkcheng, @alchenist, @alexconingham, @alexgenin, @alistaire47, @andbarker, @andrewdolman, @andrewjpfeiffer, @andzandz11, @aornugent, @aosmith16, @aphalo, @arthur-st, @aschersleben, @awgymer, @Ax3man, @baderstine, @baffelli, @baptiste, @BarkleyBG, @basille, @batpigandme, @batuff, @bbolker, @bbrewington, @beansprout88, @behrman, @ben519, @benediktclaus, @berkorbay, @bfgray3, @bhaskarvk, @billdenney, @bjreisman, @boshek, @botanize, @botaspablo, @bouch-ra, @brianwdavis, @briencj, @brodieG, @bsaul, @bschneidr, @burchill, @buyske, @byapparov, @caijun, @cankutcubuk, @CharlesCara, @Chavelior, @christianhomberg, @cinkova, @ckuenne, @clauswilke, @cooknl, @corytu, @cpsievert, @cregouby, @crsh, @cryanking, @cseveren, @daattali, @danfulop, @daniel-barnett, @dantonnoriega, @DarioBoh, @DarioS, @darrkj, @DarwinAwardWinner, @DasHammett, @datalorax, @davharris, @DavidNash1, @DavyLandman, @dbo99, @ddiez, @delferts, @Demetrio92, @DesiQuintans, @dietrichson, @Dilini-Sewwandi-Rajapaksha, @dipenpatel235, @diplodata, @dirkschumacher, @djrajdev, @dl7631, @dmenne, @DocOfi, @domiden, @dongzhuoer, @dpastoor, @dpmcsuss, @dpprdan, @dpseidel, @DSLituiev, @dvcv, @dylan-stark, @eamoncaddigan, @econandrew, @edgararuiz, @edmundesterbauer, @EdwinTh, @edzer, @eeenilsson, @ekatko1, @elbamos, @elina800, @elinw, @eliocamp, @Emaasit, @emilelatour, @Enchufa2, @erocoar, @espinielli, @everydayduffy, @ewallace, @FabianRoger, @FelixMailoa, @FlordeAzahar, @flying-sheep, @fmassicano, @foldager, @foo-bar-baz-qux, @francoisturcot, @Freguglia, @frostell, @gfiumara, @GG786, @ggrothendieck, @ghost, @gilleschapron, @GillesSanMartin, @gjabel, @glennstone, @gmbecker, @GoodluckH, @gordocabron, @goyalmunish, @grantmcdermott, @GreenStat, @gregmacfarlane, @gregrs-uk, @GuangchuangYu, @gwarnes-mdsol, @ha0ye, @hadley, @hannes101, @hansvancalster, @hardeepsjohar, @has2k1, @heckendorfc, @hedjour, @Henrik-P, @henrikmidtiby, @hrabel, @hrbrmstr, @huangl07, @HughParsonage, @ibiris, @idavydov, @idemockle, @igordot, @Ilia-Kosenkov, @IndrajeetPatil, @irudnyts, @izahn, @jan-glx, @janvanoeveren, @jarrod-dalton, @jcrada, @jdagilliland, @jemus42, @jenitivecase, @jennybc, @jentjr, @jflycn, @jgoad, @jimdholland, @jimhester, @jnaber, @jnolis, @joacorapela, @joergtrojan, @JoFAM, @johngoldin, @JohnMount, @jonocarroll, @joojala, @jorgher, @josephuses, @joshkehn, @jpilorget, @jrnold, @jrvianna, @jsams, @jsta, @JTapper, @juliasilge, @jvcasillas, @jwdink, @jwhendy, @JWilb, @jzadra, @kamilsi, @karawoo, @karldw, @katrinleinweber, @kaybenleroll, @kenbeek, @kent37, @kevinushey, @kimchpekr, @klmr, @kmace, @krlmlr, @kylebmetrum, @landesbergn, @laurareads, @ldecicco-USGS, @Leoloh, @likanzhan, @lindeloev, @lionel-, @liuwell, @llrs, @LSanselme, @luisDVA, @luwei0917, @MagicForrest, @malcolmbarrett, @mallerhand, @ManuelNeumann, @manuelreif, @MarauderPixie, @mariellep, @Maschette, @mattwilliamson13, @mbergins, @mcol, @mdsumner, @melohr, @mentalplex, @mfoos, @mgacc0, @mgruebsch, @MichaelChirico, @MichaelRatajczak, @mikgh, @mikmart, @MilesMcBain, @mine-cetinkaya-rundel, @mitchelloharawild, @mjbock, @mkoohafkan, @mkuhn, @monikav, @mpancia, @mrtns, @mruessler, @mundl, @mvkorpel, @mwaldstein, @ndphillips, @Nekochef, @nhamilton1980, @nicksolomon, @nipunbatra, @noamross, @Nowosad, @nteetor, @nzxwang, @oneilsh, @ozgen92, @patr1ckm, @pbreheny, @pelotom, @petersorensen, @philstraforelli, @pkq, @pnolain, @Pomido, @powestermark, @pscheid92, @pschloss, @ptoche, @qinzhu, @QuentinRoy, @R180, @ractingmatrix, @RafaRafa, @randomgambit, @raubreywhite, @RawanRadi, @ray-p144, @RegalPlatypus, @Rekyt, @RemmyGuo, @ReneMalenfant, @renozao, @restonslacker, @rlionheart92, @rmatev, @rmatkins, @rmheiberger, @RMHogervorst, @Robinlovelace, @RoelVerbelen, @rohan-shah, @rpruim, @ruaridhw, @Ryo-N7, @sabinfos, @sachinbanugariya, @sahirbhatnagar, @salauer, @sathishsrinivasank, @saudiwin, @schloerke, @seancaodo, @setempler, @sfirke, @sgoodm8, @shippy, @skanskan, @slowkow, @smouksassi, @SomeUser999, @space-echo, @statkclee, @statsandthings, @statsccpr, @sTeamTraen, @stefanedwards, @stephankraut, @SteveMillard, @stla, @svannoy, @swimmingsand, @taraskaduk, @tbradley1013, @tdhock, @Thieffen, @ThierryO, @thjwong, @thk686, @thomashauner, @thomaskvalnes, @thomasp85, @thvasilo, @tiernanmartin, @timgoodman, @timothyslau, @tingtingben, @tjmahr, @toouggy, @topepo, @traversc, @truemoid, @tungmilan, @Tutuchan, @tzoltak, @ulo, @UweBlock, @vadimus202, @VectorPosse, @VikrantDogra, @vnijs, @wch, @wdsteck, @WHMan, @wibeasley, @wkristan, @woodwards, @wpetry, @wxlu718, @xhdong-umd, @yeedle, @yonicd, @yutannihilation, @zeehio, @zhenglei-gao, @zlskidmore, @ZoidbergIII, and @zz77zz.