├── inst ├── staticdocs │ ├── README.md │ ├── footer.html │ └── head.html └── CITATION ├── .gitignore ├── data ├── mpg.rda ├── seals.rda ├── midwest.rda ├── msleep.rda ├── diamonds.rda ├── economics.rda ├── faithfuld.rda ├── txhousing.rda ├── luv_colours.rda ├── presidential.rda └── economics_long.rda ├── .Rbuildignore ├── tests ├── testthat.R └── testthat │ ├── Rplots.pdf │ ├── test-grid-utils.R │ ├── test-guides.R │ ├── test-geom-ribbon.R │ ├── test-geom-boxplot.R │ ├── test-geom-freqpoly.R │ ├── test-stats.r │ ├── test-geom-tile.R │ ├── test-stat-density.R │ ├── test-labels.r │ ├── test-range.r │ ├── test-stat-density2d.R │ ├── test-scale-discrete.R │ ├── test-qplot.r │ ├── helper-plot-data.r │ ├── test-geom-violin.R │ ├── test-geom-text.R │ ├── test-annotate.r │ ├── test-data.r │ ├── test-stats-function.r │ ├── test-stat-bin2d.R │ ├── test-boxplot.r │ ├── test-geom-rule.R │ ├── test-fortify.r │ ├── test-coord-train.r │ ├── test-aes-grouping.r │ ├── test-aes-setting.r │ ├── test-stat-sum.R │ ├── test-facet-.r │ ├── test-sanitise-dim.r │ ├── test-build.r │ ├── test-layer.r │ ├── test-aes.r │ ├── test-utilities.r │ ├── test-ggsave.R │ └── test-coord-polar.r ├── vignettes └── car.png ├── R ├── ggplot2.r ├── aaa-.r ├── position-identity.r ├── plot-last.r ├── position-fill.r ├── geom-freqpoly.r ├── grob-null.r ├── autoplot.r ├── zzz.r ├── bench.r ├── utilities-grid.r ├── range.r ├── fortify.r ├── utilities-resolution.r ├── scale-linetype.r ├── stat-identity.r ├── geom-blank.r ├── hexbin.R ├── utilities-help.r ├── stat-unique.r ├── guides-grid.r ├── position-nudge.R ├── grob-absolute.r ├── summary.r ├── scale-alpha.r ├── utilities-matrix.r ├── coord-quickmap.R ├── utilities-table.r ├── geom-defaults.r ├── scale-shape.r ├── geom-bin2d.r ├── geom-hline.r ├── geom-vline.r ├── scale-grey.r ├── stat-binhex.r ├── stat-sum.r ├── grouping.r ├── geom-pointrange.r ├── aes-calculated.r ├── facet-viewports.r ├── aes-position.r ├── stat-summary-hex.r ├── coord-fixed.r ├── facet-.r ├── geom-spoke.r ├── geom-errorbar.r ├── geom-curve.r ├── grob-dotstack.r ├── scale-type.R ├── coord-flip.r └── aes-colour-fill-alpha.r ├── man ├── is.Coord.Rd ├── zeroGrob.Rd ├── is.rel.Rd ├── is.ggproto.Rd ├── is.theme.Rd ├── ggplotGrob.Rd ├── last_plot.Rd ├── is.ggplot.Rd ├── is.facet.Rd ├── element_blank.Rd ├── dtouter.Rd ├── dtmelt.Rd ├── absoluteGrob.Rd ├── aes_auto.Rd ├── faithfuld.Rd ├── facet.Rd ├── presidential.Rd ├── aes_all.Rd ├── mean_se.Rd ├── should_stop.Rd ├── rel.Rd ├── luv_colours.Rd ├── graphical-units.Rd ├── waiver.Rd ├── element_line.Rd ├── position_identity.Rd ├── add_theme.Rd ├── element_grob.Rd ├── element_rect.Rd ├── summary.ggplot.Rd ├── benchplot.Rd ├── add_margins.Rd ├── transform_position.Rd ├── update_labels.Rd ├── as.list.ggproto.Rd ├── limits.Rd ├── fortify.Rd ├── margin.Rd ├── format.ggproto.Rd ├── facet_null.Rd ├── autoplot.Rd ├── reexports.Rd ├── seals.Rd ├── txhousing.Rd ├── coord_munch.Rd ├── print.ggproto.Rd ├── update_defaults.Rd ├── hmisc.Rd ├── print.ggplot.Rd ├── margins.Rd ├── resolution.Rd ├── expand_limits.Rd ├── mpg.Rd ├── ggplot_gtable.Rd ├── position_nudge.Rd ├── calc_element.Rd ├── fortify.map.Rd ├── remove_missing.Rd ├── scale_linetype.Rd ├── diamonds.Rd ├── ggplot_build.Rd ├── annotation_map.Rd ├── label_bquote.Rd ├── scale_alpha.Rd ├── labs.Rd ├── economics.Rd ├── lims.Rd ├── element_text.Rd ├── msleep.Rd ├── scale_shape.Rd ├── midwest.Rd ├── gg_dep.Rd ├── position_jitterdodge.Rd ├── coord_flip.Rd ├── fortify.sp.Rd ├── fortify-multcomp.Rd ├── scale_grey.Rd ├── coord_fixed.Rd ├── map_data.Rd ├── borders.Rd ├── aes.Rd ├── ggproto.Rd ├── position_jitter.Rd ├── draw_key.Rd ├── as_labeller.Rd ├── aes_position.Rd ├── annotation_custom.Rd ├── annotation_raster.Rd ├── position_dodge.Rd ├── cut_interval.Rd ├── aes_.Rd ├── theme_update.Rd ├── scale_identity.Rd └── guides.Rd ├── lwplot.Rproj ├── old-README-ggplot2.md └── README.md /inst/staticdocs/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | -------------------------------------------------------------------------------- /data/mpg.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/mpg.rda -------------------------------------------------------------------------------- /data/seals.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/seals.rda -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^local 4 | .*\.tar\.gz$ 5 | ^vignettes -------------------------------------------------------------------------------- /data/midwest.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/midwest.rda -------------------------------------------------------------------------------- /data/msleep.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/msleep.rda -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(lwplot) 3 | 4 | test_check("lwplot") 5 | -------------------------------------------------------------------------------- /data/diamonds.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/diamonds.rda -------------------------------------------------------------------------------- /data/economics.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/economics.rda -------------------------------------------------------------------------------- /data/faithfuld.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/faithfuld.rda -------------------------------------------------------------------------------- /data/txhousing.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/txhousing.rda -------------------------------------------------------------------------------- /vignettes/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/vignettes/car.png -------------------------------------------------------------------------------- /data/luv_colours.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/luv_colours.rda -------------------------------------------------------------------------------- /data/presidential.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/presidential.rda -------------------------------------------------------------------------------- /data/economics_long.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/data/economics_long.rda -------------------------------------------------------------------------------- /tests/testthat/Rplots.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddelbuettel/lwplot/HEAD/tests/testthat/Rplots.pdf -------------------------------------------------------------------------------- /R/ggplot2.r: -------------------------------------------------------------------------------- 1 | #' @import scales grid gtable 2 | #' @importFrom plyr defaults 3 | #' @importFrom stats setNames 4 | #' @importFrom data.table melt 5 | NULL 6 | -------------------------------------------------------------------------------- /tests/testthat/test-grid-utils.R: -------------------------------------------------------------------------------- 1 | context("Grid utilites") 2 | 3 | test_that("width_cm and height_cm work with unit arithmetic", { 4 | x <- 2 * unit(1, "cm") 5 | 6 | expect_equal(width_cm(x), 2) 7 | expect_equal(height_cm(x), 2) 8 | }) 9 | -------------------------------------------------------------------------------- /tests/testthat/test-guides.R: -------------------------------------------------------------------------------- 1 | context("Guides") 2 | 3 | test_that("colourbar trains without labels", { 4 | g <- guide_colorbar() 5 | sc <- scale_colour_continuous(limits = c(0, 4), labels = NULL) 6 | 7 | out <- guide_train(g, sc) 8 | expect_equal(names(out$key), c("colour", ".value")) 9 | }) 10 | 11 | -------------------------------------------------------------------------------- /man/is.Coord.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/coord-.r 3 | \name{is.Coord} 4 | \alias{is.Coord} 5 | \title{Is this object a coordinate system?} 6 | \usage{ 7 | is.Coord(x) 8 | } 9 | \description{ 10 | Is this object a coordinate system? 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-ribbon.R: -------------------------------------------------------------------------------- 1 | context("geom_ribbon") 2 | 3 | test_that("NAs are not dropped from the data", { 4 | df <- data.frame(x = 1:5, y = c(1, 1, NA, 1, 1)) 5 | 6 | p <- ggplot(df, aes(x))+ 7 | geom_ribbon(aes(ymin = y - 1, ymax = y + 1)) 8 | 9 | expect_equal(layer_data(p)$ymin, c(0, 0, NA, 0, 0)) 10 | }) 11 | -------------------------------------------------------------------------------- /man/zeroGrob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/grob-null.r 3 | \name{zeroGrob} 4 | \alias{zeroGrob} 5 | \title{The zero grob draws nothing and has zero size.} 6 | \usage{ 7 | zeroGrob() 8 | } 9 | \description{ 10 | The zero grob draws nothing and has zero size. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/is.rel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme-elements.r 3 | \name{is.rel} 4 | \alias{is.rel} 5 | \title{Reports whether x is a rel object} 6 | \usage{ 7 | is.rel(x) 8 | } 9 | \arguments{ 10 | \item{x}{An object to test} 11 | } 12 | \description{ 13 | Reports whether x is a rel object 14 | } 15 | -------------------------------------------------------------------------------- /man/is.ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggproto.r 3 | \name{is.ggproto} 4 | \alias{is.ggproto} 5 | \title{Is an object a ggproto object?} 6 | \usage{ 7 | is.ggproto(x) 8 | } 9 | \arguments{ 10 | \item{x}{An object to test.} 11 | } 12 | \description{ 13 | Is an object a ggproto object? 14 | } 15 | -------------------------------------------------------------------------------- /man/is.theme.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme.r 3 | \name{is.theme} 4 | \alias{is.theme} 5 | \title{Reports whether x is a theme object} 6 | \usage{ 7 | is.theme(x) 8 | } 9 | \arguments{ 10 | \item{x}{An object to test} 11 | } 12 | \description{ 13 | Reports whether x is a theme object 14 | } 15 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-boxplot.R: -------------------------------------------------------------------------------- 1 | context("geom_boxplot") 2 | 3 | test_that("can use US spelling of colour", { 4 | df <- data.frame(x = 1, y = c(1:5, 100)) 5 | plot <- ggplot(df, aes(x, y)) + geom_boxplot(outlier.color = "red") 6 | 7 | gpar <- layer_grob(plot)[[1]]$children[[1]]$children[[1]]$gp 8 | expect_equal(gpar$col, "#FF0000FF") 9 | }) 10 | -------------------------------------------------------------------------------- /man/ggplotGrob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot-build.r 3 | \name{ggplotGrob} 4 | \alias{ggplotGrob} 5 | \title{Generate a ggplot2 plot grob.} 6 | \usage{ 7 | ggplotGrob(x) 8 | } 9 | \arguments{ 10 | \item{x}{ggplot2 object} 11 | } 12 | \description{ 13 | Generate a ggplot2 plot grob. 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-freqpoly.R: -------------------------------------------------------------------------------- 1 | context("freqpoly") 2 | 3 | test_that("can do frequency polygon with categorical x", { 4 | df <- data.frame(x = rep(letters[1:3], 3:1)) 5 | 6 | p <- ggplot(df, aes(x)) + geom_freqpoly(stat = "count") 7 | d <- layer_data(p) 8 | 9 | expect_is(d$x, "integer") 10 | expect_equal(d$x, 1:3) 11 | expect_equal(d$y, 3:1) 12 | }) 13 | -------------------------------------------------------------------------------- /man/last_plot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot-last.r 3 | \name{last_plot} 4 | \alias{last_plot} 5 | \title{Retrieve the last plot to be modified or created.} 6 | \usage{ 7 | last_plot() 8 | } 9 | \description{ 10 | Retrieve the last plot to be modified or created. 11 | } 12 | \seealso{ 13 | \code{\link{ggsave}} 14 | } 15 | -------------------------------------------------------------------------------- /man/is.ggplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.r 3 | \name{is.ggplot} 4 | \alias{is.ggplot} 5 | \title{Reports whether x is a ggplot object} 6 | \usage{ 7 | is.ggplot(x) 8 | } 9 | \arguments{ 10 | \item{x}{An object to test} 11 | } 12 | \description{ 13 | Reports whether x is a ggplot object 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/is.facet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/facet-.r 3 | \name{is.facet} 4 | \alias{is.facet} 5 | \title{Is this object a facetting specification?} 6 | \usage{ 7 | is.facet(x) 8 | } 9 | \arguments{ 10 | \item{x}{object to test} 11 | } 12 | \description{ 13 | Is this object a facetting specification? 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /lwplot.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageInstallArgs: --no-multiarch --with-keep.source 17 | PackageRoxygenize: rd,collate,namespace 18 | -------------------------------------------------------------------------------- /R/aaa-.r: -------------------------------------------------------------------------------- 1 | #' @include ggproto.r 2 | NULL 3 | 4 | #' Base ggproto classes for ggplot2 5 | #' 6 | #' If you are creating a new geom, stat, position, or scale in another package, 7 | #' you'll need to extend from \code{lwplot::Geom}, \code{lwplot::Stat}, 8 | #' \code{lwplot::Position}, or \code{lwplot::Scale}. 9 | #' 10 | #' @seealso ggproto 11 | #' @keywords internal 12 | #' @name ggplot2-ggproto 13 | NULL 14 | -------------------------------------------------------------------------------- /R/position-identity.r: -------------------------------------------------------------------------------- 1 | #' Don't adjust position 2 | #' 3 | #' @family position adjustments 4 | #' @export 5 | position_identity <- function() { 6 | PositionIdentity 7 | } 8 | 9 | #' @rdname ggplot2-ggproto 10 | #' @format NULL 11 | #' @usage NULL 12 | #' @export 13 | PositionIdentity <- ggproto("PositionIdentity", Position, 14 | compute_layer = function(data, params, scales) { 15 | data 16 | } 17 | ) 18 | -------------------------------------------------------------------------------- /man/element_blank.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme-elements.r 3 | \name{element_blank} 4 | \alias{element_blank} 5 | \title{Theme element: blank. 6 | This theme element draws nothing, and assigns no space} 7 | \usage{ 8 | element_blank() 9 | } 10 | \description{ 11 | Theme element: blank. 12 | This theme element draws nothing, and assigns no space 13 | } 14 | -------------------------------------------------------------------------------- /man/dtouter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lwplotAddins.R 3 | \name{dtouter} 4 | \alias{dtouter} 5 | \title{Replacement for reshape on outer} 6 | \usage{ 7 | dtouter(N) 8 | } 9 | \arguments{ 10 | \item{N}{dimension} 11 | } 12 | \value{ 13 | A data.frame corresponding to `melt` on `outer(1:N,1:N)` 14 | } 15 | \description{ 16 | Replacement for reshape on outer 17 | } 18 | -------------------------------------------------------------------------------- /man/dtmelt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lwplotAddins.R 3 | \name{dtmelt} 4 | \alias{dtmelt} 5 | \title{Use data.table::melt} 6 | \usage{ 7 | dtmelt(df, ...) 8 | } 9 | \arguments{ 10 | \item{df}{a data.frame 11 | dimension} 12 | 13 | \item{...}{remaining arguments} 14 | } 15 | \value{ 16 | A melted data.frame 17 | } 18 | \description{ 19 | Use data.table::melt 20 | } 21 | -------------------------------------------------------------------------------- /tests/testthat/test-stats.r: -------------------------------------------------------------------------------- 1 | context("Stats") 2 | 3 | test_that("plot succeeds even if some computation fails", { 4 | df <- data.frame(x = 1:2, y = 1) 5 | p1 <- ggplot(df, aes(x, y)) + geom_point() 6 | 7 | b1 <- ggplot_build(p1) 8 | expect_equal(length(b1$data), 1) 9 | 10 | p2 <- p1 + geom_smooth() 11 | expect_warning(b2 <- ggplot_build(p2), "Computation failed") 12 | expect_equal(length(b2$data), 2) 13 | }) 14 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite ggplot2 in publications, please use:") 2 | 3 | citEntry(entry = "book", 4 | author = "Hadley Wickham", 5 | title = "ggplot2: Elegant Graphics for Data Analysis", 6 | publisher = "Springer-Verlag New York", 7 | year = "2009", 8 | isbn = "978-0-387-98140-6", 9 | url = "http://ggplot2.org", 10 | textVersion = "H. Wickham. ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York, 2009." 11 | ) 12 | -------------------------------------------------------------------------------- /inst/staticdocs/footer.html: -------------------------------------------------------------------------------- 1 |

Back to top

2 | 3 |

What do you think of the documentation? Please let me know by filling out this short online survey.

4 | 5 |

Built by staticdocs. Styled with bootstrap.

6 | -------------------------------------------------------------------------------- /man/absoluteGrob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/grob-absolute.r 3 | \name{absoluteGrob} 4 | \alias{absoluteGrob} 5 | \title{Absolute grob} 6 | \usage{ 7 | absoluteGrob(grob, width = NULL, height = NULL, xmin = NULL, 8 | ymin = NULL, vp = NULL) 9 | } 10 | \description{ 11 | This grob has fixed dimensions and position. 12 | } 13 | \details{ 14 | It's still experimental 15 | } 16 | \keyword{internal} 17 | -------------------------------------------------------------------------------- /man/aes_auto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/aes.r 3 | \name{aes_auto} 4 | \alias{aes_auto} 5 | \title{Automatic aesthetic mapping} 6 | \usage{ 7 | aes_auto(data = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{data}{data.frame or names of variables} 11 | 12 | \item{...}{aesthetics that need to be explicitly mapped.} 13 | } 14 | \description{ 15 | Automatic aesthetic mapping 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/faithfuld.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{faithfuld} 5 | \alias{faithfuld} 6 | \title{2d density estimate of Old Faithful data} 7 | \format{A data frame with 5,625 observations and 3 variables.} 8 | \usage{ 9 | faithfuld 10 | } 11 | \description{ 12 | A 2d density estimate of the waiting and eruptions variables data 13 | \link{faithful}. 14 | } 15 | \keyword{datasets} 16 | -------------------------------------------------------------------------------- /man/facet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/facet-.r 3 | \name{facet} 4 | \alias{facet} 5 | \title{Facet specification.} 6 | \usage{ 7 | facet(..., shrink = TRUE, subclass = c()) 8 | } 9 | \arguments{ 10 | \item{...}{object fields} 11 | 12 | \item{shrink}{shrink scales to fit output of statistics, not raw data} 13 | } 14 | \description{ 15 | Create new facetting specification. For internal use only. 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /R/plot-last.r: -------------------------------------------------------------------------------- 1 | .plot_store <- function() { 2 | .last_plot <- NULL 3 | 4 | list( 5 | get = function() .last_plot, 6 | set = function(value) .last_plot <<- value 7 | ) 8 | } 9 | .store <- .plot_store() 10 | 11 | # Set last plot created or modified 12 | set_last_plot <- function(value) .store$set(value) 13 | 14 | 15 | #' Retrieve the last plot to be modified or created. 16 | #' 17 | #' @seealso \code{\link{ggsave}} 18 | #' @export 19 | last_plot <- function() .store$get() 20 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-tile.R: -------------------------------------------------------------------------------- 1 | context("geom_tile") 2 | 3 | test_that("accepts width and height params", { 4 | df <- data.frame(x = c("a", "b"), y = c("a", "b")) 5 | 6 | out1 <- layer_data(ggplot(df, aes(x, y)) + geom_tile()) 7 | expect_equal(out1$xmin, c(0.5, 1.5)) 8 | expect_equal(out1$xmax, c(1.5, 2.5)) 9 | 10 | out2 <- layer_data(ggplot(df, aes(x, y)) + geom_tile(width = 0.5, height = 0.5)) 11 | expect_equal(out2$xmin, c(0.75, 1.75)) 12 | expect_equal(out2$xmax, c(1.25, 2.25)) 13 | }) 14 | -------------------------------------------------------------------------------- /man/presidential.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{presidential} 5 | \alias{presidential} 6 | \title{Terms of 11 presidents from Eisenhower to Obama.} 7 | \format{A data frame with 11 rows and 4 variables} 8 | \usage{ 9 | presidential 10 | } 11 | \description{ 12 | The names of each president, the start and end date of their term, and 13 | their party of 11 US presidents from Eisenhower to Obama. 14 | } 15 | \keyword{datasets} 16 | -------------------------------------------------------------------------------- /man/aes_all.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/aes.r 3 | \name{aes_all} 4 | \alias{aes_all} 5 | \title{Given a character vector, create a set of identity mappings} 6 | \usage{ 7 | aes_all(vars) 8 | } 9 | \arguments{ 10 | \item{vars}{vector of variable names} 11 | } 12 | \description{ 13 | Given a character vector, create a set of identity mappings 14 | } 15 | \examples{ 16 | aes_all(names(mtcars)) 17 | aes_all(c("x", "y", "col", "pch")) 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/mean_se.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stat-summary.r 3 | \name{mean_se} 4 | \alias{mean_se} 5 | \title{Calculate mean and standard errors on either side.} 6 | \usage{ 7 | mean_se(x, mult = 1) 8 | } 9 | \arguments{ 10 | \item{x}{numeric vector} 11 | 12 | \item{mult}{number of multiples of standard error} 13 | } 14 | \description{ 15 | Calculate mean and standard errors on either side. 16 | } 17 | \seealso{ 18 | for use with \code{\link{stat_summary}} 19 | } 20 | -------------------------------------------------------------------------------- /man/should_stop.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utilities.r 3 | \name{should_stop} 4 | \alias{should_stop} 5 | \title{Used in examples to illustrate when errors should occur.} 6 | \usage{ 7 | should_stop(expr) 8 | } 9 | \arguments{ 10 | \item{expr}{code to evaluate.} 11 | } 12 | \description{ 13 | Used in examples to illustrate when errors should occur. 14 | } 15 | \examples{ 16 | should_stop(stop("Hi!")) 17 | should_stop(should_stop("Hi!")) 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /tests/testthat/test-stat-density.R: -------------------------------------------------------------------------------- 1 | context("stat_density") # and stat_ydensity 2 | 3 | test_that("compute_density succeeds when variance is zero", { 4 | dens <- compute_density(rep(0, 10), NULL, from = 0.5, to = 0.5) 5 | expect_equal(dens$n, rep(10, 512)) 6 | }) 7 | 8 | test_that("compute_density returns useful df when <3 values", { 9 | dens <- compute_density(c(1, 2), NULL, from = 0, to = 0) 10 | 11 | expect_equal(nrow(dens), 2) 12 | expect_equal(names(dens), c("x", "density", "scaled", "count", "n")) 13 | }) 14 | -------------------------------------------------------------------------------- /man/rel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme-elements.r 3 | \name{rel} 4 | \alias{rel} 5 | \title{Relative sizing for theme elements} 6 | \usage{ 7 | rel(x) 8 | } 9 | \arguments{ 10 | \item{x}{A number representing the relative size} 11 | } 12 | \description{ 13 | Relative sizing for theme elements 14 | } 15 | \examples{ 16 | df <- data.frame(x = 1:3, y = 1:3) 17 | ggplot(df, aes(x, y)) + 18 | geom_point() + 19 | theme(axis.title.x = element_text(size = rel(2.5))) 20 | } 21 | -------------------------------------------------------------------------------- /man/luv_colours.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{luv_colours} 5 | \alias{luv_colours} 6 | \title{\code{colors()} in Luv space.} 7 | \format{A data frame with 657 observations and 4 variables: 8 | \itemize{ 9 | \item{L,u,v}{Position in Luv colour space} 10 | \item{col}{Colour name} 11 | }} 12 | \usage{ 13 | luv_colours 14 | } 15 | \description{ 16 | All built-in \code{\link{colors}()} translated into Luv colour space. 17 | } 18 | \keyword{datasets} 19 | -------------------------------------------------------------------------------- /tests/testthat/test-labels.r: -------------------------------------------------------------------------------- 1 | context("Labels") 2 | 3 | test_that("Setting guide labels", { 4 | 5 | expect_identical(xlab("my label")$x, "my label") 6 | expect_identical(labs(x = "my label")$x, "my label") 7 | 8 | expect_identical(ylab("my label")$y, "my label") 9 | expect_identical(labs(y = "my label")$y, "my label") 10 | 11 | # Colour 12 | expect_identical(labs(colour = "my label")$colour, "my label") 13 | # American spelling 14 | expect_identical(labs(color = "my label")$colour, "my label") 15 | }) 16 | -------------------------------------------------------------------------------- /man/graphical-units.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom-.r 3 | \docType{data} 4 | \name{graphical-units} 5 | \alias{graphical-units} 6 | \alias{.pt} 7 | \alias{.stroke} 8 | \title{Graphical units} 9 | \format{An object of class \code{numeric} of length 1.} 10 | \usage{ 11 | .pt 12 | 13 | .stroke 14 | } 15 | \description{ 16 | Multiply size in mm by these constants in order to convert to the units 17 | that grid uses internally for \code{lwd} and \code{fontsize}. 18 | } 19 | \keyword{datasets} 20 | -------------------------------------------------------------------------------- /man/waiver.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utilities.r 3 | \name{waiver} 4 | \alias{waiver} 5 | \title{A waiver object.} 6 | \usage{ 7 | waiver() 8 | } 9 | \description{ 10 | A waiver is a "flag" object, similar to \code{NULL}, that indicates the 11 | calling function should just use the default value. It is used in certain 12 | functions to distinguish between displaying nothing (\code{NULL}) and 13 | displaying a default value calculated elsewhere (\code{waiver()}) 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /tests/testthat/test-range.r: -------------------------------------------------------------------------------- 1 | context("range") 2 | 3 | test_that("continuous ranges expands as expected", { 4 | r <- continuous_range() 5 | 6 | r$train(1) 7 | expect_equal(r$range, c(1, 1)) 8 | 9 | r$train(10) 10 | expect_equal(r$range, c(1, 10)) 11 | }) 12 | 13 | test_that("discrete ranges expands as expected", { 14 | r <- discrete_range() 15 | 16 | r$train("a") 17 | expect_equal(r$range, "a") 18 | 19 | r$train("b") 20 | expect_equal(r$range, c("a", "b")) 21 | 22 | r$train(letters) 23 | expect_equal(r$range, letters) 24 | }) 25 | -------------------------------------------------------------------------------- /man/element_line.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme-elements.r 3 | \name{element_line} 4 | \alias{element_line} 5 | \title{Theme element: line.} 6 | \usage{ 7 | element_line(colour = NULL, size = NULL, linetype = NULL, 8 | lineend = NULL, color = NULL) 9 | } 10 | \arguments{ 11 | \item{colour}{line colour} 12 | 13 | \item{size}{line size} 14 | 15 | \item{linetype}{line type} 16 | 17 | \item{lineend}{line end} 18 | 19 | \item{color}{an alias for \code{colour}} 20 | } 21 | \description{ 22 | Theme element: line. 23 | } 24 | -------------------------------------------------------------------------------- /man/position_identity.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/position-identity.r 3 | \name{position_identity} 4 | \alias{position_identity} 5 | \title{Don't adjust position} 6 | \usage{ 7 | position_identity() 8 | } 9 | \description{ 10 | Don't adjust position 11 | } 12 | \seealso{ 13 | Other position adjustments: \code{\link{position_dodge}}, 14 | \code{\link{position_fill}}, 15 | \code{\link{position_jitterdodge}}, 16 | \code{\link{position_jitter}}, 17 | \code{\link{position_nudge}} 18 | } 19 | \concept{position adjustments} 20 | -------------------------------------------------------------------------------- /man/add_theme.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme.r 3 | \name{add_theme} 4 | \alias{add_theme} 5 | \title{Modify properties of an element in a theme object} 6 | \usage{ 7 | add_theme(t1, t2, t2name) 8 | } 9 | \arguments{ 10 | \item{t1}{A theme object} 11 | 12 | \item{t2}{A theme object that is to be added to \code{t1}} 13 | 14 | \item{t2name}{A name of the t2 object. This is used for printing 15 | informative error messages.} 16 | } 17 | \description{ 18 | Modify properties of an element in a theme object 19 | } 20 | \seealso{ 21 | +.gg 22 | } 23 | -------------------------------------------------------------------------------- /man/element_grob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme-elements.r 3 | \name{element_grob} 4 | \alias{element_grob} 5 | \title{Generate grid grob from theme element} 6 | \usage{ 7 | element_grob(element, ...) 8 | } 9 | \arguments{ 10 | \item{element}{Theme element, i.e. \code{element_rect} or similar.} 11 | 12 | \item{...}{Other arguments to control specific of rendering. This is 13 | usually at least position. See the source code for individual methods.} 14 | } 15 | \description{ 16 | Generate grid grob from theme element 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/element_rect.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme-elements.r 3 | \name{element_rect} 4 | \alias{element_rect} 5 | \title{Theme element: rectangle.} 6 | \usage{ 7 | element_rect(fill = NULL, colour = NULL, size = NULL, 8 | linetype = NULL, color = NULL) 9 | } 10 | \arguments{ 11 | \item{fill}{fill colour} 12 | 13 | \item{colour}{border colour} 14 | 15 | \item{size}{border size} 16 | 17 | \item{linetype}{border linetype} 18 | 19 | \item{color}{an alias for \code{colour}} 20 | } 21 | \description{ 22 | Most often used for backgrounds and borders. 23 | } 24 | -------------------------------------------------------------------------------- /man/summary.ggplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/summary.r 3 | \name{summary.ggplot} 4 | \alias{summary.ggplot} 5 | \title{Displays a useful description of a ggplot object} 6 | \usage{ 7 | \method{summary}{ggplot}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{ggplot2 object to summarise} 11 | 12 | \item{...}{other arguments ignored (for compatibility with generic)} 13 | } 14 | \description{ 15 | Displays a useful description of a ggplot object 16 | } 17 | \examples{ 18 | p <- ggplot(mtcars, aes(mpg, wt)) + 19 | geom_point() 20 | summary(p) 21 | } 22 | \keyword{internal} 23 | -------------------------------------------------------------------------------- /tests/testthat/test-stat-density2d.R: -------------------------------------------------------------------------------- 1 | context("stat_density_2d") 2 | 3 | test_that("uses scale limits, not data limits", { 4 | base <- ggplot(mtcars, aes(wt, mpg)) + 5 | stat_density_2d() + 6 | scale_x_continuous(limits = c(1, 6)) + 7 | scale_y_continuous(limits = c(5, 40)) 8 | 9 | ret <- layer_data(base) 10 | # Check that the contour data goes beyond data range. 11 | # The specific values below are sort of arbitrary; but they go beyond the range 12 | # of the data 13 | expect_true(min(ret$x) < 1.2) 14 | expect_true(max(ret$x) > 5.8) 15 | expect_true(min(ret$y) < 8) 16 | expect_true(max(ret$y) > 35) 17 | }) 18 | -------------------------------------------------------------------------------- /man/benchplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bench.r 3 | \name{benchplot} 4 | \alias{benchplot} 5 | \title{Benchmark plot creation time. 6 | Broken down into construct, build, render and draw times.} 7 | \usage{ 8 | benchplot(x) 9 | } 10 | \arguments{ 11 | \item{x}{code to create ggplot2 plot} 12 | } 13 | \description{ 14 | Benchmark plot creation time. 15 | Broken down into construct, build, render and draw times. 16 | } 17 | \examples{ 18 | benchplot(ggplot(mtcars, aes(mpg, wt)) + geom_point()) 19 | benchplot(ggplot(mtcars, aes(mpg, wt)) + geom_point() + facet_grid(. ~ cyl)) 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /man/add_margins.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lwplotAddins.R 3 | \name{add_margins} 4 | \alias{add_margins} 5 | \title{Add margins to a data frame.} 6 | \usage{ 7 | add_margins(df, vars, margins = TRUE) 8 | } 9 | \arguments{ 10 | \item{df}{input data frame} 11 | 12 | \item{vars}{a list of character vectors giving the variables in each 13 | dimension} 14 | 15 | \item{margins}{a character vector of variable names to compute margins for. 16 | \code{TRUE} will compute all possible margins.} 17 | } 18 | \description{ 19 | Rownames are silently stripped. All margining variables will be converted 20 | to factors. 21 | } 22 | -------------------------------------------------------------------------------- /tests/testthat/test-scale-discrete.R: -------------------------------------------------------------------------------- 1 | context("scale_discrete") 2 | 3 | # Ranges ------------------------------------------------------------------ 4 | 5 | test_that("discrete ranges also encompas continuous values", { 6 | df <- data.frame(x1 = c("a", "b", "c"), x2 = c(0, 2, 4), y = 1:3) 7 | 8 | base <- ggplot(df, aes(y = y)) + scale_x_discrete() 9 | 10 | x_range <- function(x) { 11 | layer_scales(x)$x$dimension() 12 | } 13 | 14 | expect_equal(x_range(base + geom_point(aes(x1))), c(1, 3)) 15 | expect_equal(x_range(base + geom_point(aes(x2))), c(0, 4)) 16 | expect_equal(x_range(base + geom_point(aes(x1)) + geom_point(aes(x2))), c(0, 4)) 17 | }) 18 | 19 | -------------------------------------------------------------------------------- /man/transform_position.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/position-.r 3 | \name{transform_position} 4 | \alias{transform_position} 5 | \title{Convenience function to transform all position variables.} 6 | \usage{ 7 | transform_position(df, trans_x = NULL, trans_y = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{trans_x, trans_y}{Transformation functions for x and y aesthetics. 11 | (will transform x, xmin, xmax, xend etc)} 12 | 13 | \item{...}{Additional arguments passed to \code{trans_x} and \code{trans_y}.} 14 | } 15 | \description{ 16 | Convenience function to transform all position variables. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/update_labels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/labels.r 3 | \name{update_labels} 4 | \alias{update_labels} 5 | \title{Update axis/legend labels} 6 | \usage{ 7 | update_labels(p, labels) 8 | } 9 | \arguments{ 10 | \item{p}{plot to modify} 11 | 12 | \item{labels}{named list of new labels} 13 | } 14 | \description{ 15 | Update axis/legend labels 16 | } 17 | \examples{ 18 | p <- ggplot(mtcars, aes(mpg, wt)) + geom_point() 19 | update_labels(p, list(x = "New x")) 20 | update_labels(p, list(x = expression(x / y ^ 2))) 21 | update_labels(p, list(x = "New x", y = "New Y")) 22 | update_labels(p, list(colour = "Fail silently")) 23 | } 24 | -------------------------------------------------------------------------------- /man/as.list.ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggproto.r 3 | \name{as.list.ggproto} 4 | \alias{as.list.ggproto} 5 | \title{Convert a ggproto object to a list} 6 | \usage{ 7 | \method{as.list}{ggproto}(x, inherit = TRUE, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A ggproto object to convert to a list.} 11 | 12 | \item{inherit}{If \code{TRUE} (the default), flatten all inherited items into 13 | the returned list. If \code{FALSE}, do not include any inherited items.} 14 | 15 | \item{...}{Further arguments to pass to \code{as.list.environment}.} 16 | } 17 | \description{ 18 | This will not include the object's \code{super} member. 19 | } 20 | -------------------------------------------------------------------------------- /man/limits.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/limits.r 3 | \name{limits} 4 | \alias{limits} 5 | \title{Generate correct scale type for specified limits} 6 | \usage{ 7 | limits(lims, var) 8 | } 9 | \arguments{ 10 | \item{var}{name of variable} 11 | 12 | \item{limits}{vector of limits} 13 | } 14 | \description{ 15 | Generate correct scale type for specified limits 16 | } 17 | \examples{ 18 | lwplot:::limits(c(1, 5), "x") 19 | lwplot:::limits(c(5, 1), "x") 20 | lwplot:::limits(c("A", "b", "c"), "x") 21 | lwplot:::limits(c("A", "b", "c"), "fill") 22 | lwplot:::limits(as.Date(c("2008-01-01", "2009-01-01")), "x") 23 | } 24 | \keyword{internal} 25 | -------------------------------------------------------------------------------- /R/position-fill.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname position_stack 3 | position_fill <- function() { 4 | PositionFill 5 | } 6 | 7 | #' @rdname ggplot2-ggproto 8 | #' @format NULL 9 | #' @usage NULL 10 | #' @export 11 | PositionFill <- ggproto("PositionFill", Position, 12 | required_aes = c("x", "ymax"), 13 | 14 | setup_data = function(self, data, params) { 15 | if (!is.null(data$ymin) && !all(data$ymin == 0)) 16 | warning("Filling not well defined when ymin != 0", call. = FALSE) 17 | 18 | ggproto_parent(Position, self)$setup_data(data) 19 | }, 20 | 21 | compute_panel = function(data, params, scales) { 22 | collide(data, NULL, "position_fill", pos_fill) 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /man/fortify.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fortify.r 3 | \name{fortify} 4 | \alias{fortify} 5 | \title{Fortify a model with data.} 6 | \usage{ 7 | fortify(model, data, ...) 8 | } 9 | \arguments{ 10 | \item{model}{model or other R object to convert to data frame} 11 | 12 | \item{data}{original dataset, if needed} 13 | 14 | \item{...}{other arguments passed to methods} 15 | } 16 | \description{ 17 | Rather than using this function, I now recomend using the \pkg{broom} 18 | package, which implements a much wider range of methods. \code{fortify} 19 | may be deprecated in the future. 20 | } 21 | \seealso{ 22 | \code{\link{fortify.lm}} 23 | } 24 | -------------------------------------------------------------------------------- /man/margin.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/margins.R 3 | \name{margin} 4 | \alias{margin} 5 | \title{Define margins.} 6 | \usage{ 7 | margin(t = 0, r = 0, b = 0, l = 0, unit = "pt") 8 | } 9 | \arguments{ 10 | \item{t, r, b, l}{Dimensions of each margin. (To remember order, think trouble).} 11 | 12 | \item{unit}{Default units of dimensions. Defaults to "pt" so it 13 | can be most easily scaled with the text.} 14 | } 15 | \description{ 16 | This is a convenient function that creates a grid unit object of the 17 | correct length to use for setting margins. 18 | } 19 | \examples{ 20 | margin(4) 21 | margin(4, 2) 22 | margin(4, 3, 2, 1) 23 | } 24 | -------------------------------------------------------------------------------- /man/format.ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggproto.r 3 | \name{format.ggproto} 4 | \alias{format.ggproto} 5 | \title{Format a ggproto object} 6 | \usage{ 7 | \method{format}{ggproto}(x, ..., flat = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{A ggproto object to print.} 11 | 12 | \item{...}{If the ggproto object has a \code{print} method, further arguments 13 | will be passed to it. Otherwise, these arguments are unused.} 14 | 15 | \item{flat}{If \code{TRUE} (the default), show a flattened list of all local 16 | and inherited members. If \code{FALSE}, show the inheritance hierarchy.} 17 | } 18 | \description{ 19 | Format a ggproto object 20 | } 21 | -------------------------------------------------------------------------------- /man/facet_null.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/facet-null.r 3 | \name{facet_null} 4 | \alias{facet_null} 5 | \title{Facet specification: a single panel.} 6 | \usage{ 7 | facet_null(shrink = TRUE) 8 | } 9 | \arguments{ 10 | \item{shrink}{If \code{TRUE}, will shrink scales to fit output of 11 | statistics, not raw data. If \code{FALSE}, will be range of raw data 12 | before statistical summary.} 13 | } 14 | \description{ 15 | Facet specification: a single panel. 16 | } 17 | \examples{ 18 | # facet_null is the default facetting specification if you 19 | # don't override it with facet_grid or facet_wrap 20 | ggplot(mtcars, aes(mpg, wt)) + geom_point() 21 | } 22 | -------------------------------------------------------------------------------- /R/geom-freqpoly.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname geom_histogram 3 | geom_freqpoly <- function(mapping = NULL, data = NULL, 4 | stat = "bin", position = "identity", 5 | ..., 6 | na.rm = FALSE, 7 | show.legend = NA, 8 | inherit.aes = TRUE) { 9 | 10 | params <- list(na.rm = na.rm, ...) 11 | if (identical(stat, "bin")) { 12 | params$pad <- TRUE 13 | } 14 | 15 | layer( 16 | data = data, 17 | mapping = mapping, 18 | stat = stat, 19 | geom = GeomPath, 20 | position = position, 21 | show.legend = show.legend, 22 | inherit.aes = inherit.aes, 23 | params = params 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /tests/testthat/test-qplot.r: -------------------------------------------------------------------------------- 1 | context("qplot") 2 | 3 | test_that("qplot works with variables in data frame and parent env", { 4 | df <- data.frame(x = 1:10, a = 1:10) 5 | y <- 1:10 6 | b <- 1:10 7 | 8 | expect_is(qplot(x, y, data = df), "ggplot") 9 | expect_is(qplot(x, y, data = df, colour = a), "ggplot") 10 | expect_is(qplot(x, y, data = df, colour = b), "ggplot") 11 | 12 | bin <- 1 13 | expect_is(qplot(x, data = df, binwidth = bin), "ggplot") 14 | }) 15 | 16 | test_that("qplot works in non-standard environments", { 17 | env <- new.env(parent = globalenv()) 18 | expr <- quote({ 19 | `-1-` <- 10 20 | x <- 1:10 21 | qplot(x, breaks = 0:`-1-`) 22 | }) 23 | 24 | expect_is(eval(expr, env), "ggplot") 25 | 26 | }) 27 | 28 | -------------------------------------------------------------------------------- /man/autoplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/autoplot.r 3 | \name{autoplot} 4 | \alias{autoplot} 5 | \title{Create a complete ggplot appropriate to a particular data type} 6 | \usage{ 7 | autoplot(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{an object, whose class will determine the behaviour of autoplot} 11 | 12 | \item{...}{other arguments passed to specific methods} 13 | } 14 | \value{ 15 | a ggplot object 16 | } 17 | \description{ 18 | \code{autoplot} uses ggplot2 to draw a particular plot for an object of a 19 | particular class in a single command. This defines the S3 generic that 20 | other classes and packages can extend. 21 | } 22 | \seealso{ 23 | \code{\link{ggplot}} and \code{\link{fortify}} 24 | } 25 | -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utilities.r, R/utilities-grid.r 3 | \docType{import} 4 | \name{reexports} 5 | \alias{reexports} 6 | \alias{alpha} 7 | \alias{unit} 8 | \alias{arrow} 9 | \title{Objects exported from other packages} 10 | \examples{ 11 | ggplot(mpg, aes(displ, hwy)) + 12 | geom_point(alpha = 0.5, colour = "blue") 13 | 14 | ggplot(mpg, aes(displ, hwy)) + 15 | geom_point(colour = alpha("blue", 0.5)) 16 | } 17 | \keyword{internal} 18 | \description{ 19 | These objects are imported from other packages. Follow the links 20 | below to see their documentation. 21 | 22 | \describe{ 23 | \item{grid}{\code{\link[grid]{unit}}, \code{\link[grid]{arrow}}} 24 | 25 | \item{scales}{\code{\link[scales]{alpha}}} 26 | }} 27 | 28 | -------------------------------------------------------------------------------- /R/grob-null.r: -------------------------------------------------------------------------------- 1 | #' The zero grob draws nothing and has zero size. 2 | #' 3 | #' @keywords internal 4 | #' @export 5 | zeroGrob <- function() .zeroGrob 6 | 7 | .zeroGrob <- grob(cl = "zeroGrob", name = "NULL") 8 | #' @export 9 | #' @method widthDetails zeroGrob 10 | widthDetails.zeroGrob <- function(x) unit(0, "cm") 11 | #' @export 12 | #' @method heightDetails zeroGrob 13 | heightDetails.zeroGrob <- function(x) unit(0, "cm") 14 | #' @export 15 | #' @method grobWidth zeroGrob 16 | grobWidth.zeroGrob <- function(x) unit(0, "cm") 17 | #' @export 18 | #' @method grobHeight zeroGrob 19 | grobHeight.zeroGrob <- function(x) unit(0, "cm") 20 | #' @export 21 | #' @method drawDetails zeroGrob 22 | drawDetails.zeroGrob <- function(x, recording) {} 23 | 24 | is.zero <- function(x) is.null(x) || inherits(x, "zeroGrob") 25 | -------------------------------------------------------------------------------- /man/seals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{seals} 5 | \alias{seals} 6 | \title{Vector field of seal movements.} 7 | \format{A data frame with 1155 rows and 4 variables} 8 | \usage{ 9 | seals 10 | } 11 | \description{ 12 | This vector field was produced from the data described in Brillinger, D.R., 13 | Preisler, H.K., Ager, A.A. and Kie, J.G. "An exploratory data analysis 14 | (EDA) of the paths of moving animals". J. Statistical Planning and 15 | Inference 122 (2004), 43-63, using the methods of Brillinger, D.R., 16 | "Learning a potential function from a trajectory", Signal Processing 17 | Letters. December (2007). 18 | } 19 | \references{ 20 | \url{http://www.stat.berkeley.edu/~brill/Papers/jspifinal.pdf} 21 | } 22 | \keyword{datasets} 23 | -------------------------------------------------------------------------------- /R/autoplot.r: -------------------------------------------------------------------------------- 1 | #' Create a complete ggplot appropriate to a particular data type 2 | #' 3 | #' \code{autoplot} uses ggplot2 to draw a particular plot for an object of a 4 | #' particular class in a single command. This defines the S3 generic that 5 | #' other classes and packages can extend. 6 | #' 7 | #' @param object an object, whose class will determine the behaviour of autoplot 8 | #' @param ... other arguments passed to specific methods 9 | #' @return a ggplot object 10 | #' @export 11 | #' @seealso \code{\link{ggplot}} and \code{\link{fortify}} 12 | autoplot <- function(object, ...) { 13 | UseMethod("autoplot") 14 | } 15 | 16 | #' @export 17 | autoplot.default <- function(object, ...) { 18 | stop("Objects of type ", paste(class(object), collapse = "/"), 19 | " not supported by autoplot.", call. = FALSE) 20 | } 21 | 22 | -------------------------------------------------------------------------------- /R/zzz.r: -------------------------------------------------------------------------------- 1 | .onAttach <- function(...) { 2 | ## if (!interactive() || stats::runif(1) > 0.1) return() 3 | 4 | ## tips <- c( 5 | ## "Need help? Try the ggplot2 mailing list: http://groups.google.com/group/ggplot2.", 6 | ## "Find out what's changed in ggplot2 at http://github.com/hadley/ggplot2/releases.", 7 | ## "Use suppressPackageStartupMessages() to eliminate package startup messages.", 8 | ## "Stackoverflow is a great place to get help: http://stackoverflow.com/tags/ggplot2.", 9 | ## "Need help getting started? Try the cookbook for R: http://www.cookbook-r.com/Graphs/", 10 | ## "Want to understand how all the pieces fit together? Buy the ggplot2 book: http://ggplot2.org/book/" 11 | ## ) 12 | 13 | ## tip <- sample(tips, 1) 14 | ## packageStartupMessage(paste(strwrap(tip), collapse = "\n")) 15 | } 16 | -------------------------------------------------------------------------------- /man/txhousing.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{txhousing} 5 | \alias{txhousing} 6 | \title{Housing sales in TX.} 7 | \format{A data frame with 8602 observations and 9 variables: 8 | \itemize{ 9 | \item{city}{Name of MLS area} 10 | \item{year,month,date}{Date} 11 | \item{sales}{Number of sales} 12 | \item{volume}{Total value of sales} 13 | \item{median}{Median sale price} 14 | \item{listings}{Total active listings} 15 | \item{inventory}{"Months inventory": amount of time it would take to sell 16 | all current listings at current pace of sales.} 17 | }} 18 | \usage{ 19 | txhousing 20 | } 21 | \description{ 22 | Information about the housing market in Texas provided by the TAMU 23 | real estate center, \url{http://recenter.tamu.edu/}. 24 | } 25 | \keyword{datasets} 26 | -------------------------------------------------------------------------------- /R/bench.r: -------------------------------------------------------------------------------- 1 | #' Benchmark plot creation time. 2 | #' Broken down into construct, build, render and draw times. 3 | #' 4 | #' @param x code to create ggplot2 plot 5 | #' @export 6 | #' @keywords internal 7 | #' @examples 8 | #' benchplot(ggplot(mtcars, aes(mpg, wt)) + geom_point()) 9 | #' benchplot(ggplot(mtcars, aes(mpg, wt)) + geom_point() + facet_grid(. ~ cyl)) 10 | benchplot <- function(x) { 11 | 12 | construct <- system.time(force(x)) 13 | stopifnot(inherits(x, "ggplot")) 14 | 15 | build <- system.time(data <- ggplot_build(x)) 16 | render <- system.time(grob <- ggplot_gtable(data)) 17 | draw <- system.time(grid.draw(grob)) 18 | 19 | times <- rbind(construct, build, render, draw)[, 1:3] 20 | 21 | plyr::unrowname(data.frame( 22 | step = c("construct", "build", "render", "draw", "TOTAL"), 23 | rbind(times, colSums(times)))) 24 | } 25 | -------------------------------------------------------------------------------- /man/coord_munch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/coord-munch.r 3 | \name{coord_munch} 4 | \alias{coord_munch} 5 | \title{Munch coordinates data} 6 | \usage{ 7 | coord_munch(coord, data, range, segment_length = 0.01) 8 | } 9 | \arguments{ 10 | \item{coord}{Coordinate system definition.} 11 | 12 | \item{data}{Data set to transform - should have variables \code{x} and 13 | \code{y} are chopped up into small pieces (as defined by \code{group}). 14 | All other variables are duplicated as needed.} 15 | 16 | \item{range}{Panel range specification.} 17 | 18 | \item{segment_length}{Target segment length} 19 | } 20 | \description{ 21 | This function "munches" lines, dividing each line into many small pieces 22 | so they can be transformed independently. Used inside geom functions. 23 | } 24 | \keyword{internal} 25 | -------------------------------------------------------------------------------- /man/print.ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggproto.r 3 | \name{print.ggproto} 4 | \alias{print.ggproto} 5 | \title{Print a ggproto object} 6 | \usage{ 7 | \method{print}{ggproto}(x, ..., flat = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{A ggproto object to print.} 11 | 12 | \item{...}{If the ggproto object has a \code{print} method, further arguments 13 | will be passed to it. Otherwise, these arguments are unused.} 14 | 15 | \item{flat}{If \code{TRUE} (the default), show a flattened list of all local 16 | and inherited members. If \code{FALSE}, show the inheritance hierarchy.} 17 | } 18 | \description{ 19 | If a ggproto object has a \code{$print} method, this will call that method. 20 | Otherwise, it will print out the members of the object, and optionally, the 21 | members of the inherited objects. 22 | } 23 | -------------------------------------------------------------------------------- /man/update_defaults.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom-defaults.r 3 | \name{update_geom_defaults} 4 | \alias{update_geom_defaults} 5 | \alias{update_stat_defaults} 6 | \title{Modify geom/stat aesthetic defaults for future plots} 7 | \usage{ 8 | update_geom_defaults(geom, new) 9 | 10 | update_stat_defaults(stat, new) 11 | } 12 | \arguments{ 13 | \item{new}{Named list of aesthetics.} 14 | 15 | \item{stat, geom}{Name of geom/stat to modify (like \code{"point"} or 16 | \code{"bin"}), or a Geom/Stat object (like \code{GeomPoint} or 17 | \code{StatBin}).} 18 | } 19 | \description{ 20 | Modify geom/stat aesthetic defaults for future plots 21 | } 22 | \examples{ 23 | update_geom_defaults("point", list(colour = "darkblue")) 24 | ggplot(mtcars, aes(mpg, wt)) + geom_point() 25 | update_geom_defaults("point", list(colour = "black")) 26 | } 27 | -------------------------------------------------------------------------------- /man/hmisc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stat-summary.r 3 | \name{hmisc} 4 | \alias{hmisc} 5 | \alias{mean_cl_boot} 6 | \alias{mean_cl_normal} 7 | \alias{mean_sdl} 8 | \alias{median_hilow} 9 | \title{Wrap up a selection of summary functions from Hmisc to make it easy to use 10 | with \code{\link{stat_summary}}.} 11 | \usage{ 12 | mean_cl_boot(x, ...) 13 | 14 | mean_cl_normal(x, ...) 15 | 16 | mean_sdl(x, ...) 17 | 18 | median_hilow(x, ...) 19 | } 20 | \arguments{ 21 | \item{x}{a numeric vector} 22 | 23 | \item{...}{other arguments passed on to the respective Hmisc function.} 24 | } 25 | \description{ 26 | See the Hmisc documentation for details of their options. 27 | } 28 | \seealso{ 29 | \code{\link[Hmisc]{smean.cl.boot}}, 30 | \code{\link[Hmisc]{smean.cl.normal}}, \code{\link[Hmisc]{smean.sdl}}, 31 | \code{\link[Hmisc]{smedian.hilow}} 32 | } 33 | -------------------------------------------------------------------------------- /man/print.ggplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.r 3 | \name{print.ggplot} 4 | \alias{print.ggplot} 5 | \alias{plot.ggplot} 6 | \title{Draw plot on current graphics device.} 7 | \usage{ 8 | \method{print}{ggplot}(x, newpage = is.null(vp), vp = NULL, ...) 9 | 10 | \method{plot}{ggplot}(x, newpage = is.null(vp), vp = NULL, ...) 11 | } 12 | \arguments{ 13 | \item{x}{plot to display} 14 | 15 | \item{newpage}{draw new (empty) page first?} 16 | 17 | \item{vp}{viewport to draw plot in} 18 | 19 | \item{...}{other arguments not used by this method} 20 | } 21 | \value{ 22 | Invisibly returns the result of \code{\link{ggplot_build}}, which 23 | is a list with components that contain the plot itself, the data, 24 | information about the scales, panels etc. 25 | } 26 | \description{ 27 | Draw plot on current graphics device. 28 | } 29 | \keyword{hplot} 30 | -------------------------------------------------------------------------------- /R/utilities-grid.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | grid::unit 3 | 4 | #' @export 5 | grid::arrow 6 | 7 | # Name ggplot grid object 8 | # Convenience function to name grid objects 9 | # 10 | # @keyword internal 11 | ggname <- function(prefix, grob) { 12 | grob$name <- grobName(grob, prefix) 13 | grob 14 | } 15 | 16 | width_cm <- function(x) { 17 | if (is.grob(x)) { 18 | convertWidth(grobWidth(x), "cm", TRUE) 19 | } else if (is.unit(x)) { 20 | convertWidth(x, "cm", TRUE) 21 | } else if (is.list(x)) { 22 | vapply(x, width_cm, numeric(1)) 23 | } else { 24 | stop("Unknown input") 25 | } 26 | } 27 | height_cm <- function(x) { 28 | if (is.grob(x)) { 29 | convertWidth(grobHeight(x), "cm", TRUE) 30 | } else if (is.unit(x)) { 31 | convertHeight(x, "cm", TRUE) 32 | } else if (is.list(x)) { 33 | vapply(x, height_cm, numeric(1)) 34 | } else { 35 | stop("Unknown input") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/testthat/helper-plot-data.r: -------------------------------------------------------------------------------- 1 | # Transform the data as the coordinate system does 2 | cdata <- function(plot) { 3 | pieces <- ggplot_build(plot) 4 | 5 | lapply(pieces$data, function(d) { 6 | plyr::ddply(d, "PANEL", function(panel_data) { 7 | scales <- panel_scales(pieces$panel, panel_data$PANEL[1]) 8 | details <- plot$coordinates$train(scales) 9 | plot$coordinates$transform(panel_data, details) 10 | }) 11 | }) 12 | } 13 | 14 | pranges <- function(plot) { 15 | panels <- ggplot_build(plot)$panel 16 | 17 | x_ranges <- lapply(panels$x_scales, function(scale) scale$get_limits()) 18 | y_ranges <- lapply(panels$y_scales, function(scale) scale$get_limits()) 19 | 20 | 21 | npscales <- plot$scales$non_position_scales() 22 | npranges <- lapply(npscales$scales$scales, function(scale) scale$get_limits()) 23 | 24 | 25 | c(list(x = x_ranges, y = y_ranges), npranges) 26 | } 27 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-violin.R: -------------------------------------------------------------------------------- 1 | context("geom_violin") 2 | 3 | test_that("", { 4 | df <- rbind( 5 | data.frame(x = "a", y = c(0, runif(10), 1)), 6 | data.frame(x = "b", y = c(0, runif(10), 2)) 7 | ) 8 | 9 | p <- ggplot(df, aes(1, y)) + 10 | geom_violin() + 11 | facet_grid(x ~ ., scales = "free") + 12 | coord_cartesian(expand = FALSE) 13 | 14 | expect_equal(layer_scales(p, 1)$y$dimension(), c(0, 1)) 15 | expect_equal(layer_scales(p, 2)$y$dimension(), c(0, 2)) 16 | }) 17 | 18 | # create_quantile_segment_frame ------------------------------------------------- 19 | 20 | test_that("create_quantile_segment_frame functions for 3 quantiles", { 21 | density.data <- data.frame(y=(1:256)/256, density=1/256) # uniform density 22 | 23 | qs <- c(0.25, 0.5, 0.75) # 3 quantiles 24 | expect_equal(create_quantile_segment_frame(density.data, qs)$y, 25 | rep(qs, each=2)) 26 | }) 27 | 28 | -------------------------------------------------------------------------------- /man/margins.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lwplotAddins.R 3 | \name{margins} 4 | \alias{margins} 5 | \title{Figure out margining variables.} 6 | \usage{ 7 | margins(vars, margins = NULL) 8 | } 9 | \arguments{ 10 | \item{vars}{a list of character vectors giving the variables in each 11 | dimension} 12 | 13 | \item{margins}{a character vector of variable names to compute margins for. 14 | \code{TRUE} will compute all possible margins.} 15 | } 16 | \value{ 17 | list of margining combinations, or \code{NULL} if none. These are 18 | the combinations of variables that should have their values set to 19 | \code{(all)} 20 | } 21 | \description{ 22 | Given the variables that form the rows and columns, and a set of desired 23 | margins, works out which ones are possible. Variables that can't be 24 | margined over are dropped silently. 25 | } 26 | \keyword{internal} 27 | \keyword{manip} 28 | -------------------------------------------------------------------------------- /man/resolution.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utilities-resolution.r 3 | \name{resolution} 4 | \alias{resolution} 5 | \title{Compute the "resolution" of a data vector.} 6 | \usage{ 7 | resolution(x, zero = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{numeric vector} 11 | 12 | \item{zero}{should a zero value be automatically included in the 13 | computation of resolution} 14 | } 15 | \description{ 16 | The resolution is is the smallest non-zero distance between adjacent 17 | values. If there is only one unique value, then the resolution is defined 18 | to be one. 19 | } 20 | \details{ 21 | If x is an integer vector, then it is assumed to represent a discrete 22 | variable, and the resolution is 1. 23 | } 24 | \examples{ 25 | resolution(1:10) 26 | resolution((1:10) - 0.5) 27 | resolution((1:10) - 0.5, FALSE) 28 | resolution(c(1,2, 10, 20, 50)) 29 | resolution(as.integer(c(1, 10, 20, 50))) # Returns 1 30 | } 31 | -------------------------------------------------------------------------------- /R/range.r: -------------------------------------------------------------------------------- 1 | #' Mutable ranges have a two methods (\code{train} and \code{reset}), and make 2 | #' it possible to build up complete ranges with multiple passes. 3 | #' 4 | #' These range objects should be instantiated with 5 | #' \code{\link{continuous_range}} and \code{\link{discrete_range}}. 6 | #' 7 | #' @noRd 8 | Range <- ggproto("Range", NULL, 9 | range = NULL, 10 | reset = function(self) { 11 | self$range <- NULL 12 | } 13 | ) 14 | 15 | RangeDiscrete <- ggproto("RangeDiscrete", Range, 16 | train = function(self, x, drop = FALSE) { 17 | self$range <- scales::train_discrete(x, self$range, drop) 18 | } 19 | ) 20 | 21 | RangeContinuous <- ggproto("RangeContinuous", Range, 22 | train = function(self, x) { 23 | self$range <- scales::train_continuous(x, self$range) 24 | } 25 | ) 26 | 27 | continuous_range <- function() { 28 | ggproto(NULL, RangeContinuous) 29 | } 30 | 31 | discrete_range <- function() { 32 | ggproto(NULL, RangeDiscrete) 33 | } 34 | -------------------------------------------------------------------------------- /R/fortify.r: -------------------------------------------------------------------------------- 1 | #' Fortify a model with data. 2 | #' 3 | #' Rather than using this function, I now recomend using the \pkg{broom} 4 | #' package, which implements a much wider range of methods. \code{fortify} 5 | #' may be deprecated in the future. 6 | #' 7 | #' @seealso \code{\link{fortify.lm}} 8 | #' @param model model or other R object to convert to data frame 9 | #' @param data original dataset, if needed 10 | #' @param ... other arguments passed to methods 11 | #' @export 12 | fortify <- function(model, data, ...) UseMethod("fortify") 13 | 14 | #' @export 15 | fortify.data.frame <- function(model, data, ...) model 16 | #' @export 17 | fortify.NULL <- function(model, data, ...) waiver() 18 | #' @export 19 | fortify.function <- function(model, data, ...) model 20 | #' @export 21 | fortify.default <- function(model, data, ...) { 22 | stop( 23 | "ggplot2 doesn't know how to deal with data of class ", 24 | paste(class(model), collapse = "/"), 25 | call. = FALSE 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /man/expand_limits.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/limits.r 3 | \name{expand_limits} 4 | \alias{expand_limits} 5 | \title{Expand the plot limits with data.} 6 | \usage{ 7 | expand_limits(...) 8 | } 9 | \arguments{ 10 | \item{...}{named list of aesthetics specifying the value (or values) that 11 | should be included in each scale.} 12 | } 13 | \description{ 14 | panels or all plots. This function is a thin wrapper around 15 | \code{\link{geom_blank}} that makes it easy to add such values. 16 | } 17 | \examples{ 18 | p <- ggplot(mtcars, aes(mpg, wt)) + geom_point() 19 | p + expand_limits(x = 0) 20 | p + expand_limits(y = c(1, 9)) 21 | p + expand_limits(x = 0, y = 0) 22 | 23 | ggplot(mtcars, aes(mpg, wt)) + 24 | geom_point(aes(colour = cyl)) + 25 | expand_limits(colour = seq(2, 10, by = 2)) 26 | ggplot(mtcars, aes(mpg, wt)) + 27 | geom_point(aes(colour = factor(cyl))) + 28 | expand_limits(colour = factor(seq(2, 10, by = 2))) 29 | } 30 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-text.R: -------------------------------------------------------------------------------- 1 | context("geom_text") 2 | 3 | # compute_just ------------------------------------------------------------ 4 | 5 | test_that("vertical and horizontal positions are equivalent", { 6 | horiz <- compute_just(c("left", "middle", "right"), c(0, 0, 0)) 7 | vert <- compute_just(c("bottom", "center", "top"), c(0, 0, 0)) 8 | 9 | expect_equal(horiz, vert) 10 | }) 11 | 12 | test_that("inward moves text towards center", { 13 | expect_equal( 14 | compute_just(c("inward", "inward", "inward"), c(0, 0.5, 1)), 15 | c(0, 0.5, 1.0) 16 | ) 17 | }) 18 | 19 | test_that("outwards moves text away from center", { 20 | expect_equal( 21 | compute_just(c("outward", "outward", "outward"), c(0, 0.5, 1)), 22 | c(1.0, 0.5, 0) 23 | ) 24 | }) 25 | 26 | test_that("inward points close to center are centered", { 27 | expect_equal( 28 | compute_just(c("inward", "inward", "inward"), c(0.5 - 1e-3, 0.5, 0.5 + 1e-3)), 29 | c(0.5, 0.5, 0.5) 30 | ) 31 | 32 | }) 33 | 34 | -------------------------------------------------------------------------------- /R/utilities-resolution.r: -------------------------------------------------------------------------------- 1 | #' Compute the "resolution" of a data vector. 2 | #' 3 | #' The resolution is is the smallest non-zero distance between adjacent 4 | #' values. If there is only one unique value, then the resolution is defined 5 | #' to be one. 6 | #' 7 | #' If x is an integer vector, then it is assumed to represent a discrete 8 | #' variable, and the resolution is 1. 9 | #' 10 | #' @param x numeric vector 11 | #' @param zero should a zero value be automatically included in the 12 | #' computation of resolution 13 | #' @export 14 | #' @examples 15 | #' resolution(1:10) 16 | #' resolution((1:10) - 0.5) 17 | #' resolution((1:10) - 0.5, FALSE) 18 | #' resolution(c(1,2, 10, 20, 50)) 19 | #' resolution(as.integer(c(1, 10, 20, 50))) # Returns 1 20 | resolution <- function(x, zero = TRUE) { 21 | if (is.integer(x) || zero_range(range(x, na.rm = TRUE))) 22 | return(1) 23 | 24 | x <- unique(as.numeric(x)) 25 | if (zero) { 26 | x <- unique(c(0, x)) 27 | } 28 | 29 | min(diff(sort(x))) 30 | } 31 | -------------------------------------------------------------------------------- /tests/testthat/test-annotate.r: -------------------------------------------------------------------------------- 1 | context("annotate") 2 | 3 | test_that("dates in segment annotation work", { 4 | dt <- structure(list(month = structure(c(1364774400, 1377993600), 5 | class = c("POSIXct", "POSIXt"), tzone = "UTC"), total = c(-10.3, 6 | 11.7)), .Names = c("month", "total"), row.names = c(NA, -2L), class = 7 | "data.frame") 8 | 9 | p <- ggplot(dt, aes(month, total)) + 10 | geom_point() + 11 | annotate("segment", 12 | x = as.POSIXct("2013-04-01"), 13 | xend = as.POSIXct("2013-07-01"), 14 | y = -10, 15 | yend = 10 16 | ) 17 | 18 | expect_true(all(c("xend", "yend") %in% names(layer_data(p, 2)))) 19 | }) 20 | 21 | test_that("segment annotations transform with scales", { 22 | # This should be a visual test, but contriubtion documentation does not 23 | # explain how to make one 24 | ggplot(mtcars, aes(wt, mpg)) + 25 | geom_point() + 26 | annotate("segment", x = 2, y = 10, xend = 5, yend = 30, colour = "red") + 27 | scale_y_reverse() 28 | }) 29 | -------------------------------------------------------------------------------- /man/mpg.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{mpg} 5 | \alias{mpg} 6 | \title{Fuel economy data from 1999 and 2008 for 38 popular models of car} 7 | \format{A data frame with 234 rows and 11 variables 8 | \itemize{ 9 | \item manufacturer. 10 | \item model. 11 | \item displ. engine displacement, in litres 12 | \item year. 13 | \item cyl. number of cylinders 14 | \item trans. type of transmission 15 | \item drv. f = front-wheel drive, r = rear wheel drive, 4 = 4wd 16 | \item cty. city miles per gallon 17 | \item hwy. highway miles per gallon 18 | \item fl. 19 | \item class. 20 | }} 21 | \usage{ 22 | mpg 23 | } 24 | \description{ 25 | This dataset contains a subset of the fuel economy data that the EPA makes 26 | available on \url{http://fueleconomy.gov}. It contains only models which 27 | had a new release every year between 1999 and 2008 - this was used as a 28 | proxy for the popularity of the car. 29 | } 30 | \keyword{datasets} 31 | -------------------------------------------------------------------------------- /man/ggplot_gtable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot-build.r 3 | \name{ggplot_gtable} 4 | \alias{ggplot_gtable} 5 | \title{Build a plot with all the usual bits and pieces.} 6 | \usage{ 7 | ggplot_gtable(data) 8 | } 9 | \arguments{ 10 | \item{data}{plot data generated by \code{\link{ggplot_build}}} 11 | 12 | \item{plot}{plot object} 13 | } 14 | \value{ 15 | a \code{\link{gtable}} object 16 | } 17 | \description{ 18 | This function builds all grobs necessary for displaying the plot, and 19 | stores them in a special data structure called a \code{\link{gtable}}. 20 | This object is amenable to programmatic manipulation, should you want 21 | to (e.g.) make the legend box 2 cm wide, or combine multiple plots into 22 | a single display, preserving aspect ratios across the plots. 23 | } 24 | \seealso{ 25 | \code{\link{print.ggplot}} and \code{link{benchplot}} for 26 | for functions that contain the complete set of steps for generating 27 | a ggplot2 plot. 28 | } 29 | \keyword{internal} 30 | -------------------------------------------------------------------------------- /R/scale-linetype.r: -------------------------------------------------------------------------------- 1 | #' Scale for line patterns. 2 | #' 3 | #' Default line types based on a set supplied by Richard Pearson, 4 | #' University of Manchester. Line types can not be mapped to continuous 5 | #' values. 6 | #' 7 | #' @inheritParams scale_x_discrete 8 | #' @param na.value The linetype to use for \code{NA} values. 9 | #' @rdname scale_linetype 10 | #' @export 11 | #' @examples 12 | #' base <- ggplot(economics_long, aes(date, value01)) 13 | #' base + geom_line(aes(group = variable)) 14 | #' base + geom_line(aes(linetype = variable)) 15 | #' 16 | #' # See scale_manual for more flexibility 17 | scale_linetype <- function(..., na.value = "blank") { 18 | discrete_scale("linetype", "linetype_d", linetype_pal(), 19 | na.value = na.value, ...) 20 | } 21 | 22 | #' @rdname scale_linetype 23 | #' @export 24 | scale_linetype_continuous <- function(...) { 25 | stop("A continuous variable can not be mapped to linetype", call. = FALSE) 26 | } 27 | #' @rdname scale_linetype 28 | #' @export 29 | scale_linetype_discrete <- scale_linetype 30 | -------------------------------------------------------------------------------- /man/position_nudge.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/position-nudge.R 3 | \name{position_nudge} 4 | \alias{position_nudge} 5 | \title{Nudge points.} 6 | \usage{ 7 | position_nudge(x = 0, y = 0) 8 | } 9 | \arguments{ 10 | \item{x, y}{Amount of vertical and horizontal distance to move.} 11 | } 12 | \description{ 13 | This is useful if you want to nudge labels a little ways from their 14 | points. 15 | } 16 | \examples{ 17 | df <- data.frame( 18 | x = c(1,3,2,5), 19 | y = c("a","c","d","c") 20 | ) 21 | 22 | ggplot(df, aes(x, y)) + 23 | geom_point() + 24 | geom_text(aes(label = y)) 25 | 26 | ggplot(df, aes(x, y)) + 27 | geom_point() + 28 | geom_text(aes(label = y), position = position_nudge(y = -0.1)) 29 | } 30 | \seealso{ 31 | Other position adjustments: \code{\link{position_dodge}}, 32 | \code{\link{position_fill}}, 33 | \code{\link{position_identity}}, 34 | \code{\link{position_jitterdodge}}, 35 | \code{\link{position_jitter}} 36 | } 37 | \concept{position adjustments} 38 | -------------------------------------------------------------------------------- /man/calc_element.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme.r 3 | \name{calc_element} 4 | \alias{calc_element} 5 | \title{Calculate the element properties, by inheriting properties from its parents} 6 | \usage{ 7 | calc_element(element, theme, verbose = FALSE) 8 | } 9 | \arguments{ 10 | \item{element}{The name of the theme element to calculate} 11 | 12 | \item{theme}{A theme object (like theme_grey())} 13 | 14 | \item{verbose}{If TRUE, print out which elements this one inherits from} 15 | } 16 | \description{ 17 | Calculate the element properties, by inheriting properties from its parents 18 | } 19 | \examples{ 20 | t <- theme_grey() 21 | calc_element('text', t) 22 | 23 | # Compare the "raw" element definition to the element with calculated inheritance 24 | t$axis.text.x 25 | calc_element('axis.text.x', t, verbose = TRUE) 26 | 27 | # This reports that axis.text.x inherits from axis.text, 28 | # which inherits from text. You can view each of them with: 29 | t$axis.text.x 30 | t$axis.text 31 | t$text 32 | 33 | } 34 | -------------------------------------------------------------------------------- /man/fortify.map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fortify-map.r 3 | \name{fortify.map} 4 | \alias{fortify.map} 5 | \title{Fortify method for map objects.} 6 | \usage{ 7 | \method{fortify}{map}(model, data, ...) 8 | } 9 | \arguments{ 10 | \item{model}{map object} 11 | 12 | \item{data}{not used by this method} 13 | 14 | \item{...}{not used by this method} 15 | } 16 | \description{ 17 | This function turns a map into a data frame that can more easily be 18 | plotted with ggplot2. 19 | } 20 | \examples{ 21 | if (requireNamespace("maps",quietly=TRUE) && requireNamespace("mapproj",quietly=TRUE)){ 22 | ca <- map("county", "ca", plot = FALSE, fill = TRUE) 23 | head(fortify(ca)) 24 | ggplot(ca, aes(long, lat)) + 25 | geom_polygon(aes(group = group)) 26 | 27 | tx <- map("county", "texas", plot = FALSE, fill = TRUE) 28 | head(fortify(tx)) 29 | ggplot(tx, aes(long, lat)) + 30 | geom_polygon(aes(group = group), colour = "white") 31 | } 32 | } 33 | \seealso{ 34 | \code{\link{map_data}} and \code{\link{borders}} 35 | } 36 | -------------------------------------------------------------------------------- /tests/testthat/test-data.r: -------------------------------------------------------------------------------- 1 | context("Data") 2 | 3 | test_that("stringsAsFactors doesn't affect results", { 4 | 5 | sAF <- getOption("stringsAsFactors") 6 | dat.character <- data.frame(x = letters[5:1], y = 1:5, stringsAsFactors = FALSE) 7 | dat.factor <- data.frame(x = letters[5:1], y = 1:5, stringsAsFactors = TRUE) 8 | 9 | base <- ggplot(mapping = aes(x, y)) + geom_point() 10 | xlabels <- function(x) x$panel$ranges[[1]]$x.labels 11 | 12 | options(stringsAsFactors = TRUE) 13 | char_true <- ggplot_build(base %+% dat.character) 14 | factor_true <- ggplot_build(base %+% dat.factor) 15 | 16 | options(stringsAsFactors = FALSE) 17 | char_false <- ggplot_build(base %+% dat.character) 18 | factor_false <- ggplot_build(base %+% dat.factor) 19 | 20 | options(stringsAsFactors = sAF) 21 | 22 | expect_equal(xlabels(char_true), letters[1:5]) 23 | expect_equal(xlabels(char_false), letters[1:5]) 24 | expect_equal(xlabels(factor_true), letters[1:5]) 25 | expect_equal(xlabels(factor_false), letters[1:5]) 26 | }) 27 | -------------------------------------------------------------------------------- /R/stat-identity.r: -------------------------------------------------------------------------------- 1 | #' Identity statistic. 2 | #' 3 | #' The identity statistic leaves the data unchanged. 4 | #' 5 | #' @inheritParams layer 6 | #' @inheritParams geom_point 7 | #' @export 8 | #' @examples 9 | #' p <- ggplot(mtcars, aes(wt, mpg)) 10 | #' p + stat_identity() 11 | stat_identity <- function(mapping = NULL, data = NULL, 12 | geom = "point", position = "identity", 13 | ..., 14 | show.legend = NA, 15 | inherit.aes = TRUE) { 16 | layer( 17 | data = data, 18 | mapping = mapping, 19 | stat = StatIdentity, 20 | geom = geom, 21 | position = position, 22 | show.legend = show.legend, 23 | inherit.aes = inherit.aes, 24 | params = list( 25 | na.rm = FALSE, 26 | ... 27 | ) 28 | ) 29 | } 30 | 31 | #' @rdname ggplot2-ggproto 32 | #' @format NULL 33 | #' @usage NULL 34 | #' @export 35 | StatIdentity <- ggproto("StatIdentity", Stat, 36 | compute_layer = function(data, scales, params) { 37 | data 38 | } 39 | ) 40 | -------------------------------------------------------------------------------- /man/remove_missing.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utilities.r 3 | \name{remove_missing} 4 | \alias{remove_missing} 5 | \title{Convenience function to remove missing values from a data.frame} 6 | \usage{ 7 | remove_missing(df, na.rm = FALSE, vars = names(df), name = "", 8 | finite = FALSE) 9 | } 10 | \arguments{ 11 | \item{df}{data.frame} 12 | 13 | \item{na.rm}{If true, will suppress warning message.} 14 | 15 | \item{vars}{Character vector of variables to check for missings in} 16 | 17 | \item{name}{Optional function name to improve error message.} 18 | 19 | \item{finite}{If \code{TRUE}, will also remove non-finite values.} 20 | } 21 | \description{ 22 | Remove all non-complete rows, with a warning if \code{na.rm = FALSE}. 23 | ggplot is somewhat more accommodating of missing values than R generally. 24 | For those stats which require complete data, missing values will be 25 | automatically removed with a warning. If \code{na.rm = TRUE} is supplied 26 | to the statistic, the warning will be suppressed. 27 | } 28 | \keyword{internal} 29 | -------------------------------------------------------------------------------- /R/geom-blank.r: -------------------------------------------------------------------------------- 1 | #' Blank, draws nothing. 2 | #' 3 | #' The blank geom draws nothing, but can be a useful way of ensuring common 4 | #' scales between different plots. 5 | #' 6 | #' @export 7 | #' @inheritParams layer 8 | #' @inheritParams geom_point 9 | #' @examples 10 | #' ggplot(mtcars, aes(wt, mpg)) 11 | #' # Nothing to see here! 12 | geom_blank <- function(mapping = NULL, data = NULL, 13 | stat = "identity", position = "identity", 14 | ..., 15 | show.legend = NA, 16 | inherit.aes = TRUE) { 17 | layer( 18 | data = data, 19 | mapping = mapping, 20 | stat = stat, 21 | geom = GeomBlank, 22 | position = position, 23 | show.legend = show.legend, 24 | inherit.aes = inherit.aes, 25 | params = list(...) 26 | ) 27 | } 28 | 29 | 30 | #' @rdname ggplot2-ggproto 31 | #' @format NULL 32 | #' @usage NULL 33 | #' @export 34 | GeomBlank <- ggproto("GeomBlank", Geom, 35 | default_aes = aes(), 36 | handle_na = function(data, params) data, 37 | draw_panel = function(...) nullGrob() 38 | ) 39 | -------------------------------------------------------------------------------- /tests/testthat/test-stats-function.r: -------------------------------------------------------------------------------- 1 | context("stat_function") 2 | 3 | test_that("uses scale limits, not data limits", { 4 | dat <- data.frame(x = c(0.1, 1:100)) 5 | dat$y <- dexp(dat$x) 6 | 7 | base <- ggplot(dat, aes(x, y)) + 8 | stat_function(fun = dexp) 9 | 10 | full <- base + 11 | scale_x_continuous(limits = c(0.1, 100)) + 12 | scale_y_continuous() 13 | ret <- layer_data(full) 14 | 15 | full_log <- base + 16 | scale_x_log10(limits = c(0.1, 100)) + 17 | scale_y_continuous() 18 | ret_log <- layer_data(full_log) 19 | 20 | expect_equal(ret$y[c(1, 101)], ret_log$y[c(1, 101)]) 21 | expect_equal(range(ret$x), c(0.1, 100)) 22 | expect_equal(range(ret_log$x), c(-1, 2)) 23 | expect_false(any(is.na(ret$y))) 24 | expect_false(any(is.na(ret_log$y))) 25 | }) 26 | 27 | test_that("works with discrete x", { 28 | dat <- data.frame(x = c("a", "b")) 29 | 30 | base <- ggplot(dat, aes(x, group = 1)) + 31 | stat_function(fun = as.numeric, geom = "point", n = 2) 32 | ret <- layer_data(base) 33 | 34 | expect_equal(ret$x, 1:2) 35 | expect_equal(ret$y, 1:2) 36 | }) 37 | -------------------------------------------------------------------------------- /R/hexbin.R: -------------------------------------------------------------------------------- 1 | hex_binwidth <- function(bins = 30, scales) { 2 | c( 3 | diff(scales$x$dimension()) / bins, 4 | diff(scales$y$dimension()) / bins 5 | ) 6 | } 7 | 8 | hex_bounds <- function(x, binwidth) { 9 | c( 10 | plyr::round_any(min(x), binwidth, floor) - 1e-6, 11 | plyr::round_any(max(x), binwidth, ceiling) + 1e-6 12 | ) 13 | } 14 | 15 | hexBinSummarise <- function(x, y, z, binwidth, fun = mean, fun.args = list(), drop = TRUE) { 16 | # Convert binwidths into bounds + nbins 17 | xbnds <- hex_bounds(x, binwidth[1]) 18 | xbins <- diff(xbnds) / binwidth[1] 19 | 20 | ybnds <- hex_bounds(y, binwidth[2]) 21 | ybins <- diff(ybnds) / binwidth[2] 22 | 23 | # Call hexbin 24 | hb <- hexbin::hexbin( 25 | x, xbnds = xbnds, xbins = xbins, 26 | y, ybnds = ybnds, shape = ybins / xbins, 27 | IDs = TRUE 28 | ) 29 | 30 | value <- do.call(tapply, c(list(quote(z), quote(hb@cID), quote(fun)), fun.args)) 31 | 32 | # Convert to data frame 33 | out <- as.data.frame(hexbin::hcell2xy(hb)) 34 | out$value <- as.vector(value) 35 | 36 | if (drop) out <- stats::na.omit(out) 37 | out 38 | } 39 | -------------------------------------------------------------------------------- /man/scale_linetype.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/scale-linetype.r 3 | \name{scale_linetype} 4 | \alias{scale_linetype} 5 | \alias{scale_linetype_continuous} 6 | \alias{scale_linetype_discrete} 7 | \title{Scale for line patterns.} 8 | \usage{ 9 | scale_linetype(..., na.value = "blank") 10 | 11 | scale_linetype_continuous(...) 12 | 13 | scale_linetype_discrete(..., na.value = "blank") 14 | } 15 | \arguments{ 16 | \item{...}{common discrete scale parameters: \code{name}, \code{breaks}, 17 | \code{labels}, \code{na.value}, \code{limits} and \code{guide}. See 18 | \code{\link{discrete_scale}} for more details} 19 | 20 | \item{na.value}{The linetype to use for \code{NA} values.} 21 | } 22 | \description{ 23 | Default line types based on a set supplied by Richard Pearson, 24 | University of Manchester. Line types can not be mapped to continuous 25 | values. 26 | } 27 | \examples{ 28 | base <- ggplot(economics_long, aes(date, value01)) 29 | base + geom_line(aes(group = variable)) 30 | base + geom_line(aes(linetype = variable)) 31 | 32 | # See scale_manual for more flexibility 33 | } 34 | -------------------------------------------------------------------------------- /man/diamonds.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{diamonds} 5 | \alias{diamonds} 6 | \title{Prices of 50,000 round cut diamonds} 7 | \format{A data frame with 53940 rows and 10 variables: 8 | \itemize{ 9 | \item price: price in US dollars (\$326--\$18,823) 10 | \item carat: weight of the diamond (0.2--5.01) 11 | \item cut: quality of the cut (Fair, Good, Very Good, Premium, Ideal) 12 | \item color: diamond colour, from J (worst) to D (best) 13 | \item clarity: a measurement of how clear the diamond is 14 | (I1 (worst), SI1, SI2, VS1, VS2, VVS1, VVS2, IF (best)) 15 | \item x: length in mm (0--10.74) 16 | \item y: width in mm (0--58.9) 17 | \item z: depth in mm (0--31.8) 18 | \item depth: total depth percentage = z / mean(x, y) = 2 * z / (x + y) (43--79) 19 | \item table: width of top of diamond relative to widest point (43--95) 20 | }} 21 | \usage{ 22 | diamonds 23 | } 24 | \description{ 25 | A dataset containing the prices and other attributes of almost 54,000 26 | diamonds. The variables are as follows: 27 | } 28 | \keyword{datasets} 29 | -------------------------------------------------------------------------------- /old-README-ggplot2.md: -------------------------------------------------------------------------------- 1 | # ggplot2 2 | 3 | [![Build Status](https://travis-ci.org/hadley/ggplot2.png?branch=master)](https://travis-ci.org/hadley/ggplot2) 4 | [![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/ggplot2)](http://cran.r-project.org/package=ggplot2) 5 | 6 | ggplot2 is a plotting system for R, based on the grammar of graphics, which tries to take the good parts of base and lattice graphics and avoid bad parts. It takes care of many of the fiddly details 7 | that make plotting a hassle (like drawing legends) as well as providing a powerful model of graphics that makes it easy to produce complex multi-layered graphics. 8 | 9 | Find out more at , and check out the nearly 500 10 | examples of ggplot in use. If you're interested, you can also sign up to 11 | the [ggplot2 mailing list at](http://groups.google.com/group/ggplot2). 12 | 13 | ## Installation 14 | 15 | Get the released version from CRAN: 16 | 17 | ```R 18 | install.packages("ggplot2") 19 | ``` 20 | 21 | Or the development version from github: 22 | 23 | ```R 24 | # install.packages("devtools") 25 | devtools::install_github("hadley/ggplot2") 26 | ``` 27 | -------------------------------------------------------------------------------- /R/utilities-help.r: -------------------------------------------------------------------------------- 1 | aesthetics <- function(x) { 2 | req_aes <- x$required_aes 3 | def_aes <- names(x$default_aes) 4 | def_aes <- setdiff(def_aes, req_aes) 5 | if (length(req_aes) == 0) { 6 | # Suppress warnings which occur when sorting NULL 7 | return(suppressWarnings(sort(names(x$default_aes)))) 8 | } 9 | if (length(def_aes) == 0) { 10 | return(paste("\\strong{", sort(x$required_aes), "}",sep = "")) 11 | } 12 | return(c(paste("\\strong{", sort(x$required_aes), "}", sep = ""), sort(def_aes))) 13 | } 14 | geom_aesthetics <- function(x) { 15 | aesthetics(find_subclass("Geom", x)) 16 | } 17 | stat_aesthetics <- function(x) { 18 | aesthetics(find_subclass("Stat", x)) 19 | } 20 | 21 | rd_aesthetics <- function(type, name) { 22 | obj <- switch(type, 23 | geom = find_subclass("Geom", name), 24 | stat = find_subclass("Stat", name) 25 | ) 26 | aes <- aesthetics(obj) 27 | 28 | paste("\\code{", type, "_", name, "} ", 29 | "understands the following aesthetics (required aesthetics are in bold):\n\n", 30 | "\\itemize{\n", 31 | paste(" \\item \\code{", aes, "}", collapse = "\n", sep = ""), 32 | "\n}\n", sep = "") 33 | } 34 | -------------------------------------------------------------------------------- /inst/staticdocs/head.html: -------------------------------------------------------------------------------- 1 | 2 | {{pagetitle}}. {{#package}}{{package}} {{version}}{{/package}} 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 28 | -------------------------------------------------------------------------------- /R/stat-unique.r: -------------------------------------------------------------------------------- 1 | #' Remove duplicates. 2 | #' 3 | #' @section Aesthetics: 4 | #' \Sexpr[results=rd,stage=build]{lwplot:::rd_aesthetics("stat", "unique")} 5 | #' 6 | #' @export 7 | #' @inheritParams layer 8 | #' @inheritParams geom_point 9 | #' @examples 10 | #' ggplot(mtcars, aes(vs, am)) + geom_point(alpha = 0.1) 11 | #' ggplot(mtcars, aes(vs, am)) + geom_point(alpha = 0.1, stat="unique") 12 | stat_unique <- function(mapping = NULL, data = NULL, 13 | geom = "point", position = "identity", 14 | ..., 15 | na.rm = FALSE, 16 | show.legend = NA, 17 | inherit.aes = TRUE) { 18 | layer( 19 | data = data, 20 | mapping = mapping, 21 | stat = StatUnique, 22 | geom = geom, 23 | position = position, 24 | show.legend = show.legend, 25 | inherit.aes = inherit.aes, 26 | params = list( 27 | na.rm = na.rm, 28 | ... 29 | ) 30 | ) 31 | } 32 | 33 | #' @rdname ggplot2-ggproto 34 | #' @format NULL 35 | #' @usage NULL 36 | #' @export 37 | StatUnique <- ggproto("StatUnique", Stat, 38 | compute_panel = function(data, scales) unique(data) 39 | ) 40 | -------------------------------------------------------------------------------- /R/guides-grid.r: -------------------------------------------------------------------------------- 1 | # Produce a grob to be used as for panel backgrounds 2 | guide_grid <- function(theme, x.minor, x.major, y.minor, y.major) { 3 | 4 | x.minor <- setdiff(x.minor, x.major) 5 | y.minor <- setdiff(y.minor, y.major) 6 | 7 | ggname("grill", grobTree( 8 | element_render(theme, "panel.background"), 9 | if (length(y.minor) > 0) element_render( 10 | theme, "panel.grid.minor.y", 11 | x = rep(0:1, length(y.minor)), y = rep(y.minor, each = 2), 12 | id.lengths = rep(2, length(y.minor)) 13 | ), 14 | if (length(x.minor) > 0) element_render( 15 | theme, "panel.grid.minor.x", 16 | x = rep(x.minor, each = 2), y = rep(0:1, length(x.minor)), 17 | id.lengths = rep(2, length(x.minor)) 18 | ), 19 | if (length(y.major) > 0) element_render( 20 | theme, "panel.grid.major.y", 21 | x = rep(0:1, length(y.major)), y = rep(y.major, each = 2), 22 | id.lengths = rep(2, length(y.major)) 23 | ), 24 | if (length(x.major) > 0) element_render( 25 | theme, "panel.grid.major.x", 26 | x = rep(x.major, each = 2), y = rep(0:1, length(x.major)), 27 | id.lengths = rep(2, length(x.major)) 28 | ) 29 | )) 30 | } 31 | -------------------------------------------------------------------------------- /R/position-nudge.R: -------------------------------------------------------------------------------- 1 | #' Nudge points. 2 | #' 3 | #' This is useful if you want to nudge labels a little ways from their 4 | #' points. 5 | #' 6 | #' @family position adjustments 7 | #' @param x,y Amount of vertical and horizontal distance to move. 8 | #' @export 9 | #' @examples 10 | #' df <- data.frame( 11 | #' x = c(1,3,2,5), 12 | #' y = c("a","c","d","c") 13 | #' ) 14 | #' 15 | #' ggplot(df, aes(x, y)) + 16 | #' geom_point() + 17 | #' geom_text(aes(label = y)) 18 | #' 19 | #' ggplot(df, aes(x, y)) + 20 | #' geom_point() + 21 | #' geom_text(aes(label = y), position = position_nudge(y = -0.1)) 22 | position_nudge <- function(x = 0, y = 0) { 23 | ggproto(NULL, PositionNudge, 24 | x = x, 25 | y = y 26 | ) 27 | } 28 | 29 | #' @rdname ggplot2-ggproto 30 | #' @format NULL 31 | #' @usage NULL 32 | #' @export 33 | PositionNudge <- ggproto("PositionNudge", Position, 34 | x = 0, 35 | y = 0, 36 | 37 | required_aes = c("x", "y"), 38 | 39 | setup_params = function(self, data) { 40 | list(x = self$x, y = self$y) 41 | }, 42 | 43 | compute_layer = function(data, params, panel) { 44 | transform_position(data, function(x) x + params$x, function(y) y + params$y) 45 | } 46 | ) 47 | -------------------------------------------------------------------------------- /man/ggplot_build.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot-build.r 3 | \name{ggplot_build} 4 | \alias{ggplot_build} 5 | \alias{layer_data} 6 | \alias{layer_scales} 7 | \alias{layer_grob} 8 | \title{Build ggplot for rendering.} 9 | \usage{ 10 | ggplot_build(plot) 11 | 12 | layer_data(plot, i = 1L) 13 | 14 | layer_scales(plot, i = 1L, j = 1L) 15 | 16 | layer_grob(plot, i = 1L) 17 | } 18 | \arguments{ 19 | \item{plot}{ggplot object} 20 | } 21 | \description{ 22 | \code{ggplot_build} takes the plot object, and performs all steps necessary 23 | to produce an object that can be rendered. This function outputs two pieces: 24 | a list of data frames (one for each layer), and a panel object, which 25 | contain all information about axis limits, breaks etc. 26 | } 27 | \details{ 28 | \code{layer_data}, \code{layer_grob}, and \code{layer_scales} are helper 29 | functions that returns the data, grob, or scales associated with a given 30 | layer. These are useful for tests. 31 | } 32 | \seealso{ 33 | \code{\link{print.ggplot}} and \code{\link{benchplot}} for 34 | functions that contain the complete set of steps for generating 35 | a ggplot2 plot. 36 | } 37 | \keyword{internal} 38 | -------------------------------------------------------------------------------- /tests/testthat/test-stat-bin2d.R: -------------------------------------------------------------------------------- 1 | context("stat_bin2d") 2 | 3 | test_that("binwidth is respected", { 4 | df <- data.frame(x = c(1, 1, 1, 2), y = c(1, 1, 1, 2)) 5 | base <- ggplot(df, aes(x, y)) + 6 | stat_bin2d(geom = "tile", binwidth = 0.25) 7 | 8 | out <- layer_data(base) 9 | expect_equal(nrow(out), 2) 10 | # Adjust tolerance to account for fuzzy breaks adjustment 11 | expect_equal(out$xmin, c(1, 1.75), tolerance = 1e-7) 12 | expect_equal(out$xmax, c(1.25, 2), tolerance = 1e-7) 13 | }) 14 | 15 | test_that("breaks override binwidth", { 16 | # Test explicitly setting the breaks for x, overriding 17 | # the binwidth. 18 | integer_breaks <- (0:4) - 0.5 # Will use for x 19 | half_breaks <- seq(0, 3.5, 0.5) # Will test against this for y 20 | 21 | df <- data.frame(x = 0:3, y = 0:3) 22 | base <- ggplot(df, aes(x, y)) + 23 | stat_bin2d( 24 | breaks = list(x = integer_breaks, y = NULL), 25 | binwidth = c(0.5, 0.5) 26 | ) 27 | 28 | out <- layer_data(base) 29 | expect_equal(out$xbin, cut(df$x, adjust_breaks(integer_breaks), include.lowest = TRUE, labels = FALSE)) 30 | expect_equal(out$ybin, cut(df$y, adjust_breaks(half_breaks), include.lowest = TRUE, labels = FALSE)) 31 | }) 32 | -------------------------------------------------------------------------------- /man/annotation_map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/annotation-map.r 3 | \name{annotation_map} 4 | \alias{annotation_map} 5 | \title{Annotation: maps.} 6 | \usage{ 7 | annotation_map(map, ...) 8 | } 9 | \arguments{ 10 | \item{map}{data frame representing a map. Most map objects can be 11 | converted into the right format by using \code{\link{fortify}}} 12 | 13 | \item{...}{other arguments used to modify aesthetics} 14 | } 15 | \description{ 16 | Annotation: maps. 17 | } 18 | \examples{ 19 | if (requireNamespace("maps", quietly=TRUE)) { 20 | usamap <- map_data("state") 21 | 22 | seal.sub <- subset(seals, long > -130 & lat < 45 & lat > 40) 23 | ggplot(seal.sub, aes(x = long, y = lat)) + 24 | annotation_map(usamap, fill = "NA", colour = "grey50") + 25 | geom_segment(aes(xend = long + delta_long, yend = lat + delta_lat)) 26 | 27 | seal2 <- transform(seal.sub, 28 | latr = cut(lat, 2), 29 | longr = cut(long, 2)) 30 | 31 | ggplot(seal2, aes(x = long, y = lat)) + 32 | annotation_map(usamap, fill = "NA", colour = "grey50") + 33 | geom_segment(aes(xend = long + delta_long, yend = lat + delta_lat)) + 34 | facet_grid(latr ~ longr, scales = "free", space = "free") 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /man/label_bquote.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/facet-labels.r 3 | \name{label_bquote} 4 | \alias{label_bquote} 5 | \title{Backquoted labeller} 6 | \usage{ 7 | label_bquote(rows = NULL, cols = NULL, default = label_value) 8 | } 9 | \arguments{ 10 | \item{rows}{Backquoted labelling expression for rows.} 11 | 12 | \item{cols}{Backquoted labelling expression for columns.} 13 | 14 | \item{default}{Default labeller function for the rows or the 15 | columns when no plotmath expression is provided.} 16 | } 17 | \description{ 18 | \code{\link{label_bquote}()} offers a flexible way of labelling 19 | facet rows or columns with plotmath expressions. Backquoted 20 | variables will be replaced with their value in the facet. 21 | } 22 | \examples{ 23 | # The variables mentioned in the plotmath expression must be 24 | # backquoted and referred to by their names. 25 | p <- ggplot(mtcars, aes(wt, mpg)) + geom_point() 26 | p + facet_grid(vs ~ ., labeller = label_bquote(alpha ^ .(vs))) 27 | p + facet_grid(. ~ vs, labeller = label_bquote(cols = .(vs) ^ .(vs))) 28 | p + facet_grid(. ~ vs + am, labeller = label_bquote(cols = .(am) ^ .(vs))) 29 | } 30 | \seealso{ 31 | \link{labellers}, \code{\link{labeller}()}, 32 | } 33 | -------------------------------------------------------------------------------- /man/scale_alpha.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/scale-alpha.r 3 | \name{scale_alpha} 4 | \alias{scale_alpha} 5 | \alias{scale_alpha_continuous} 6 | \alias{scale_alpha_discrete} 7 | \title{Alpha scales.} 8 | \usage{ 9 | scale_alpha(..., range = c(0.1, 1)) 10 | 11 | scale_alpha_continuous(..., range = c(0.1, 1)) 12 | 13 | scale_alpha_discrete(..., range = c(0.1, 1)) 14 | } 15 | \arguments{ 16 | \item{...}{Other arguments passed on to \code{\link{continuous_scale}} 17 | or \code{\link{discrete_scale}} as appropriate, to control name, limits, 18 | breaks, labels and so forth.} 19 | 20 | \item{range}{range of output alpha values. Should lie between 0 and 1.} 21 | } 22 | \description{ 23 | \code{scale_alpha} is an alias for \code{scale_alpha_continuous} since 24 | that is the most common use of alpha, and it saves a bit of typing. 25 | } 26 | \examples{ 27 | (p <- ggplot(mtcars, aes(mpg, cyl)) + 28 | geom_point(aes(alpha = cyl))) 29 | p + scale_alpha("cylinders") 30 | p + scale_alpha("number\\nof\\ncylinders") 31 | 32 | p + scale_alpha(range = c(0.4, 0.8)) 33 | 34 | (p <- ggplot(mtcars, aes(mpg, cyl)) + 35 | geom_point(aes(alpha = factor(cyl)))) 36 | p + scale_alpha_discrete(range = c(0.4, 0.8)) 37 | } 38 | -------------------------------------------------------------------------------- /tests/testthat/test-boxplot.r: -------------------------------------------------------------------------------- 1 | context("Boxplot") 2 | 3 | # thanks wch for providing the test code 4 | test_that("geom_boxplot range includes all outliers", { 5 | dat <- data.frame(x = 1, y = c(-(1:20) ^ 3, (1:20) ^ 3) ) 6 | p <- ggplot_build(ggplot(dat, aes(x,y)) + geom_boxplot()) 7 | 8 | miny <- p$panel$ranges[[1]]$y.range[1] 9 | maxy <- p$panel$ranges[[1]]$y.range[2] 10 | 11 | expect_true(miny <= min(dat$y)) 12 | expect_true(maxy >= max(dat$y)) 13 | }) 14 | 15 | test_that("geom_boxplot for continuous x gives warning if more than one x (#992)", { 16 | dat <- expand.grid(x = 1:2, y = c(-(1:5) ^ 3, (1:5) ^ 3) ) 17 | 18 | bplot <- function(aes = NULL, extra = list()) { 19 | ggplot_build(ggplot(dat, aes) + geom_boxplot(aes) + extra) 20 | } 21 | 22 | expect_warning(bplot(aes(x, y)), "Continuous x aesthetic") 23 | expect_warning(bplot(aes(x, y), facet_wrap(~x)), "Continuous x aesthetic") 24 | expect_warning(bplot(aes(Sys.Date() + x, y)), "Continuous x aesthetic") 25 | 26 | expect_warning(bplot(aes(x, group = x, y)), NA) 27 | expect_warning(bplot(aes(1, y)), NA) 28 | expect_warning(bplot(aes(factor(x), y)), NA) 29 | expect_warning(bplot(aes(x == 1, y)), NA) 30 | expect_warning(bplot(aes(as.character(x), y)), NA) 31 | }) 32 | -------------------------------------------------------------------------------- /man/labs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/labels.r 3 | \name{labs} 4 | \alias{labs} 5 | \alias{xlab} 6 | \alias{ylab} 7 | \alias{ggtitle} 8 | \title{Change axis labels and legend titles} 9 | \usage{ 10 | labs(...) 11 | 12 | xlab(label) 13 | 14 | ylab(label) 15 | 16 | ggtitle(label) 17 | } 18 | \arguments{ 19 | \item{...}{a list of new names in the form aesthetic = "new name"} 20 | 21 | \item{label}{The text for the axis or plot title.} 22 | } 23 | \description{ 24 | Change axis labels and legend titles 25 | } 26 | \examples{ 27 | p <- ggplot(mtcars, aes(mpg, wt)) + geom_point() 28 | p + labs(title = "New plot title") 29 | p + labs(x = "New x label") 30 | p + xlab("New x label") 31 | p + ylab("New y label") 32 | p + ggtitle("New plot title") 33 | 34 | # This should work independently of other functions that modify the 35 | # the scale names 36 | p + ylab("New y label") + ylim(2, 4) 37 | p + ylim(2, 4) + ylab("New y label") 38 | 39 | # The labs function also modifies legend labels 40 | p <- ggplot(mtcars, aes(mpg, wt, colour = cyl)) + geom_point() 41 | p + labs(colour = "Cylinders") 42 | 43 | # Can also pass in a list, if that is more convenient 44 | p + labs(list(title = "Title", x = "X", y = "Y")) 45 | } 46 | -------------------------------------------------------------------------------- /man/economics.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{economics} 5 | \alias{economics} 6 | \alias{economics_long} 7 | \title{US economic time series.} 8 | \format{A data frame with 478 rows and 6 variables 9 | \itemize{ 10 | \item date. Month of data collection 11 | \item psavert, personal savings rate, 12 | \url{http://research.stlouisfed.org/fred2/series/PSAVERT/} 13 | \item pce, personal consumption expenditures, in billions of dollars, 14 | \url{http://research.stlouisfed.org/fred2/series/PCE} 15 | \item unemploy, number of unemployed in thousands, 16 | \url{http://research.stlouisfed.org/fred2/series/UNEMPLOY} 17 | \item uempmed, median duration of unemployment, in week, 18 | \url{http://research.stlouisfed.org/fred2/series/UEMPMED} 19 | \item pop, total population, in thousands, 20 | \url{http://research.stlouisfed.org/fred2/series/POP} 21 | }} 22 | \usage{ 23 | economics 24 | 25 | economics_long 26 | } 27 | \description{ 28 | This dataset was produced from US economic time series data available from 29 | \url{http://research.stlouisfed.org/fred2}. \code{economics} is in "wide" 30 | format, \code{economics_long} is in "long" format. 31 | } 32 | \keyword{datasets} 33 | -------------------------------------------------------------------------------- /R/grob-absolute.r: -------------------------------------------------------------------------------- 1 | #' Absolute grob 2 | #' 3 | #' This grob has fixed dimensions and position. 4 | #' 5 | #' It's still experimental 6 | #' 7 | #' @keywords internal 8 | absoluteGrob <- function(grob, width = NULL, height = NULL, 9 | xmin = NULL, ymin = NULL, vp = NULL) { 10 | 11 | gTree( 12 | children = grob, 13 | width = width, height = height, 14 | xmin = xmin, ymin = ymin, 15 | vp = vp, cl = "absoluteGrob" 16 | ) 17 | } 18 | 19 | #' @export 20 | #' @method grobHeight absoluteGrob 21 | grobHeight.absoluteGrob <- function(x) { 22 | x$height %||% grobHeight(x$children) 23 | } 24 | #' @export 25 | #' @method grobWidth absoluteGrob 26 | grobWidth.absoluteGrob <- function(x) { 27 | x$width %||% grobWidth(x$children) 28 | } 29 | 30 | #' @export 31 | #' @method grobX absoluteGrob 32 | grobX.absoluteGrob <- function(x, theta) { 33 | if (!is.null(x$xmin) && theta == "west") return(x$xmin) 34 | grobX(x$children, theta) 35 | } 36 | #' @export 37 | #' @method grobY absoluteGrob 38 | grobY.absoluteGrob <- function(x, theta) { 39 | if (!is.null(x$ymin) && theta == "south") return(x$ymin) 40 | grobY(x$children, theta) 41 | } 42 | 43 | #' @export 44 | #' @method grid.draw absoluteGrob 45 | grid.draw.absoluteGrob <- function(x, recording = TRUE) { 46 | NextMethod() 47 | } 48 | -------------------------------------------------------------------------------- /R/summary.r: -------------------------------------------------------------------------------- 1 | #' Displays a useful description of a ggplot object 2 | #' 3 | #' @param object ggplot2 object to summarise 4 | #' @param ... other arguments ignored (for compatibility with generic) 5 | #' @keywords internal 6 | #' @method summary ggplot 7 | #' @export 8 | #' @examples 9 | #' p <- ggplot(mtcars, aes(mpg, wt)) + 10 | #' geom_point() 11 | #' summary(p) 12 | summary.ggplot <- function(object, ...) { 13 | wrap <- function(x) paste( 14 | paste(strwrap(x, exdent = 2), collapse = "\n"), 15 | "\n", sep = "" 16 | ) 17 | 18 | if (!is.null(object$data)) { 19 | output <- paste( 20 | "data: ", paste(names(object$data), collapse = ", "), 21 | " [", nrow(object$data), "x", ncol(object$data), "] ", 22 | "\n", sep = "") 23 | cat(wrap(output)) 24 | } 25 | if (length(object$mapping) > 0) { 26 | cat("mapping: ", clist(object$mapping), "\n", sep = "") 27 | } 28 | if (object$scales$n() > 0) { 29 | cat("scales: ", paste(object$scales$input(), collapse = ", "), "\n") 30 | } 31 | 32 | cat("faceting: ") 33 | print(object$facet) 34 | 35 | if (length(object$layers) > 0) 36 | cat("-----------------------------------\n") 37 | invisible(lapply(object$layers, function(x) { 38 | print(x) 39 | cat("\n") 40 | })) 41 | 42 | } 43 | -------------------------------------------------------------------------------- /man/lims.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/limits.r 3 | \name{lims} 4 | \alias{lims} 5 | \alias{xlim} 6 | \alias{ylim} 7 | \title{Convenience functions to set the axis limits.} 8 | \usage{ 9 | lims(...) 10 | 11 | xlim(...) 12 | 13 | ylim(...) 14 | } 15 | \arguments{ 16 | \item{...}{If numeric, will create a continuous scale, if factor or 17 | character, will create a discrete scale. For \code{lims}, every 18 | argument must be named.} 19 | } 20 | \description{ 21 | Observations not in this range will be dropped completely and 22 | not passed to any other layers. If a NA value is substituted for one of the 23 | limits that limit is automatically calculated. 24 | } 25 | \examples{ 26 | # xlim 27 | xlim(15, 20) 28 | xlim(20, 15) 29 | xlim(c(10, 20)) 30 | xlim("a", "b", "c") 31 | 32 | ggplot(mtcars, aes(mpg, wt)) + 33 | geom_point() + 34 | xlim(15, 20) 35 | # with automatic lower limit 36 | ggplot(mtcars, aes(mpg, wt)) + 37 | geom_point() + 38 | xlim(NA, 20) 39 | 40 | # Change both xlim and ylim 41 | ggplot(mtcars, aes(mpg, wt)) + 42 | geom_point() + 43 | lims(x = c(10, 20), y = c(3, 5)) 44 | } 45 | \seealso{ 46 | For changing x or y axis limits \strong{without} dropping data 47 | observations, see \code{\link{coord_cartesian}}. 48 | } 49 | -------------------------------------------------------------------------------- /man/element_text.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme-elements.r 3 | \name{element_text} 4 | \alias{element_text} 5 | \title{Theme element: text.} 6 | \usage{ 7 | element_text(family = NULL, face = NULL, colour = NULL, 8 | size = NULL, hjust = NULL, vjust = NULL, angle = NULL, 9 | lineheight = NULL, color = NULL, margin = NULL, debug = NULL) 10 | } 11 | \arguments{ 12 | \item{family}{font family} 13 | 14 | \item{face}{font face ("plain", "italic", "bold", "bold.italic")} 15 | 16 | \item{colour}{text colour} 17 | 18 | \item{size}{text size (in pts)} 19 | 20 | \item{hjust}{horizontal justification (in [0, 1])} 21 | 22 | \item{vjust}{vertical justification (in [0, 1])} 23 | 24 | \item{angle}{angle (in [0, 360])} 25 | 26 | \item{lineheight}{line height} 27 | 28 | \item{color}{an alias for \code{colour}} 29 | 30 | \item{margin}{margins around the text. See \code{\link{margin}} for more 31 | details. When creating a theme, the margins should be placed on the 32 | side of the text facing towards the center of the plot.} 33 | 34 | \item{debug}{If \code{TRUE}, aids visual debugging by drawing a solid 35 | rectangle behind the complete text area, and a point where each label 36 | is anchored.} 37 | } 38 | \description{ 39 | Theme element: text. 40 | } 41 | -------------------------------------------------------------------------------- /man/msleep.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{msleep} 5 | \alias{msleep} 6 | \title{An updated and expanded version of the mammals sleep dataset.} 7 | \format{A data frame with 83 rows and 11 variables 8 | \itemize{ 9 | \item name. common name 10 | \item genus. 11 | \item vore. carnivore, omnivore or herbivore? 12 | \item order. 13 | \item conservation. the conservation status of the animal 14 | \item sleep\_total. total amount of sleep, in hours 15 | \item sleep\_rem. rem sleep, in hours 16 | \item sleep\_cycle. length of sleep cycle, in hours 17 | \item awake. amount of time spent awake, in hours 18 | \item brainwt. brain weight in kilograms 19 | \item bodywt. body weight in kilograms 20 | }} 21 | \usage{ 22 | msleep 23 | } 24 | \description{ 25 | This is an updated and expanded version of the mammals sleep dataset. 26 | Updated sleep times and weights were taken from V. M. Savage and G. B. 27 | West. A quantitative, theoretical framework for understanding mammalian 28 | sleep. Proceedings of the National Academy of Sciences, 104 (3):1051-1056, 29 | 2007. 30 | } 31 | \details{ 32 | Additional variables order, conservation status and vore were added from 33 | wikipedia. 34 | } 35 | \keyword{datasets} 36 | -------------------------------------------------------------------------------- /tests/testthat/test-geom-rule.R: -------------------------------------------------------------------------------- 1 | context("geom_rule") 2 | # tests for geom_vline, geom_hline & geom_abline 3 | 4 | df <- data.frame(x = 1:3, y = 3:1) 5 | p <- ggplot(df, aes(x, y)) + geom_point() 6 | p_col <- ggplot(df, aes(x, y, colour = factor(x))) + geom_point() 7 | 8 | test_that("setting parameters makes one row df", { 9 | b <- p + geom_hline(yintercept = 1.5) 10 | expect_equal(layer_data(b, 2)$yintercept, 1.5) 11 | 12 | b <- p + geom_vline(xintercept = 1.5) 13 | expect_equal(layer_data(b, 2)$xintercept, 1.5) 14 | 15 | b <- p + geom_abline() 16 | expect_equal(layer_data(b, 2)$intercept, 0) 17 | expect_equal(layer_data(b, 2)$slope, 1) 18 | 19 | b <- p + geom_abline(slope = 0, intercept = 1) 20 | expect_equal(layer_data(b, 2)$intercept, 1) 21 | expect_equal(layer_data(b, 2)$slope, 0) 22 | }) 23 | 24 | test_that("setting aesthetics generates one row for each input row", { 25 | b <- p + geom_hline(aes(yintercept = 1.5)) 26 | expect_equal(layer_data(b, 2)$yintercept, rep(1.5, 3)) 27 | 28 | b <- p + geom_vline(aes(xintercept = 1.5)) 29 | expect_equal(layer_data(b, 2)$xintercept, rep(1.5, 3)) 30 | 31 | b <- p + geom_abline(aes(slope = 0, intercept = 1)) 32 | expect_equal(layer_data(b, 2)$intercept, rep(1, 3)) 33 | expect_equal(layer_data(b, 2)$slope, rep(0, 3)) 34 | }) 35 | -------------------------------------------------------------------------------- /R/scale-alpha.r: -------------------------------------------------------------------------------- 1 | #' Alpha scales. 2 | #' 3 | #' \code{scale_alpha} is an alias for \code{scale_alpha_continuous} since 4 | #' that is the most common use of alpha, and it saves a bit of typing. 5 | #' 6 | #' @param ... Other arguments passed on to \code{\link{continuous_scale}} 7 | #' or \code{\link{discrete_scale}} as appropriate, to control name, limits, 8 | #' breaks, labels and so forth. 9 | #' @param range range of output alpha values. Should lie between 0 and 1. 10 | #' @export 11 | #' @examples 12 | #' (p <- ggplot(mtcars, aes(mpg, cyl)) + 13 | #' geom_point(aes(alpha = cyl))) 14 | #' p + scale_alpha("cylinders") 15 | #' p + scale_alpha("number\nof\ncylinders") 16 | #' 17 | #' p + scale_alpha(range = c(0.4, 0.8)) 18 | #' 19 | #' (p <- ggplot(mtcars, aes(mpg, cyl)) + 20 | #' geom_point(aes(alpha = factor(cyl)))) 21 | #' p + scale_alpha_discrete(range = c(0.4, 0.8)) 22 | scale_alpha <- function(..., range = c(0.1, 1)) { 23 | continuous_scale("alpha", "alpha_c", rescale_pal(range), ...) 24 | } 25 | 26 | #' @rdname scale_alpha 27 | #' @export 28 | scale_alpha_continuous <- scale_alpha 29 | 30 | #' @rdname scale_alpha 31 | #' @export 32 | scale_alpha_discrete <- function(..., range = c(0.1, 1)) { 33 | discrete_scale("alpha", "alpha_d", 34 | function(n) seq(range[1], range[2], length.out = n), ...) 35 | } 36 | -------------------------------------------------------------------------------- /R/utilities-matrix.r: -------------------------------------------------------------------------------- 1 | # Col union 2 | # Form the union of columns in a and b. If there are columns of the same name in both a and b, take the column from a. 3 | # 4 | # @param data frame a 5 | # @param data frame b 6 | # @keyword internal 7 | cunion <- function(a, b) { 8 | if (length(a) == 0) return(b) 9 | if (length(b) == 0) return(a) 10 | 11 | cbind(a, b[setdiff(names(b), names(a))]) 12 | } 13 | 14 | # Interleave (or zip) multiple units into one vector 15 | interleave <- function(...) UseMethod("interleave") 16 | #' @export 17 | interleave.unit <- function(...) { 18 | do.call("unit.c", do.call("interleave.default", plyr::llply(list(...), as.list))) 19 | } 20 | #' @export 21 | interleave.default <- function(...) { 22 | vectors <- list(...) 23 | 24 | # Check lengths 25 | lengths <- unique(setdiff(plyr::laply(vectors, length), 1)) 26 | if (length(lengths) == 0) lengths <- 1 27 | stopifnot(length(lengths) <= 1) 28 | 29 | # Replicate elements of length one up to correct length 30 | singletons <- plyr::laply(vectors, length) == 1 31 | vectors[singletons] <- plyr::llply(vectors[singletons], rep, lengths) 32 | 33 | # Interleave vectors 34 | n <- lengths 35 | p <- length(vectors) 36 | interleave <- rep(1:n, each = p) + seq(0, p - 1) * n 37 | unlist(vectors, recursive = FALSE)[interleave] 38 | } 39 | -------------------------------------------------------------------------------- /R/coord-quickmap.R: -------------------------------------------------------------------------------- 1 | #' @inheritParams coord_cartesian 2 | #' @export 3 | #' @rdname coord_map 4 | coord_quickmap <- function(xlim = NULL, ylim = NULL, expand = TRUE) { 5 | ggproto(NULL, CoordQuickmap, 6 | limits = list(x = xlim, y = ylim), 7 | expand = expand 8 | ) 9 | } 10 | 11 | #' @rdname ggplot2-ggproto 12 | #' @format NULL 13 | #' @usage NULL 14 | #' @export 15 | CoordQuickmap <- ggproto("CoordQuickmap", CoordCartesian, 16 | 17 | aspect = function(ranges) { 18 | # compute coordinates of center point of map 19 | x.center <- sum(ranges$x.range) / 2 20 | y.center <- sum(ranges$y.range) / 2 21 | 22 | # compute distance corresponding to 1 degree in either direction 23 | # from the center 24 | x.dist <- dist_central_angle(x.center + c(-0.5, 0.5), rep(y.center, 2)) 25 | y.dist <- dist_central_angle(rep(x.center, 2), y.center + c(-0.5, 0.5)) 26 | # NB: this makes the projection correct in the center of the plot and 27 | # increasingly less correct towards the edges. For regions of reasonnable 28 | # size, this seems to give better results than computing this ratio from 29 | # the total lat and lon span. 30 | 31 | # scale the plot with this aspect ratio 32 | ratio <- y.dist / x.dist 33 | 34 | diff(ranges$y.range) / diff(ranges$x.range) * ratio 35 | } 36 | ) 37 | -------------------------------------------------------------------------------- /man/scale_shape.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/scale-shape.r 3 | \name{scale_shape} 4 | \alias{scale_shape} 5 | \alias{scale_shape_discrete} 6 | \alias{scale_shape_continuous} 7 | \title{Scale for shapes, aka glyphs.} 8 | \usage{ 9 | scale_shape(..., solid = TRUE) 10 | } 11 | \arguments{ 12 | \item{...}{common discrete scale parameters: \code{name}, \code{breaks}, 13 | \code{labels}, \code{na.value}, \code{limits} and \code{guide}. See 14 | \code{\link{discrete_scale}} for more details} 15 | 16 | \item{solid}{Are the shapes solid, \code{TRUE}, or hollow \code{FALSE}?} 17 | } 18 | \description{ 19 | A continuous variable can not be mapped to shape. 20 | } 21 | \examples{ 22 | dsmall <- diamonds[sample(nrow(diamonds), 100), ] 23 | 24 | (d <- ggplot(dsmall, aes(carat, price)) + geom_point(aes(shape = cut))) 25 | d + scale_shape(solid = TRUE) # the default 26 | d + scale_shape(solid = FALSE) 27 | d + scale_shape(name = "Cut of diamond") 28 | d + scale_shape(name = "Cut of\\ndiamond") 29 | 30 | # To change order of levels, change order of 31 | # underlying factor 32 | levels(dsmall$cut) <- c("Fair", "Good", "Very Good", "Premium", "Ideal") 33 | 34 | # Need to recreate plot to pick up new data 35 | ggplot(dsmall, aes(price, carat)) + geom_point(aes(shape = cut)) 36 | 37 | # Or for short: 38 | d \%+\% dsmall 39 | } 40 | -------------------------------------------------------------------------------- /man/midwest.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{midwest} 5 | \alias{midwest} 6 | \title{Midwest demographics.} 7 | \format{A data frame with 437 rows and 28 variables 8 | \itemize{ 9 | \item PID 10 | \item county 11 | \item state 12 | \item area 13 | \item poptotal. Total population 14 | \item popdensity. Population density 15 | \item popwhite. Number of whites. 16 | \item popblack. Number of blacks. 17 | \item popamerindian. Number of American Indians. 18 | \item popasian. Number of Asians. 19 | \item popother. Number of other races. 20 | \item percwhite. Percent white. 21 | \item percblack. Percent black. 22 | \item percamerindan. Percent American Indian. 23 | \item percasian. Percent Asian. 24 | \item percother. Percent other races. 25 | \item popadults. Number of adults. 26 | \item perchsd. 27 | \item percollege. Percent college educated. 28 | \item percprof. Percent profession. 29 | \item poppovertyknown. 30 | \item percpovertyknown 31 | \item percbelowpoverty 32 | \item percchildbelowpovert 33 | \item percadultpoverty 34 | \item percelderlypoverty 35 | \item inmetro. In a metro area. 36 | \item category' 37 | }} 38 | \usage{ 39 | midwest 40 | } 41 | \description{ 42 | Demographic information of midwest counties 43 | } 44 | \keyword{datasets} 45 | -------------------------------------------------------------------------------- /R/utilities-table.r: -------------------------------------------------------------------------------- 1 | compute_grob_widths <- function(grob_layout, widths) { 2 | cols <- split(grob_layout, grob_layout$l) 3 | do.call("unit.c", lapply(cols, compute_grob_dimensions, dims = widths)) 4 | } 5 | 6 | compute_grob_heights <- function(grob_layout, heights) { 7 | cols <- split(grob_layout, grob_layout$t) 8 | do.call("unit.c", lapply(cols, compute_grob_dimensions, dims = heights)) 9 | } 10 | 11 | compute_grob_dimensions <- function(grob_layout, dims) { 12 | # If any don't have explicit dims, then width is NULL 13 | if (!any(grob_layout$type %in% names(dims))) { 14 | return(unit(1, "null")) 15 | } 16 | 17 | grob_layout <- grob_layout[grob_layout$type %in% names(dims), , drop = FALSE] 18 | 19 | dims <- unique(Map(function(type, pos) { 20 | type_width <- dims[[type]] 21 | if (length(type_width) == 1) type_width else type_width[pos] 22 | }, grob_layout$type, grob_layout$id)) 23 | units <- vapply(dims, is.unit, logical(1)) 24 | 25 | if (all(units)) { 26 | if (all(lapply(dims, attr, "unit") == "null")) unit(max(unlist(dims)), "null") 27 | else do.call("max", dims) 28 | } else { 29 | raw_max <- unit(max(unlist(dims[!units])), "cm") 30 | if (any(units)) { 31 | unit_max <- max(do.call("unit.c", dims[units])) 32 | max(raw_max, unit_max) 33 | } 34 | else { 35 | raw_max 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/testthat/test-fortify.r: -------------------------------------------------------------------------------- 1 | context("Fortify") 2 | library(sp) 3 | 4 | test_that("Spatial polygons have correct ordering", { 5 | make_square <- function(x = 0, y = 0, height = 1, width = 1){ 6 | delx <- width/2 7 | dely <- height/2 8 | Polygon(matrix(c(x + delx, x - delx,x - delx,x + delx,x + delx , 9 | y - dely,y - dely,y + dely,y + dely,y - dely), ncol = 2)) 10 | } 11 | 12 | make_hole <- function(x = 0, y = 0, height = .5, width = .5){ 13 | p <- make_square(x = x, y = y, height = height, width = width) 14 | p@hole <- TRUE 15 | p 16 | } 17 | 18 | fake_data <- data.frame(ids = 1:5, region = c(1,1,2,3,4)) 19 | rownames(fake_data) <- 1:5 20 | polys <- list(Polygons(list(make_square(), make_hole()), 1), 21 | Polygons(list(make_square(1,0), make_square(2, 0)), 2), 22 | Polygons(list(make_square(1,1)), 3), 23 | Polygons(list(make_square(0,1)), 4), 24 | Polygons(list(make_square(0,3)), 5)) 25 | 26 | 27 | polys_sp <- SpatialPolygons(polys) 28 | fake_sp <- SpatialPolygonsDataFrame(polys_sp, fake_data) 29 | 30 | # now reorder regions 31 | polys2 <- rev(polys) 32 | polys2_sp <- SpatialPolygons(polys2) 33 | fake_sp2 <- SpatialPolygonsDataFrame(polys2_sp, fake_data) 34 | 35 | expect_equivalent(fortify(fake_sp), plyr::arrange(fortify(fake_sp2), id, order)) 36 | 37 | }) 38 | -------------------------------------------------------------------------------- /R/geom-defaults.r: -------------------------------------------------------------------------------- 1 | #' Modify geom/stat aesthetic defaults for future plots 2 | #' 3 | #' @param stat,geom Name of geom/stat to modify (like \code{"point"} or 4 | #' \code{"bin"}), or a Geom/Stat object (like \code{GeomPoint} or 5 | #' \code{StatBin}). 6 | #' @param new Named list of aesthetics. 7 | #' @export 8 | #' @examples 9 | #' update_geom_defaults("point", list(colour = "darkblue")) 10 | #' ggplot(mtcars, aes(mpg, wt)) + geom_point() 11 | #' update_geom_defaults("point", list(colour = "black")) 12 | #' @rdname update_defaults 13 | update_geom_defaults <- function(geom, new) { 14 | if (is.character(geom)) { 15 | g <- find_subclass("Geom", geom) 16 | } else if (inherits(geom, "Geom")) { 17 | g <- geom 18 | } else { 19 | stop('`geom` must be a string (like "point") or a Geom object (like GeomPoint).', 20 | call. = FALSE) 21 | } 22 | 23 | old <- g$default_aes 24 | g$default_aes <- defaults(new, old) 25 | } 26 | 27 | #' @rdname update_defaults 28 | #' @export 29 | update_stat_defaults <- function(stat, new) { 30 | if (is.character(stat)) { 31 | g <- find_subclass("Stat", stat) 32 | } else if (inherits(stat, "Stat")) { 33 | g <- stat 34 | } else { 35 | stop('`stat` must be a string (like "point") or a Stat object (like StatBin).', 36 | call. = FALSE) 37 | } 38 | 39 | old <- g$default_aes 40 | g$default_aes <- defaults(new, old) 41 | } 42 | -------------------------------------------------------------------------------- /R/scale-shape.r: -------------------------------------------------------------------------------- 1 | #' Scale for shapes, aka glyphs. 2 | #' 3 | #' A continuous variable can not be mapped to shape. 4 | #' 5 | #' @param solid Are the shapes solid, \code{TRUE}, or hollow \code{FALSE}? 6 | #' @inheritParams scale_x_discrete 7 | #' @rdname scale_shape 8 | #' @export 9 | #' @examples 10 | #' dsmall <- diamonds[sample(nrow(diamonds), 100), ] 11 | #' 12 | #' (d <- ggplot(dsmall, aes(carat, price)) + geom_point(aes(shape = cut))) 13 | #' d + scale_shape(solid = TRUE) # the default 14 | #' d + scale_shape(solid = FALSE) 15 | #' d + scale_shape(name = "Cut of diamond") 16 | #' d + scale_shape(name = "Cut of\ndiamond") 17 | #' 18 | #' # To change order of levels, change order of 19 | #' # underlying factor 20 | #' levels(dsmall$cut) <- c("Fair", "Good", "Very Good", "Premium", "Ideal") 21 | #' 22 | #' # Need to recreate plot to pick up new data 23 | #' ggplot(dsmall, aes(price, carat)) + geom_point(aes(shape = cut)) 24 | #' 25 | #' # Or for short: 26 | #' d %+% dsmall 27 | scale_shape <- function(..., solid = TRUE) { 28 | discrete_scale("shape", "shape_d", shape_pal(solid), ...) 29 | } 30 | 31 | #' @rdname scale_shape 32 | #' @export 33 | #' @usage NULL 34 | scale_shape_discrete <- scale_shape 35 | 36 | #' @rdname scale_shape 37 | #' @export 38 | #' @usage NULL 39 | scale_shape_continuous <- function(...) { 40 | stop("A continuous variable can not be mapped to shape", call. = FALSE) 41 | } 42 | -------------------------------------------------------------------------------- /man/gg_dep.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utilities.r 3 | \name{gg_dep} 4 | \alias{gg_dep} 5 | \title{Give a deprecation error, warning, or message, depending on version number.} 6 | \usage{ 7 | gg_dep(version, msg) 8 | } 9 | \arguments{ 10 | \item{version}{The last version of ggplot2 where this function was good 11 | (in other words, the last version where it was not deprecated).} 12 | 13 | \item{msg}{The message to print.} 14 | } 15 | \description{ 16 | Version numbers have the format .., like 0.9.2. 17 | This function compares the current version number of ggplot2 against the 18 | specified \code{version}, which is the most recent version before the 19 | function (or other object) was deprecated. 20 | } 21 | \details{ 22 | \code{gg_dep} will give an error, warning, or message, depending on the 23 | difference between the current ggplot2 version and the specified 24 | \code{version}. 25 | 26 | If the current major number is greater than \code{version}'s major number, 27 | or if the current minor number is more than 1 greater than \code{version}'s 28 | minor number, give an error. 29 | 30 | If the current minor number differs from \code{version}'s minor number by 31 | one, give a warning. 32 | 33 | If the current subminor number differs from \code{version}'s subminor 34 | number, print a message. 35 | } 36 | \keyword{internal} 37 | -------------------------------------------------------------------------------- /R/geom-bin2d.r: -------------------------------------------------------------------------------- 1 | #' Add heatmap of 2d bin counts. 2 | #' 3 | #' @section Aesthetics: 4 | #' \Sexpr[results=rd,stage=build]{lwplot:::rd_aesthetics("stat", "bin2d")} 5 | #' 6 | #' @export 7 | #' @inheritParams layer 8 | #' @inheritParams geom_point 9 | #' @param geom,stat Use to override the default connection between 10 | #' \code{geom_bin2d} and \code{stat_bin2d}. 11 | #' @seealso \code{\link{stat_binhex}} for hexagonal binning 12 | #' @examples 13 | #' d <- ggplot(diamonds, aes(x, y)) + xlim(4, 10) + ylim(4, 10) 14 | #' d + geom_bin2d() 15 | #' 16 | #' # You can control the size of the bins by specifying the number of 17 | #' # bins in each direction: 18 | #' d + geom_bin2d(bins = 10) 19 | #' d + geom_bin2d(bins = 30) 20 | #' 21 | #' # Or by specifying the width of the bins 22 | #' d + geom_bin2d(binwidth = c(0.1, 0.1)) 23 | geom_bin2d <- function(mapping = NULL, data = NULL, 24 | stat = "bin2d", position = "identity", 25 | ..., 26 | na.rm = FALSE, 27 | show.legend = NA, 28 | inherit.aes = TRUE) { 29 | 30 | layer( 31 | data = data, 32 | mapping = mapping, 33 | stat = stat, 34 | geom = GeomTile, 35 | position = position, 36 | show.legend = show.legend, 37 | inherit.aes = inherit.aes, 38 | params = list( 39 | na.rm = na.rm, 40 | ... 41 | ) 42 | ) 43 | } 44 | -------------------------------------------------------------------------------- /man/position_jitterdodge.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/position-jitterdodge.R 3 | \name{position_jitterdodge} 4 | \alias{position_jitterdodge} 5 | \title{Adjust position by simultaneously dodging and jittering} 6 | \usage{ 7 | position_jitterdodge(jitter.width = NULL, jitter.height = 0, 8 | dodge.width = 0.75) 9 | } 10 | \arguments{ 11 | \item{jitter.width}{degree of jitter in x direction. Defaults to 40\% of the 12 | resolution of the data.} 13 | 14 | \item{jitter.height}{degree of jitter in y direction. Defaults to 0.} 15 | 16 | \item{dodge.width}{the amount to dodge in the x direction. Defaults to 0.75, 17 | the default \code{position_dodge()} width.} 18 | } 19 | \description{ 20 | This is primarily used for aligning points generated through 21 | \code{geom_point()} with dodged boxplots (e.g., a \code{geom_boxplot()} with 22 | a fill aesthetic supplied). 23 | } 24 | \examples{ 25 | dsub <- diamonds[ sample(nrow(diamonds), 1000), ] 26 | ggplot(dsub, aes(x = cut, y = carat, fill = clarity)) + 27 | geom_boxplot(outlier.size = 0) + 28 | geom_point(pch = 21, position = position_jitterdodge()) 29 | } 30 | \seealso{ 31 | Other position adjustments: \code{\link{position_dodge}}, 32 | \code{\link{position_fill}}, 33 | \code{\link{position_identity}}, 34 | \code{\link{position_jitter}}, 35 | \code{\link{position_nudge}} 36 | } 37 | \concept{position adjustments} 38 | -------------------------------------------------------------------------------- /man/coord_flip.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/coord-flip.r 3 | \name{coord_flip} 4 | \alias{coord_flip} 5 | \title{Flipped cartesian coordinates.} 6 | \usage{ 7 | coord_flip(xlim = NULL, ylim = NULL, expand = TRUE) 8 | } 9 | \arguments{ 10 | \item{xlim}{Limits for the x and y axes.} 11 | 12 | \item{ylim}{Limits for the x and y axes.} 13 | 14 | \item{expand}{If \code{TRUE}, the default, adds a small expansion factor to 15 | the limits to ensure that data and axes don't overlap. If \code{FALSE}, 16 | limits are taken exactly from the data or \code{xlim}/\code{ylim}.} 17 | } 18 | \description{ 19 | Flipped cartesian coordinates so that horizontal becomes vertical, and 20 | vertical, horizontal. This is primarily useful for converting geoms and 21 | statistics which display y conditional on x, to x conditional on y. 22 | } 23 | \examples{ 24 | # Very useful for creating boxplots, and other interval 25 | # geoms in the horizontal instead of vertical position. 26 | 27 | ggplot(diamonds, aes(cut, price)) + 28 | geom_boxplot() + 29 | coord_flip() 30 | 31 | h <- ggplot(diamonds, aes(carat)) + 32 | geom_histogram() 33 | h 34 | h + coord_flip() 35 | h + coord_flip() + scale_x_reverse() 36 | 37 | # You can also use it to flip line and area plots: 38 | df <- data.frame(x = 1:5, y = (1:5) ^ 2) 39 | ggplot(df, aes(x, y)) + 40 | geom_area() 41 | last_plot() + coord_flip() 42 | } 43 | -------------------------------------------------------------------------------- /R/geom-hline.r: -------------------------------------------------------------------------------- 1 | #' @include stat-.r 2 | NULL 3 | 4 | #' @export 5 | #' @rdname geom_abline 6 | geom_hline <- function(mapping = NULL, data = NULL, 7 | ..., 8 | yintercept, 9 | na.rm = FALSE, 10 | show.legend = NA) { 11 | 12 | # Act like an annotation 13 | if (!missing(yintercept)) { 14 | data <- data.frame(yintercept = yintercept) 15 | mapping <- aes(yintercept = yintercept) 16 | show.legend <- FALSE 17 | } 18 | 19 | layer( 20 | data = data, 21 | mapping = mapping, 22 | stat = StatIdentity, 23 | geom = GeomHline, 24 | position = PositionIdentity, 25 | show.legend = show.legend, 26 | inherit.aes = FALSE, 27 | params = list( 28 | na.rm = na.rm, 29 | ... 30 | ) 31 | ) 32 | } 33 | 34 | #' @rdname ggplot2-ggproto 35 | #' @format NULL 36 | #' @usage NULL 37 | #' @export 38 | GeomHline <- ggproto("GeomHline", Geom, 39 | draw_panel = function(data, panel_scales, coord) { 40 | ranges <- coord$range(panel_scales) 41 | 42 | data$x <- ranges$x[1] 43 | data$xend <- ranges$x[2] 44 | data$y <- data$yintercept 45 | data$yend <- data$yintercept 46 | 47 | GeomSegment$draw_panel(unique(data), panel_scales, coord) 48 | }, 49 | 50 | default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA), 51 | required_aes = "yintercept", 52 | 53 | draw_key = draw_key_path 54 | ) 55 | -------------------------------------------------------------------------------- /R/geom-vline.r: -------------------------------------------------------------------------------- 1 | #' @include stat-.r 2 | NULL 3 | 4 | #' @export 5 | #' @rdname geom_abline 6 | geom_vline <- function(mapping = NULL, data = NULL, 7 | ..., 8 | xintercept, 9 | na.rm = FALSE, 10 | show.legend = NA) { 11 | 12 | # Act like an annotation 13 | if (!missing(xintercept)) { 14 | data <- data.frame(xintercept = xintercept) 15 | mapping <- aes(xintercept = xintercept) 16 | show.legend <- FALSE 17 | } 18 | 19 | layer( 20 | data = data, 21 | mapping = mapping, 22 | stat = StatIdentity, 23 | geom = GeomVline, 24 | position = PositionIdentity, 25 | show.legend = show.legend, 26 | inherit.aes = FALSE, 27 | params = list( 28 | na.rm = na.rm, 29 | ... 30 | ) 31 | ) 32 | } 33 | 34 | #' @rdname ggplot2-ggproto 35 | #' @format NULL 36 | #' @usage NULL 37 | #' @export 38 | GeomVline <- ggproto("GeomVline", Geom, 39 | draw_panel = function(data, panel_scales, coord) { 40 | ranges <- coord$range(panel_scales) 41 | 42 | data$x <- data$xintercept 43 | data$xend <- data$xintercept 44 | data$y <- ranges$y[1] 45 | data$yend <- ranges$y[2] 46 | 47 | GeomSegment$draw_panel(unique(data), panel_scales, coord) 48 | }, 49 | 50 | default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA), 51 | required_aes = "xintercept", 52 | 53 | draw_key = draw_key_vline 54 | ) 55 | -------------------------------------------------------------------------------- /R/scale-grey.r: -------------------------------------------------------------------------------- 1 | #' Sequential grey colour scale. 2 | #' 3 | #' Based on \code{\link{gray.colors}} 4 | #' 5 | #' @inheritParams scales::grey_pal 6 | #' @inheritParams scale_colour_hue 7 | #' @seealso Other colour scales: 8 | #' \code{\link{scale_colour_brewer}}, 9 | #' \code{\link{scale_colour_gradient}}, 10 | #' \code{\link{scale_colour_hue}} 11 | #' @rdname scale_grey 12 | #' @export 13 | #' @examples 14 | #' p <- ggplot(mtcars, aes(mpg, wt)) + geom_point(aes(colour = factor(cyl))) 15 | #' p + scale_colour_grey() 16 | #' p + scale_colour_grey(end = 0) 17 | #' 18 | #' # You may want to turn off the pale grey background with this scale 19 | #' p + scale_colour_grey() + theme_bw() 20 | #' 21 | #' # Colour of missing values is controlled with na.value: 22 | #' miss <- factor(sample(c(NA, 1:5), nrow(mtcars), replace = TRUE)) 23 | #' ggplot(mtcars, aes(mpg, wt)) + 24 | #' geom_point(aes(colour = miss)) + 25 | #' scale_colour_grey() 26 | #' ggplot(mtcars, aes(mpg, wt)) + 27 | #' geom_point(aes(colour = miss)) + 28 | #' scale_colour_grey(na.value = "green") 29 | scale_colour_grey <- function(..., start = 0.2, end = 0.8, na.value = "red") { 30 | discrete_scale("colour", "grey", grey_pal(start, end), 31 | na.value = na.value, ...) 32 | } 33 | 34 | #' @rdname scale_grey 35 | #' @export 36 | scale_fill_grey <- function(..., start = 0.2, end = 0.8, na.value = "red") { 37 | discrete_scale("fill", "grey", grey_pal(start, end), 38 | na.value = na.value, ...) 39 | } 40 | -------------------------------------------------------------------------------- /tests/testthat/test-coord-train.r: -------------------------------------------------------------------------------- 1 | context("coord_train") 2 | 3 | test_that("NA's don't appear in breaks", { 4 | 5 | # Returns true if any major/minor breaks have an NA 6 | any_NA_major_minor <- function(trained) { 7 | ns <- names(trained)[grepl("(\\.major)|(\\.minor)$", names(trained))] 8 | 9 | for (n in ns) { 10 | if (!is.null(trained[n]) && any(is.na(trained[n]))) 11 | return(TRUE) 12 | } 13 | 14 | return(FALSE) 15 | } 16 | 17 | scales <- list( 18 | x = scale_x_continuous(limits = c(1, 12)), 19 | y = scale_y_continuous(limits = c(1, 12)) 20 | ) 21 | 22 | # First have to test that scale_breaks_positions will return a vector with NA 23 | # This is a test to make sure the later tests will be useful! 24 | # It's possible that changes to the the way that breaks are calculated will 25 | # make it so that scale_break_positions will no longer give NA for range 1, 12 26 | expect_true(any(is.na((scales$x$break_positions())))) 27 | expect_true(any(is.na((scales$y$break_positions())))) 28 | 29 | # Check the various types of coords to make sure they don't have NA breaks 30 | expect_false(any_NA_major_minor(coord_polar()$train(scales))) 31 | expect_false(any_NA_major_minor(coord_cartesian()$train(scales))) 32 | expect_false(any_NA_major_minor(coord_trans()$train(scales))) 33 | expect_false(any_NA_major_minor(coord_fixed()$train(scales))) 34 | #DEdd expect_false(any_NA_major_minor(coord_map()$train(scales))) 35 | }) 36 | -------------------------------------------------------------------------------- /tests/testthat/test-aes-grouping.r: -------------------------------------------------------------------------------- 1 | context("Aesthetics (grouping)") 2 | 3 | df <- data.frame( 4 | x = 1:4, 5 | a = c("a", "a", "b", "b"), 6 | b = c("a", "b", "a", "b") 7 | ) 8 | 9 | group <- function(x) as.vector(layer_data(x, 1)$group) 10 | groups <- function(x) length(unique(group(x))) 11 | 12 | test_that("one group per combination of discrete vars", { 13 | plot <- ggplot(df, aes(x, x)) + geom_point() 14 | expect_equal(group(plot), rep(NO_GROUP, 4)) 15 | 16 | plot <- ggplot(df, aes(x, a)) + geom_point() 17 | expect_equal(group(plot), c(1, 1, 2, 2)) 18 | plot <- ggplot(df, aes(x, b)) + geom_point() 19 | expect_equal(group(plot), c(1, 2, 1, 2)) 20 | 21 | plot <- ggplot(df, aes(a, b)) + geom_point() 22 | expect_equal(groups(plot), 4) 23 | }) 24 | 25 | test_that("label is not used as a grouping var", { 26 | plot <- ggplot(df, aes(x, x, label = a)) + geom_point() 27 | expect_equal(group(plot), rep(NO_GROUP, 4)) 28 | 29 | plot <- ggplot(df, aes(x, x, colour = a, label = b)) + geom_point() 30 | expect_equal(group(plot), c(1, 1, 2, 2)) 31 | }) 32 | 33 | test_that("group aesthetic overrides defaults", { 34 | plot <- ggplot(df, aes(x, x, group = x)) + geom_point() 35 | expect_equal(groups(plot), 4) 36 | 37 | plot <- ggplot(df, aes(a, b, group = 1)) + geom_point() 38 | expect_equal(groups(plot), 1) 39 | }) 40 | 41 | test_that("group param overrides defaults", { 42 | plot <- ggplot(df, aes(a, b)) + geom_point(group = 1) 43 | expect_equal(groups(plot), 1) 44 | }) 45 | -------------------------------------------------------------------------------- /R/stat-binhex.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname geom_hex 3 | #' @inheritParams stat_bin_2d 4 | stat_bin_hex <- function(mapping = NULL, data = NULL, 5 | geom = "hex", position = "identity", 6 | ..., 7 | bins = 30, 8 | binwidth = NULL, 9 | na.rm = FALSE, 10 | show.legend = NA, 11 | inherit.aes = TRUE) { 12 | layer( 13 | data = data, 14 | mapping = mapping, 15 | stat = StatBinhex, 16 | geom = geom, 17 | position = position, 18 | show.legend = show.legend, 19 | inherit.aes = inherit.aes, 20 | params = list( 21 | bins = bins, 22 | binwidth = binwidth, 23 | na.rm = na.rm, 24 | ... 25 | ) 26 | ) 27 | } 28 | 29 | #' @export 30 | #' @rdname geom_hex 31 | #' @usage NULL 32 | stat_binhex <- stat_bin_hex 33 | 34 | #' @rdname ggplot2-ggproto 35 | #' @format NULL 36 | #' @usage NULL 37 | #' @export 38 | StatBinhex <- ggproto("StatBinhex", Stat, 39 | default_aes = aes(fill = ..value..), 40 | 41 | required_aes = c("x", "y"), 42 | 43 | compute_group = function(data, scales, binwidth = NULL, bins = 30, 44 | na.rm = FALSE) { 45 | try_require("hexbin", "stat_binhex") 46 | 47 | binwidth <- binwidth %||% hex_binwidth(bins, scales) 48 | wt <- data$weight %||% rep(1L, nrow(data)) 49 | hexBinSummarise(data$x, data$y, wt, binwidth, sum) 50 | } 51 | ) 52 | 53 | -------------------------------------------------------------------------------- /R/stat-sum.r: -------------------------------------------------------------------------------- 1 | #' @inheritParams layer 2 | #' @inheritParams geom_point 3 | #' @section Computed variables: 4 | #' \describe{ 5 | #' \item{n}{number of observations at position} 6 | #' \item{prop}{percent of points in that panel at that position} 7 | #' } 8 | #' @export 9 | #' @rdname geom_count 10 | stat_sum <- function(mapping = NULL, data = NULL, 11 | geom = "point", position = "identity", 12 | ..., 13 | na.rm = FALSE, 14 | show.legend = NA, 15 | inherit.aes = TRUE) { 16 | layer( 17 | data = data, 18 | mapping = mapping, 19 | stat = StatSum, 20 | geom = geom, 21 | position = position, 22 | show.legend = show.legend, 23 | inherit.aes = inherit.aes, 24 | params = list( 25 | na.rm = na.rm, 26 | ... 27 | ) 28 | ) 29 | } 30 | 31 | #' @rdname ggplot2-ggproto 32 | #' @format NULL 33 | #' @usage NULL 34 | #' @export 35 | StatSum <- ggproto("StatSum", Stat, 36 | default_aes = aes(size = ..n..), 37 | 38 | required_aes = c("x", "y"), 39 | 40 | compute_panel = function(data, scales) { 41 | if (is.null(data$weight)) data$weight <- 1 42 | 43 | group_by <- setdiff(intersect(names(data), .all_aesthetics), "weight") 44 | 45 | counts <- plyr::count(data, group_by, wt_var = "weight") 46 | counts <- plyr::rename(counts, c(freq = "n"), warn_missing = FALSE) 47 | counts$prop <- stats::ave(counts$n, counts$group, FUN = prop.table) 48 | counts 49 | } 50 | ) 51 | -------------------------------------------------------------------------------- /man/fortify.sp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fortify-spatial.r 3 | \name{fortify.sp} 4 | \alias{fortify.sp} 5 | \alias{fortify.SpatialPolygonsDataFrame} 6 | \alias{fortify.SpatialPolygons} 7 | \alias{fortify.Polygons} 8 | \alias{fortify.Polygon} 9 | \alias{fortify.SpatialLinesDataFrame} 10 | \alias{fortify.Lines} 11 | \alias{fortify.Line} 12 | \title{Fortify method for classes from the sp package.} 13 | \usage{ 14 | \method{fortify}{SpatialPolygonsDataFrame}(model, data, region = NULL, 15 | ...) 16 | 17 | \method{fortify}{SpatialPolygons}(model, data, ...) 18 | 19 | \method{fortify}{Polygons}(model, data, ...) 20 | 21 | \method{fortify}{Polygon}(model, data, ...) 22 | 23 | \method{fortify}{SpatialLinesDataFrame}(model, data, ...) 24 | 25 | \method{fortify}{Lines}(model, data, ...) 26 | 27 | \method{fortify}{Line}(model, data, ...) 28 | } 29 | \arguments{ 30 | \item{model}{\code{SpatialPolygonsDataFrame} to convert into a dataframe.} 31 | 32 | \item{data}{not used by this method} 33 | 34 | \item{region}{name of variable used to split up regions} 35 | 36 | \item{...}{not used by this method} 37 | } 38 | \description{ 39 | To figure out the correct variable name for region, inspect 40 | \code{as.data.frame(model)}. 41 | } 42 | \examples{ 43 | if (require("maptools")) { 44 | sids <- system.file("shapes/sids.shp", package="maptools") 45 | nc1 <- readShapePoly(sids, 46 | proj4string = CRS("+proj=longlat +datum=NAD27")) 47 | nc1_df <- fortify(nc1) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /R/grouping.r: -------------------------------------------------------------------------------- 1 | # This needs to be less than 1, to distinguish it from "regular" return values 2 | # of plyr::id() used by add_group() 3 | NO_GROUP <- -1L 4 | 5 | # Ensure that the data frame contains a grouping variable. 6 | # 7 | # If the \code{group} variable is not present, then a new group 8 | # variable is generated from the interaction of all discrete (factor or 9 | # character) vectors, excluding \code{label}. The special value \code{NO_GROUP} 10 | # is used for all observations if no discrete variables exist. 11 | add_group <- function(data) { 12 | if (empty(data)) return(data) 13 | 14 | if (is.null(data$group)) { 15 | disc <- vapply(data, is.discrete, logical(1)) 16 | disc[names(disc) %in% c("label", "PANEL")] <- FALSE 17 | 18 | if (any(disc)) { 19 | data$group <- plyr::id(data[disc], drop = TRUE) 20 | } else { 21 | data$group <- NO_GROUP 22 | } 23 | } else { 24 | data$group <- plyr::id(data["group"], drop = TRUE) 25 | } 26 | 27 | data 28 | } 29 | 30 | # Is a grouping available? 31 | # (Will return TRUE if an explicit group or a discrete variable with only one 32 | # level existed when add_group() was called.) 33 | has_groups <- function(data) { 34 | # If no group aesthetic is specified, all values of the group column equal to 35 | # NO_GROUP. On the other hand, if a group aesthetic is specified, all values 36 | # are different from NO_GROUP (since they are a result of plyr::id()). NA is 37 | # returned for 0-row data frames. 38 | data$group[1L] != NO_GROUP 39 | } 40 | -------------------------------------------------------------------------------- /tests/testthat/test-aes-setting.r: -------------------------------------------------------------------------------- 1 | context("Aes - setting values") 2 | 3 | test_that("Aesthetic parameters must match length of data", { 4 | df <- data.frame(x = 1:5, y = 1:5) 5 | p <- ggplot(df, aes(x, y)) 6 | 7 | set_colours <- function(colours) { 8 | layer_data(p + geom_point(colour = colours)) 9 | } 10 | 11 | set_colours("red") 12 | expect_error(set_colours(rep("red", 2)), "must be either length 1") 13 | expect_error(set_colours(rep("red", 3)), "must be either length 1") 14 | expect_error(set_colours(rep("red", 4)), "must be either length 1") 15 | set_colours(rep("red", 5)) 16 | 17 | }) 18 | 19 | test_that("alpha affects only fill colour of solid geoms", { 20 | df <- data.frame(x = 1:2, y = 1) 21 | 22 | poly <- ggplot(df, aes(x = x, y)) + 23 | geom_polygon(fill = "red", colour = "red", alpha = 0.5) 24 | rect <- ggplot(df, aes(xmin = x, xmax = x + 1, ymin = 1, ymax = y + 1)) + 25 | geom_rect(fill = "red", colour = "red", alpha = 0.5) 26 | ribb <- ggplot(df, aes(x = x, ymin = 1, ymax = y + 1)) + 27 | geom_ribbon(fill = "red", colour = "red", alpha = 0.5) 28 | 29 | expect_equal(layer_grob(poly)[[1]]$gp$col[[1]], "red") 30 | expect_equal(layer_grob(rect)[[1]]$gp$col[[1]], "red") 31 | expect_equal(layer_grob(ribb)[[1]]$children[[1]]$gp$col[[1]], "red") 32 | 33 | expect_equal(layer_grob(poly)[[1]]$gp$fill[[1]], "#FF000080") 34 | expect_equal(layer_grob(rect)[[1]]$gp$fill[[1]], "#FF000080") 35 | expect_equal(layer_grob(ribb)[[1]]$children[[1]]$gp$fill[[1]], "#FF000080") 36 | }) 37 | -------------------------------------------------------------------------------- /man/fortify-multcomp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fortify-multcomp.r 3 | \name{fortify-multcomp} 4 | \alias{fortify-multcomp} 5 | \alias{fortify.glht} 6 | \alias{fortify.confint.glht} 7 | \alias{fortify.summary.glht} 8 | \alias{fortify.cld} 9 | \title{Fortify methods for objects produced by \pkg{multcomp}} 10 | \usage{ 11 | \method{fortify}{glht}(model, data, ...) 12 | 13 | \method{fortify}{confint.glht}(model, data, ...) 14 | 15 | \method{fortify}{summary.glht}(model, data, ...) 16 | 17 | \method{fortify}{cld}(model, data, ...) 18 | } 19 | \arguments{ 20 | \item{model}{an object of class \code{glht}, \code{confint.glht}, 21 | \code{summary.glht} or \code{\link[multcomp]{cld}}} 22 | 23 | \item{data, ...}{other arguments to the generic ignored in this method.} 24 | } 25 | \description{ 26 | Fortify methods for objects produced by \pkg{multcomp} 27 | } 28 | \examples{ 29 | if (require("multcomp")) { 30 | amod <- aov(breaks ~ wool + tension, data = warpbreaks) 31 | wht <- glht(amod, linfct = mcp(tension = "Tukey")) 32 | 33 | fortify(wht) 34 | ggplot(wht, aes(lhs, estimate)) + geom_point() 35 | 36 | CI <- confint(wht) 37 | fortify(CI) 38 | ggplot(CI, aes(lhs, estimate, ymin = lwr, ymax = upr)) + 39 | geom_pointrange() 40 | 41 | fortify(summary(wht)) 42 | ggplot(mapping = aes(lhs, estimate)) + 43 | geom_linerange(aes(ymin = lwr, ymax = upr), data = CI) + 44 | geom_point(aes(size = p), data = summary(wht)) + 45 | scale_size(trans = "reverse") 46 | 47 | cld <- cld(wht) 48 | fortify(cld) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /R/geom-pointrange.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname geom_linerange 3 | geom_pointrange <- function(mapping = NULL, data = NULL, 4 | stat = "identity", position = "identity", 5 | ..., 6 | fatten = 4, 7 | na.rm = FALSE, 8 | show.legend = NA, 9 | inherit.aes = TRUE) { 10 | layer( 11 | data = data, 12 | mapping = mapping, 13 | stat = stat, 14 | geom = GeomPointrange, 15 | position = position, 16 | show.legend = show.legend, 17 | inherit.aes = inherit.aes, 18 | params = list( 19 | fatten = fatten, 20 | na.rm = na.rm, 21 | ... 22 | ) 23 | ) 24 | } 25 | 26 | #' @rdname ggplot2-ggproto 27 | #' @format NULL 28 | #' @usage NULL 29 | #' @export 30 | GeomPointrange <- ggproto("GeomPointrange", Geom, 31 | default_aes = aes(colour = "black", size = 0.5, linetype = 1, shape = 19, 32 | fill = NA, alpha = NA, stroke = 1), 33 | 34 | draw_key = draw_key_pointrange, 35 | 36 | required_aes = c("x", "y", "ymin", "ymax"), 37 | 38 | draw_panel = function(data, panel_scales, coord, fatten = 4) { 39 | if (is.null(data$y)) 40 | return(GeomLinerange$draw_panel(data, panel_scales, coord)) 41 | 42 | ggname("geom_pointrange", 43 | gTree(children = gList( 44 | GeomLinerange$draw_panel(data, panel_scales, coord), 45 | GeomPoint$draw_panel(transform(data, size = size * fatten), panel_scales, coord) 46 | )) 47 | ) 48 | } 49 | ) 50 | -------------------------------------------------------------------------------- /R/aes-calculated.r: -------------------------------------------------------------------------------- 1 | # Regex to determine if an identifier refers to a calculated aesthetic 2 | match_calculated_aes <- "^\\.\\.([a-zA-Z._]+)\\.\\.$" 3 | 4 | # Determine if aesthetic is calculated 5 | is_calculated_aes <- function(aesthetics) { 6 | vars <- lapply(aesthetics, find_vars) 7 | 8 | vapply(vars, function(x) any(grepl(match_calculated_aes, x)), logical(1)) 9 | } 10 | 11 | find_vars <- function(expr) { 12 | if (is.name(expr)) { 13 | as.character(expr) 14 | } else if (is.atomic(expr)) { 15 | character() 16 | } else if (is.call(expr)) { 17 | unlist(lapply(expr[-1], find_vars)) 18 | } else if (is.pairlist(expr)) { 19 | # In the unlikely event of an anonymous function 20 | unlist(lapply(expr, find_vars)) 21 | } else { 22 | stop("Unknown input:", class(expr)[1]) 23 | } 24 | } 25 | 26 | # Strip dots from expressions 27 | strip_dots <- function(expr) { 28 | if (is.atomic(expr)) { 29 | expr 30 | } else if (is.name(expr)) { 31 | expr_ch <- as.character(expr) 32 | if (nchar(expr_ch) > 0) { 33 | as.name(gsub(match_calculated_aes, "\\1", expr_ch)) 34 | } else { 35 | expr 36 | } 37 | } else if (is.call(expr)) { 38 | expr[-1] <- lapply(expr[-1], strip_dots) 39 | expr 40 | } else if (is.pairlist(expr)) { 41 | # In the unlikely event of an anonymous function 42 | as.pairlist(lapply(expr, strip_dots)) 43 | } else if (is.list(expr)) { 44 | # For list of aesthetics 45 | lapply(expr, strip_dots) 46 | } else { 47 | stop("Unknown input:", class(expr)[1]) 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /tests/testthat/test-stat-sum.R: -------------------------------------------------------------------------------- 1 | context("stat_sum") 2 | 3 | test_that("handles grouping correctly", { 4 | d <- diamonds[1:1000, ] 5 | all_ones <- function(x) all.equal(mean(x), 1) 6 | 7 | base <- ggplot(d, aes(cut, clarity)) 8 | 9 | ret <- layer_data(base + stat_sum()) 10 | expect_equal(nrow(ret), 38) 11 | expect_equal(sum(ret$n), nrow(d)) 12 | expect_true(all_ones(ret$prop)) 13 | 14 | ret <- layer_data(base + stat_sum(aes(group = 1))) 15 | expect_equal(nrow(ret), 38) 16 | expect_equal(sum(ret$n), nrow(d)) 17 | expect_equal(sum(ret$prop), 1) 18 | 19 | ret <- layer_data(base + stat_sum(aes(group = cut))) 20 | expect_equal(nrow(ret), 38) 21 | expect_equal(sum(ret$n), nrow(d)) 22 | expect_true(all_ones(tapply(ret$prop, ret$x, FUN = sum))) 23 | 24 | ret <- layer_data(base + stat_sum(aes(group = cut, colour = cut))) 25 | expect_equal(nrow(ret), 38) 26 | expect_equal(sum(ret$n), nrow(d)) 27 | expect_true(all_ones(tapply(ret$prop, ret$x, FUN = sum))) 28 | 29 | ret <- layer_data(base + stat_sum(aes(group = clarity))) 30 | expect_equal(nrow(ret), 38) 31 | expect_equal(sum(ret$n), nrow(d)) 32 | expect_true(all_ones(tapply(ret$prop, ret$y, FUN = sum))) 33 | 34 | ret <- layer_data(base + stat_sum(aes(group = clarity, colour = cut))) 35 | expect_equal(nrow(ret), 38) 36 | expect_equal(sum(ret$n), nrow(d)) 37 | expect_true(all_ones(tapply(ret$prop, ret$y, FUN = sum))) 38 | 39 | ret <- layer_data(base + stat_sum(aes(group = 1, weight = price))) 40 | expect_equal(nrow(ret), 38) 41 | expect_equal(sum(ret$n), sum(d$price)) 42 | expect_equal(sum(ret$prop), 1) 43 | }) 44 | -------------------------------------------------------------------------------- /man/scale_grey.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/scale-grey.r, R/zxx.r 3 | \name{scale_colour_grey} 4 | \alias{scale_colour_grey} 5 | \alias{scale_fill_grey} 6 | \alias{scale_color_grey} 7 | \title{Sequential grey colour scale.} 8 | \usage{ 9 | scale_colour_grey(..., start = 0.2, end = 0.8, na.value = "red") 10 | 11 | scale_fill_grey(..., start = 0.2, end = 0.8, na.value = "red") 12 | } 13 | \arguments{ 14 | \item{...}{Other arguments passed on to \code{\link{discrete_scale}} 15 | to control name, limits, breaks, labels and so forth.} 16 | 17 | \item{start}{grey value at low end of palette} 18 | 19 | \item{end}{grey value at high end of palette} 20 | 21 | \item{na.value}{Colour to use for missing values} 22 | } 23 | \description{ 24 | Based on \code{\link{gray.colors}} 25 | } 26 | \examples{ 27 | p <- ggplot(mtcars, aes(mpg, wt)) + geom_point(aes(colour = factor(cyl))) 28 | p + scale_colour_grey() 29 | p + scale_colour_grey(end = 0) 30 | 31 | # You may want to turn off the pale grey background with this scale 32 | p + scale_colour_grey() + theme_bw() 33 | 34 | # Colour of missing values is controlled with na.value: 35 | miss <- factor(sample(c(NA, 1:5), nrow(mtcars), replace = TRUE)) 36 | ggplot(mtcars, aes(mpg, wt)) + 37 | geom_point(aes(colour = miss)) + 38 | scale_colour_grey() 39 | ggplot(mtcars, aes(mpg, wt)) + 40 | geom_point(aes(colour = miss)) + 41 | scale_colour_grey(na.value = "green") 42 | } 43 | \seealso{ 44 | Other colour scales: 45 | \code{\link{scale_colour_brewer}}, 46 | \code{\link{scale_colour_gradient}}, 47 | \code{\link{scale_colour_hue}} 48 | } 49 | -------------------------------------------------------------------------------- /R/facet-viewports.r: -------------------------------------------------------------------------------- 1 | # Assign viewports to a matrix of grobs 2 | # 3 | # Uses the structure (and names) of the matrix of grobs, to automatically 4 | # assign each grob to the appropriate viewport 5 | assign_viewports <- function(grobs) { 6 | make_grid <- function(type) { 7 | data.frame( 8 | type = type, 9 | x = c(row(grobs[[type]])), 10 | y = c(col(grobs[[type]])) 11 | ) 12 | } 13 | 14 | assign_vp <- function(type, x, y) { 15 | ggname(type, editGrob(grobs[[type]][[x, y]], vp = vp_path(x, y, type))) 16 | } 17 | 18 | grid <- plyr::ldply(names(grobs), make_grid) 19 | plyr::mlply(grid, assign_vp) 20 | } 21 | 22 | # Setup matrix of viewports for a layout with given parameters 23 | setup_viewports <- function(type, data, offset = c(0,0), clip = "on") { 24 | rows <- nrow(data) 25 | cols <- ncol(data) 26 | 27 | vp <- function(x,y) { 28 | # cat(vp_name(x, y, type), ": ", x + offset[1], ", ", y + offset[2], "\n", sep="") 29 | viewport( 30 | name = vp_name(x, y, type), 31 | layout.pos.row = x + offset[1], 32 | layout.pos.col = y + offset[2], 33 | clip = clip 34 | ) 35 | } 36 | pos <- expand.grid(x = seq_len(rows), y = seq_len(cols)) 37 | do.call("vpList", plyr::mlply(pos, vp)) 38 | } 39 | 40 | # Calculate viewport path. 41 | # Helps ensure a common naming scheme throughout ggplot. 42 | vp_path <- function(row, col, type) { 43 | vpPath("panels", vp_name(row, col, type)) 44 | } 45 | 46 | # Compute viewport name. 47 | # Helps ensure a common naming scheme throughout ggplot. 48 | vp_name <- function(row, col, type) { 49 | paste(type, row, col, sep = "_") 50 | } 51 | -------------------------------------------------------------------------------- /man/coord_fixed.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/coord-fixed.r 3 | \name{coord_fixed} 4 | \alias{coord_fixed} 5 | \alias{coord_equal} 6 | \title{Cartesian coordinates with fixed relationship between x and y scales.} 7 | \usage{ 8 | coord_fixed(ratio = 1, xlim = NULL, ylim = NULL, expand = TRUE) 9 | } 10 | \arguments{ 11 | \item{ratio}{aspect ratio, expressed as \code{y / x}} 12 | 13 | \item{xlim}{Limits for the x and y axes.} 14 | 15 | \item{ylim}{Limits for the x and y axes.} 16 | 17 | \item{expand}{If \code{TRUE}, the default, adds a small expansion factor to 18 | the limits to ensure that data and axes don't overlap. If \code{FALSE}, 19 | limits are taken exactly from the data or \code{xlim}/\code{ylim}.} 20 | } 21 | \description{ 22 | A fixed scale coordinate system forces a specified ratio between the 23 | physical representation of data units on the axes. The ratio represents the 24 | number of units on the y-axis equivalent to one unit on the x-axis. The 25 | default, \code{ratio = 1}, ensures that one unit on the x-axis is the same 26 | length as one unit on the y-axis. Ratios higher than one make units on the 27 | y axis longer than units on the x-axis, and vice versa. This is similar to 28 | \code{\link[MASS]{eqscplot}}, but it works for all types of graphics. 29 | } 30 | \examples{ 31 | # ensures that the ranges of axes are equal to the specified ratio by 32 | # adjusting the plot aspect ratio 33 | 34 | p <- ggplot(mtcars, aes(mpg, wt)) + geom_point() 35 | p + coord_fixed(ratio = 1) 36 | p + coord_fixed(ratio = 5) 37 | p + coord_fixed(ratio = 1/5) 38 | 39 | # Resize the plot to see that the specified aspect ratio is maintained 40 | } 41 | -------------------------------------------------------------------------------- /R/aes-position.r: -------------------------------------------------------------------------------- 1 | #' Position related aesthetics: x, y, xmin, xmax, ymin, ymax, xend, yend 2 | #' 3 | #' This page demonstrates the usage of a sub-group 4 | #' of aesthetics; x, y, xmin, xmax, ymin, ymax, xend, and yend. 5 | #' 6 | #' @name aes_position 7 | #' @aliases x y xmin xmax ymin ymax xend yend 8 | #' @examples 9 | #' 10 | #' # Generate data: means and standard errors of means for prices 11 | #' # for each type of cut 12 | #' dmod <- lm(price ~ cut, data = diamonds) 13 | #' cuts <- data.frame(cut = unique(diamonds$cut), predict(dmod, data.frame(cut = 14 | #' unique(diamonds$cut)), se = TRUE)[c("fit", "se.fit")]) 15 | #' se <- ggplot(cuts, aes(x = cut, y = fit, ymin = fit - se.fit, 16 | #' ymax = fit + se.fit, colour = cut)) 17 | #' se + geom_pointrange() 18 | #' 19 | #' # Using annotate 20 | #' p <- ggplot(mtcars, aes(wt, mpg)) + geom_point() 21 | #' p + annotate("rect", xmin = 2, xmax = 3.5, ymin = 2, ymax = 25, 22 | #' fill = "dark grey", alpha = .5) 23 | #' 24 | #' # Geom_segment examples 25 | #' p + geom_segment(aes(x = 2, y = 15, xend = 2, yend = 25), 26 | #' arrow = arrow(length = unit(0.5, "cm"))) 27 | #' p + geom_segment(aes(x = 2, y = 15, xend = 3, yend = 15), 28 | #' arrow = arrow(length = unit(0.5, "cm"))) 29 | #' p + geom_segment(aes(x = 5, y = 30, xend = 3.5, yend = 25), 30 | #' arrow = arrow(length = unit(0.5, "cm"))) 31 | #' 32 | #' # You can also use geom_segment to recreate plot(type = "h") : 33 | #' counts <- as.data.frame(table(x = rpois(100, 5))) 34 | #' counts$x <- as.numeric(as.character(counts$x)) 35 | #' with(counts, plot(x, Freq, type = "h", lwd = 10)) 36 | #' 37 | #' ggplot(counts, aes(x, Freq)) + 38 | #' geom_segment(aes(yend = 0, xend = x), size = 10) 39 | NULL 40 | -------------------------------------------------------------------------------- /man/map_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fortify-map.r 3 | \name{map_data} 4 | \alias{map_data} 5 | \title{Create a data frame of map data.} 6 | \usage{ 7 | map_data(map, region = ".", exact = FALSE, ...) 8 | } 9 | \arguments{ 10 | \item{map}{name of map provided by the \pkg{maps} package. These 11 | include \code{\link[maps]{county}}, \code{\link[maps]{france}}, 12 | \code{\link[maps]{italy}}, \code{\link[maps]{nz}}, 13 | \code{\link[maps]{state}}, \code{\link[maps]{usa}}, 14 | \code{\link[maps]{world}}, \code{\link[maps]{world2}}.} 15 | 16 | \item{region}{name of subregions to include. Defaults to \code{.} which 17 | includes all subregion. See documentation for \code{\link[maps]{map}} 18 | for more details.} 19 | 20 | \item{exact}{should the \code{region} be treated as a regular expression 21 | (\code{FALSE}) or as a fixed string (\code{TRUE}).} 22 | 23 | \item{...}{all other arguments passed on to \code{\link[maps]{map}}} 24 | } 25 | \description{ 26 | Create a data frame of map data. 27 | } 28 | \examples{ 29 | if (require("maps") && require("mapproj")) { 30 | states <- map_data("state") 31 | arrests <- USArrests 32 | names(arrests) <- tolower(names(arrests)) 33 | arrests$region <- tolower(rownames(USArrests)) 34 | 35 | choro <- merge(states, arrests, sort = FALSE, by = "region") 36 | choro <- choro[order(choro$order), ] 37 | ggplot(choro, aes(long, lat)) + 38 | geom_polygon(aes(group = group, fill = assault)) + 39 | coord_map("albers", at0 = 45.5, lat1 = 29.5) 40 | 41 | ggplot(choro, aes(long, lat)) + 42 | geom_polygon(aes(group = group, fill = assault / murder)) + 43 | coord_map("albers", at0 = 45.5, lat1 = 29.5) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /man/borders.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fortify-map.r 3 | \name{borders} 4 | \alias{borders} 5 | \title{Create a layer of map borders.} 6 | \usage{ 7 | borders(database = "world", regions = ".", fill = NA, 8 | colour = "grey50", xlim = NULL, ylim = NULL, ...) 9 | } 10 | \arguments{ 11 | \item{database}{map data, see \code{\link[maps]{map}} for details} 12 | 13 | \item{regions}{map region} 14 | 15 | \item{fill}{fill colour} 16 | 17 | \item{colour}{border colour} 18 | 19 | \item{xlim, ylim}{latitudinal and logitudinal range for extracting map 20 | polygons, see \code{\link[maps]{map}} for details.} 21 | 22 | \item{...}{other arguments passed onto \code{\link{geom_polygon}}} 23 | } 24 | \description{ 25 | Create a layer of map borders. 26 | } 27 | \examples{ 28 | if (requireNamespace("maps",quietly=TRUE) && require("mapproj",quietly=TRUE)) { 29 | 30 | ia <- map_data("county", "iowa") 31 | mid_range <- function(x) mean(range(x)) 32 | seats <- plyr::ddply(ia, "subregion", plyr::colwise(mid_range, c("lat", "long"))) 33 | ggplot(ia, aes(long, lat)) + 34 | geom_polygon(aes(group = group), fill = NA, colour = "grey60") + 35 | geom_text(aes(label = subregion), data = seats, size = 2, angle = 45) 36 | 37 | data(us.cities) 38 | capitals <- subset(us.cities, capital == 2) 39 | ggplot(capitals, aes(long, lat)) + 40 | borders("state") + 41 | geom_point(aes(size = pop)) + 42 | scale_size_area() + 43 | coord_quickmap() 44 | 45 | # Same map, with some world context 46 | ggplot(capitals, aes(long, lat)) + 47 | borders("world", xlim = c(-130, -60), ylim = c(20, 50)) + 48 | geom_point(aes(size = pop)) + 49 | scale_size_area() + 50 | coord_quickmap() 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /R/stat-summary-hex.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname stat_summary_2d 3 | #' @inheritParams stat_bin_hex 4 | stat_summary_hex <- function(mapping = NULL, data = NULL, 5 | geom = "hex", position = "identity", 6 | ..., 7 | bins = 30, 8 | binwidth = NULL, 9 | drop = TRUE, 10 | fun = "mean", 11 | fun.args = list(), 12 | na.rm = FALSE, 13 | show.legend = NA, 14 | inherit.aes = TRUE) { 15 | layer( 16 | data = data, 17 | mapping = mapping, 18 | stat = StatSummaryHex, 19 | geom = geom, 20 | position = position, 21 | show.legend = show.legend, 22 | inherit.aes = inherit.aes, 23 | params = list( 24 | bins = bins, 25 | binwidth = binwidth, 26 | drop = drop, 27 | fun = fun, 28 | fun.args = fun.args, 29 | na.rm = na.rm, 30 | ... 31 | ) 32 | ) 33 | } 34 | 35 | #' @rdname ggplot2-ggproto 36 | #' @format NULL 37 | #' @usage NULL 38 | #' @export 39 | StatSummaryHex <- ggproto("StatSummaryHex", Stat, 40 | default_aes = aes(fill = ..value..), 41 | 42 | required_aes = c("x", "y", "z"), 43 | 44 | compute_group = function(data, scales, binwidth = NULL, bins = 30, drop = TRUE, 45 | fun = "mean", fun.args = list()) { 46 | try_require("hexbin", "stat_summary_hex") 47 | 48 | binwidth <- binwidth %||% hex_binwidth(bins, scales) 49 | hexBinSummarise(data$x, data$y, data$z, binwidth, 50 | fun = fun, fun.args = fun.args, drop = drop) 51 | } 52 | ) 53 | -------------------------------------------------------------------------------- /man/aes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/aes.r 3 | \name{aes} 4 | \alias{aes} 5 | \title{Define aesthetic mappings.} 6 | \usage{ 7 | aes(x, y, ...) 8 | } 9 | \arguments{ 10 | \item{x, y, ...}{List of name value pairs giving aesthetics to map to 11 | variables. The names for x and y aesthetics can be omitted (because 12 | they are so common); all other aesthetics must be named.} 13 | } 14 | \description{ 15 | Generate aesthetic mappings that describe how variables in the data are 16 | mapped to visual properties (aesthetics) of geoms. This function also 17 | standardise aesthetic names by performs partial name matching, converting 18 | color to colour, and old style R names to ggplot names (eg. pch to shape, 19 | cex to size) 20 | } 21 | \examples{ 22 | aes(x = mpg, y = wt) 23 | aes(mpg, wt) 24 | 25 | # You can also map aesthetics to functions of variables 26 | aes(x = mpg ^ 2, y = wt / cyl) 27 | 28 | # Aesthetic names are automatically standardised 29 | aes(col = x) 30 | aes(fg = x) 31 | aes(color = x) 32 | aes(colour = x) 33 | 34 | # aes is almost always used with ggplot() or a layer 35 | ggplot(mpg, aes(displ, hwy)) + geom_point() 36 | ggplot(mpg) + geom_point(aes(displ, hwy)) 37 | 38 | # Aesthetics supplied to ggplot() are used as defaults for every layer 39 | # you can override them, or supply different aesthetics for each layer 40 | } 41 | \seealso{ 42 | See \code{\link{aes_q}}/\code{\link{aes_string}} for standard 43 | evaluation versions of \code{aes}. 44 | 45 | See 46 | \code{\link{aes_colour_fill_alpha}}, \code{\link{aes_group_order}}, 47 | \code{\link{aes_linetype_size_shape}} and \code{\link{aes_position}} 48 | for more specific examples with different aesthetics. 49 | } 50 | -------------------------------------------------------------------------------- /R/coord-fixed.r: -------------------------------------------------------------------------------- 1 | #' Cartesian coordinates with fixed relationship between x and y scales. 2 | #' 3 | #' A fixed scale coordinate system forces a specified ratio between the 4 | #' physical representation of data units on the axes. The ratio represents the 5 | #' number of units on the y-axis equivalent to one unit on the x-axis. The 6 | #' default, \code{ratio = 1}, ensures that one unit on the x-axis is the same 7 | #' length as one unit on the y-axis. Ratios higher than one make units on the 8 | #' y axis longer than units on the x-axis, and vice versa. This is similar to 9 | #' \code{\link[MASS]{eqscplot}}, but it works for all types of graphics. 10 | #' 11 | #' @export 12 | #' @inheritParams coord_cartesian 13 | #' @param ratio aspect ratio, expressed as \code{y / x} 14 | #' @examples 15 | #' # ensures that the ranges of axes are equal to the specified ratio by 16 | #' # adjusting the plot aspect ratio 17 | #' 18 | #' p <- ggplot(mtcars, aes(mpg, wt)) + geom_point() 19 | #' p + coord_fixed(ratio = 1) 20 | #' p + coord_fixed(ratio = 5) 21 | #' p + coord_fixed(ratio = 1/5) 22 | #' 23 | #' # Resize the plot to see that the specified aspect ratio is maintained 24 | coord_fixed <- function(ratio = 1, xlim = NULL, ylim = NULL, expand = TRUE) { 25 | ggproto(NULL, CoordFixed, 26 | limits = list(x = xlim, y = ylim), 27 | ratio = ratio, 28 | expand = expand 29 | ) 30 | } 31 | 32 | #' @export 33 | #' @rdname coord_fixed 34 | #' @usage NULL 35 | coord_equal <- coord_fixed 36 | 37 | 38 | #' @rdname ggplot2-ggproto 39 | #' @format NULL 40 | #' @usage NULL 41 | #' @export 42 | CoordFixed <- ggproto("CoordFixed", CoordCartesian, 43 | 44 | aspect = function(self, ranges) { 45 | diff(ranges$y.range) / diff(ranges$x.range) * self$ratio 46 | } 47 | ) 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## lwplot 2 | 3 | This is an *experimental* fork of [ggplot2](README-ggplot2.md) which aims to explore if we 4 | can make it part of the [tinyverse](http://www.tinyverse.org). 5 | 6 | ### What's with the name? 7 | 8 | LW can stand for _lighter-weight_ but also Leland Wilkinson of _Grammar of Graphics_ fame. 9 | 10 | ### Which Version ? 11 | 12 | We started off ggplot2 2.1.0 which still had somewhat moderate dependencies: 13 | 14 | ``` 15 | Depends: R (>= 3.1) 16 | Imports: digest, grid, gtable (>= 0.1.1), MASS, plyr (>= 1.7.1), 17 | reshape2, scales (>= 0.3.0), stats 18 | ``` 19 | 20 | Version 2.2.0 introduced the `tibble` and `lazyeval`: 21 | 22 | ``` 23 | Depends: R (>= 3.1) 24 | Imports: digest, grid, gtable (>= 0.1.1), MASS, plyr (>= 1.7.1), 25 | reshape2, scales (>= 0.4.1), stats, tibble, lazyeval 26 | ``` 27 | 28 | Version 3.0.0 adds `rlang`, `mgcv`, `viridisLite`, `withr`: 29 | 30 | ``` 31 | Depends: R (>= 3.1) 32 | Imports: digest, grid, gtable (>= 0.1.1), lazyeval, MASS, mgcv, plyr 33 | (>= 1.7.1), reshape2, rlang, scales (>= 0.5.0), stats, tibble, 34 | viridisLite, withr (>= 2.0.0) 35 | ``` 36 | 37 | Maybe we can stay at what 2.1.0 and even remove `plyr` and `reshape2` 38 | by introducing `data.table`. 39 | 40 | ### Status ? 41 | 42 | Not bad. After some minimal changes, it passes `R CMD check` as `lwplot`. 43 | 44 | And following some initial work, `reshape2` is gone. `plyr` is still in, and 45 | removing it will be quite some work. 46 | 47 | ### Who ? 48 | 49 | Dirk Eddelbuettel for this. 50 | 51 | Hadley Wickham and many collaborators for the underlying ggplot2 2.1.0. 52 | 53 | ### License 54 | 55 | GPL-2 as before 56 | 57 | ### Anything else ? 58 | 59 | Please don't distribute this yet. 60 | -------------------------------------------------------------------------------- /man/ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggproto.r 3 | \name{ggproto} 4 | \alias{ggproto} 5 | \alias{ggproto_parent} 6 | \title{Create a new ggproto object} 7 | \usage{ 8 | ggproto(`_class` = NULL, `_inherit` = NULL, ...) 9 | 10 | ggproto_parent(parent, self) 11 | } 12 | \arguments{ 13 | \item{_class}{Class name to assign to the object. This is stored as the class 14 | attribute of the object. If \code{NULL} (the default), no class name will 15 | be added to the object.} 16 | 17 | \item{_inherit}{ggproto object to inherit from. If \code{NULL}, don't inherit 18 | from any object.} 19 | 20 | \item{...}{A list of members in the ggproto object.} 21 | 22 | \item{parent, self}{Access parent class \code{parent} of object \code{self}.} 23 | } 24 | \description{ 25 | ggproto is inspired by the proto package, but it has some important 26 | differences. Notably, it cleanly supports cross-package inheritance, and has 27 | faster performance. 28 | } 29 | \section{Calling ggproto methods}{ 30 | 31 | 32 | ggproto methods can take an optional \code{self} argument: if it is present, 33 | it is a regular method; if it's absent, it's a "static" method (i.e. it 34 | doesn't use any fields). 35 | 36 | Imagine you have a ggproto object \code{Adder}, which has a 37 | method \code{addx = function(self, n) n + self$x}. Then, to call this 38 | function, you would use \code{Adder$addx(10)} -- the \code{self} is passed 39 | in automatically by the wrapper function. \code{self} be located anywhere 40 | in the function signature, although customarily it comes first. 41 | } 42 | 43 | \section{Calling methods in a parent}{ 44 | 45 | 46 | To explicitly call a methods in a parent, use 47 | \code{ggproto_parent(Parent, self)}. 48 | } 49 | 50 | -------------------------------------------------------------------------------- /tests/testthat/test-facet-.r: -------------------------------------------------------------------------------- 1 | context("Facetting") 2 | 3 | df <- data.frame(x = 1:3, y = 3:1, z = letters[1:3]) 4 | 5 | test_that("facets split up the data", { 6 | l1 <- ggplot(df, aes(x, y)) + geom_point() + facet_wrap(~z) 7 | l2 <- ggplot(df, aes(x, y)) + geom_point() + facet_grid(. ~ z) 8 | l3 <- ggplot(df, aes(x, y)) + geom_point() + facet_grid(z ~ .) 9 | 10 | d1 <- layer_data(l1) 11 | d2 <- layer_data(l2) 12 | d3 <- layer_data(l3) 13 | 14 | expect_equal(d1, d2) 15 | expect_equal(d1, d3) 16 | expect_equal(d1$PANEL, factor(1:3)) 17 | }) 18 | 19 | test_that("facets with free scales scale independently", { 20 | l1 <- ggplot(df, aes(x, y)) + geom_point() + 21 | facet_wrap(~z, scales = "free") 22 | d1 <- cdata(l1)[[1]] 23 | expect_true(sd(d1$x) < 1e-10) 24 | expect_true(sd(d1$y) < 1e-10) 25 | 26 | l2 <- ggplot(df, aes(x, y)) + geom_point() + 27 | facet_grid(. ~ z, scales = "free") 28 | d2 <- cdata(l2)[[1]] 29 | expect_true(sd(d2$x) < 1e-10) 30 | expect_equal(length(unique(d2$y)), 3) 31 | 32 | l3 <- ggplot(df, aes(x, y)) + geom_point() + 33 | facet_grid(z ~ ., scales = "free") 34 | d3 <- cdata(l3)[[1]] 35 | expect_equal(length(unique(d3$x)), 3) 36 | expect_true(sd(d3$y) < 1e-10) 37 | }) 38 | 39 | 40 | test_that("shrink parameter affects scaling", { 41 | l1 <- ggplot(df, aes(1, y)) + geom_point() 42 | r1 <- pranges(l1) 43 | 44 | expect_equal(r1$x[[1]], c(1, 1)) 45 | expect_equal(r1$y[[1]], c(1, 3)) 46 | 47 | l2 <- ggplot(df, aes(1, y)) + stat_summary(fun.y = "mean") 48 | r2 <- pranges(l2) 49 | expect_equal(r2$y[[1]], c(2, 2)) 50 | 51 | l3 <- ggplot(df, aes(1, y)) + stat_summary(fun.y = "mean") + 52 | facet_null(shrink = FALSE) 53 | r3 <- pranges(l3) 54 | expect_equal(r3$y[[1]], c(1, 3)) 55 | }) 56 | -------------------------------------------------------------------------------- /tests/testthat/test-sanitise-dim.r: -------------------------------------------------------------------------------- 1 | context("sanitise_dim") 2 | 3 | test_that("sanitise_dim returns NULL for zero-length inputs, with appropriate warnings", { 4 | expect_identical(sanitise_dim(NULL), NULL) 5 | n <- integer() 6 | y <- expect_identical(suppressWarnings(sanitise_dim(n)), NULL) 7 | expect_warning(sanitise_dim(n), "`n` has length zero and will be treated as NULL.") 8 | }) 9 | 10 | test_that("sanitise_dim returns the first element or NULL for non-positive integer inputs, with appropriate warnings", { 11 | n <- 1:2 12 | expect_identical(suppressWarnings(sanitise_dim(n)), 1L) 13 | expect_warning(sanitise_dim(n), "Only the first value of `n` will be used.") 14 | n2 <- 0:1 15 | expect_identical(suppressWarnings(sanitise_dim(n2)), NULL) 16 | expect_warning(sanitise_dim(n2), "Only the first value of `n2` will be used.") 17 | expect_warning(sanitise_dim(n2), "`n2` is missing or less than 1 and will be treated as NULL.") 18 | }) 19 | 20 | test_that("sanitise_dim returns a NULL for missing inputs, with appropriate warnings", { 21 | n <- NA_integer_ 22 | expect_identical(suppressWarnings(sanitise_dim(n)), NULL) 23 | expect_warning(sanitise_dim(n), "`n` is missing or less than 1 and will be treated as NULL.") 24 | }) 25 | 26 | test_that("sanitise_dim returns a positive integer or NULL for non-integer inputs, with appropriate warnings", { 27 | n <- 1.5 28 | expect_identical(suppressWarnings(sanitise_dim(n)), 1L) 29 | expect_warning(sanitise_dim(n), "Coercing `n` to be an integer.") 30 | n2 <- 0.9999999 31 | expect_identical(suppressWarnings(sanitise_dim(n2)), NULL) 32 | expect_warning(sanitise_dim(n2), "Coercing `n2` to be an integer.") 33 | expect_warning(sanitise_dim(n2), "`n2` is missing or less than 1 and will be treated as NULL.") 34 | }) 35 | -------------------------------------------------------------------------------- /man/position_jitter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/position-jitter.r 3 | \name{position_jitter} 4 | \alias{position_jitter} 5 | \title{Jitter points to avoid overplotting.} 6 | \usage{ 7 | position_jitter(width = NULL, height = NULL) 8 | } 9 | \arguments{ 10 | \item{width, height}{Amount of vertical and horizontal jitter. The jitter 11 | is added in both positive and negative directions, so the total spread 12 | is twice the value specified here. 13 | 14 | If omitted, defaults to 40\% of the resolution of the data: this means the 15 | jitter values will occupy 80\% of the implied bins. Categorical data 16 | is aligned on the integers, so a width or height of 0.5 will spread the 17 | data so it's not possible to see the distinction between the categories.} 18 | } 19 | \description{ 20 | Jitter points to avoid overplotting. 21 | } 22 | \examples{ 23 | ggplot(mtcars, aes(am, vs)) + geom_point() 24 | 25 | # Default amount of jittering will generally be too much for 26 | # small datasets: 27 | ggplot(mtcars, aes(am, vs)) + geom_jitter() 28 | 29 | # Two ways to override 30 | ggplot(mtcars, aes(am, vs)) + 31 | geom_jitter(width = 0.1, height = 0.1) 32 | ggplot(mtcars, aes(am, vs)) + 33 | geom_jitter(position = position_jitter(width = 0.1, height = 0.1)) 34 | 35 | # The default works better for large datasets, where it will 36 | # take up as much space as a boxplot or a bar 37 | ggplot(mpg, aes(class, hwy)) + 38 | geom_jitter() + 39 | geom_boxplot() 40 | } 41 | \seealso{ 42 | Other position adjustments: \code{\link{position_dodge}}, 43 | \code{\link{position_fill}}, 44 | \code{\link{position_identity}}, 45 | \code{\link{position_jitterdodge}}, 46 | \code{\link{position_nudge}} 47 | } 48 | \concept{position adjustments} 49 | -------------------------------------------------------------------------------- /man/draw_key.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/legend-draw.r 3 | \name{draw_key} 4 | \alias{draw_key} 5 | \alias{draw_key_point} 6 | \alias{draw_key_abline} 7 | \alias{draw_key_rect} 8 | \alias{draw_key_polygon} 9 | \alias{draw_key_blank} 10 | \alias{draw_key_boxplot} 11 | \alias{draw_key_crossbar} 12 | \alias{draw_key_path} 13 | \alias{draw_key_vpath} 14 | \alias{draw_key_dotplot} 15 | \alias{draw_key_pointrange} 16 | \alias{draw_key_smooth} 17 | \alias{draw_key_text} 18 | \alias{draw_key_label} 19 | \alias{draw_key_vline} 20 | \title{Key drawing functions} 21 | \usage{ 22 | draw_key_point(data, params, size) 23 | 24 | draw_key_abline(data, params, size) 25 | 26 | draw_key_rect(data, params, size) 27 | 28 | draw_key_polygon(data, params, size) 29 | 30 | draw_key_blank(data, params, size) 31 | 32 | draw_key_boxplot(data, params, size) 33 | 34 | draw_key_crossbar(data, params, size) 35 | 36 | draw_key_path(data, params, size) 37 | 38 | draw_key_vpath(data, params, size) 39 | 40 | draw_key_dotplot(data, params, size) 41 | 42 | draw_key_pointrange(data, params, size) 43 | 44 | draw_key_smooth(data, params, size) 45 | 46 | draw_key_text(data, params, size) 47 | 48 | draw_key_label(data, params, size) 49 | 50 | draw_key_vline(data, params, size) 51 | } 52 | \arguments{ 53 | \item{data}{A single row data frame containing the scaled aesthetics to 54 | display in this key} 55 | 56 | \item{params}{A list of additional parameters supplied to the geom.} 57 | 58 | \item{size}{Width and height of key in mm.} 59 | } 60 | \value{ 61 | A grid grob. 62 | } 63 | \description{ 64 | Each Geom has an associated function that draws the key when the geom needs 65 | to be displayed in a legend. These are the options built into ggplot2. 66 | } 67 | \keyword{internal} 68 | -------------------------------------------------------------------------------- /man/as_labeller.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/facet-labels.r 3 | \name{as_labeller} 4 | \alias{as_labeller} 5 | \title{Coerce to labeller function} 6 | \usage{ 7 | as_labeller(x, default = label_value, multi_line = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{Object to coerce to a labeller function. If a named 11 | character vector, it is used as a lookup table before being 12 | passed on to \code{default}. If a non-labeller function, it is 13 | assumed it takes and returns character vectors and is applied to 14 | the labels. If a labeller, it is simply applied to the labels.} 15 | 16 | \item{default}{Default labeller to process the labels produced by 17 | lookup tables or modified by non-labeller functions.} 18 | 19 | \item{multi_line}{Whether to display the labels of multiple factors 20 | on separate lines. This is passed to the labeller function.} 21 | } 22 | \description{ 23 | This transforms objects to labeller functions. Used internally by 24 | \code{\link{labeller}()}. 25 | } 26 | \examples{ 27 | p <- ggplot(mtcars, aes(disp, drat)) + geom_point() 28 | p + facet_wrap(~am) 29 | 30 | # Rename labels on the fly with a lookup character vector 31 | to_string <- as_labeller(c(`0` = "Zero", `1` = "One")) 32 | p + facet_wrap(~am, labeller = to_string) 33 | 34 | # Quickly transform a function operating on character vectors to a 35 | # labeller function: 36 | appender <- function(string, suffix = "-foo") paste0(string, suffix) 37 | p + facet_wrap(~am, labeller = as_labeller(appender)) 38 | 39 | # If you have more than one facetting variable, be sure to dispatch 40 | # your labeller to the right variable with labeller() 41 | p + facet_grid(cyl ~ am, labeller = labeller(am = to_string)) 42 | } 43 | \seealso{ 44 | \code{\link{labeller}()}, \link{labellers} 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/test-build.r: -------------------------------------------------------------------------------- 1 | # Test the complete path from plot specification to rendered data 2 | context("Plot building") 3 | 4 | df <- data.frame(x = 1:3, y = 3:1, z = letters[1:3]) 5 | 6 | test_that("there is one data frame for each layer", { 7 | nlayers <- function(x) length(ggplot_build(x)$data) 8 | 9 | l1 <- ggplot(df, aes(x, y)) + geom_point() 10 | l2 <- ggplot(df, aes(x, y)) + geom_point() + geom_line() 11 | l3 <- ggplot(df, aes(x, y)) + geom_point() + geom_line() + geom_point() 12 | 13 | expect_equal(nlayers(l1), 1) 14 | expect_equal(nlayers(l2), 2) 15 | expect_equal(nlayers(l3), 3) 16 | }) 17 | 18 | test_that("position aesthetics coerced to correct type", { 19 | l1 <- ggplot(df, aes(x, y)) + geom_point() 20 | d1 <- layer_data(l1, 1) 21 | 22 | expect_is(d1$x, "numeric") 23 | expect_is(d1$y, "numeric") 24 | 25 | l2 <- ggplot(df, aes(x, z)) + geom_point() + scale_x_discrete() 26 | d2 <- layer_data(l2, 1) 27 | 28 | expect_is(d2$x, "integer") 29 | expect_is(d2$y, "integer") 30 | }) 31 | 32 | test_that("non-position aesthetics are mapped", { 33 | l1 <- ggplot(df, aes(x, y, fill = z, colour = z, shape = z, size = z)) + 34 | geom_point() 35 | d1 <- layer_data(l1, 1) 36 | 37 | expect_equal(sort(names(d1)), sort(c("x", "y", "fill", "group", 38 | "colour", "shape", "size", "PANEL", "alpha", "stroke"))) 39 | 40 | l2 <- l1 + scale_colour_manual(values = c("blue", "red", "yellow")) 41 | d2 <- layer_data(l2, 1) 42 | expect_equal(d2$colour, c("blue", "red", "yellow")) 43 | }) 44 | 45 | test_that("strings are not converted to factors", { 46 | df <- data.frame(x = 1:2, y = 2:1, label = c("alpha", "beta"), stringsAsFactors = FALSE) 47 | p <- ggplot(df, aes(x, y)) + 48 | geom_text(aes(label = label), parse = TRUE) 49 | 50 | expect_is(layer_data(p)$label, "character") 51 | }) 52 | -------------------------------------------------------------------------------- /man/aes_position.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/aes-position.r 3 | \name{aes_position} 4 | \alias{aes_position} 5 | \alias{x} 6 | \alias{y} 7 | \alias{xmin} 8 | \alias{xmax} 9 | \alias{ymin} 10 | \alias{ymax} 11 | \alias{xend} 12 | \alias{yend} 13 | \title{Position related aesthetics: x, y, xmin, xmax, ymin, ymax, xend, yend} 14 | \description{ 15 | This page demonstrates the usage of a sub-group 16 | of aesthetics; x, y, xmin, xmax, ymin, ymax, xend, and yend. 17 | } 18 | \examples{ 19 | 20 | # Generate data: means and standard errors of means for prices 21 | # for each type of cut 22 | dmod <- lm(price ~ cut, data = diamonds) 23 | cuts <- data.frame(cut = unique(diamonds$cut), predict(dmod, data.frame(cut = 24 | unique(diamonds$cut)), se = TRUE)[c("fit", "se.fit")]) 25 | se <- ggplot(cuts, aes(x = cut, y = fit, ymin = fit - se.fit, 26 | ymax = fit + se.fit, colour = cut)) 27 | se + geom_pointrange() 28 | 29 | # Using annotate 30 | p <- ggplot(mtcars, aes(wt, mpg)) + geom_point() 31 | p + annotate("rect", xmin = 2, xmax = 3.5, ymin = 2, ymax = 25, 32 | fill = "dark grey", alpha = .5) 33 | 34 | # Geom_segment examples 35 | p + geom_segment(aes(x = 2, y = 15, xend = 2, yend = 25), 36 | arrow = arrow(length = unit(0.5, "cm"))) 37 | p + geom_segment(aes(x = 2, y = 15, xend = 3, yend = 15), 38 | arrow = arrow(length = unit(0.5, "cm"))) 39 | p + geom_segment(aes(x = 5, y = 30, xend = 3.5, yend = 25), 40 | arrow = arrow(length = unit(0.5, "cm"))) 41 | 42 | # You can also use geom_segment to recreate plot(type = "h") : 43 | counts <- as.data.frame(table(x = rpois(100, 5))) 44 | counts$x <- as.numeric(as.character(counts$x)) 45 | with(counts, plot(x, Freq, type = "h", lwd = 10)) 46 | 47 | ggplot(counts, aes(x, Freq)) + 48 | geom_segment(aes(yend = 0, xend = x), size = 10) 49 | } 50 | -------------------------------------------------------------------------------- /man/annotation_custom.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/annotation-custom.r 3 | \name{annotation_custom} 4 | \alias{annotation_custom} 5 | \title{Annotation: Custom grob.} 6 | \usage{ 7 | annotation_custom(grob, xmin = -Inf, xmax = Inf, ymin = -Inf, 8 | ymax = Inf) 9 | } 10 | \arguments{ 11 | \item{grob}{grob to display} 12 | 13 | \item{xmin, xmax}{x location (in data coordinates) giving horizontal 14 | location of raster} 15 | 16 | \item{ymin, ymax}{y location (in data coordinates) giving vertical 17 | location of raster} 18 | } 19 | \description{ 20 | This is a special geom intended for use as static annotations 21 | that are the same in every panel. These annotations will not 22 | affect scales (i.e. the x and y axes will not grow to cover the range 23 | of the grob, and the grob will not be modified by any ggplot settings or mappings). 24 | } 25 | \details{ 26 | Most useful for adding tables, inset plots, and other grid-based decorations. 27 | } 28 | \note{ 29 | \code{annotation_custom} expects the grob to fill the entire viewport 30 | defined by xmin, xmax, ymin, ymax. Grobs with a different (absolute) size 31 | will be center-justified in that region. 32 | Inf values can be used to fill the full plot panel (see examples). 33 | } 34 | \examples{ 35 | # Dummy plot 36 | df <- data.frame(x = 1:10, y = 1:10) 37 | base <- ggplot(df, aes(x, y)) + 38 | geom_blank() + 39 | theme_bw() 40 | 41 | # Full panel annotation 42 | base + annotation_custom( 43 | grob = grid::roundrectGrob(), 44 | xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf 45 | ) 46 | 47 | # Inset plot 48 | df2 <- data.frame(x = 1 , y = 1) 49 | g <- ggplotGrob(ggplot(df2, aes(x, y)) + 50 | geom_point() + 51 | theme(plot.background = element_rect(colour = "black"))) 52 | base + 53 | annotation_custom(grob = g, xmin = 1, xmax = 10, ymin = 8, ymax = 10) 54 | } 55 | -------------------------------------------------------------------------------- /man/annotation_raster.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/annotation-raster.r 3 | \name{annotation_raster} 4 | \alias{annotation_raster} 5 | \title{Annotation: High-performance rectangular tiling.} 6 | \usage{ 7 | annotation_raster(raster, xmin, xmax, ymin, ymax, interpolate = FALSE) 8 | } 9 | \arguments{ 10 | \item{raster}{raster object to display} 11 | 12 | \item{xmin, xmax}{x location (in data coordinates) giving horizontal 13 | location of raster} 14 | 15 | \item{ymin, ymax}{y location (in data coordinates) giving vertical 16 | location of raster} 17 | 18 | \item{interpolate}{If \code{TRUE} interpolate linearly, if \code{FALSE} 19 | (the default) don't interpolate.} 20 | } 21 | \description{ 22 | This is a special version of \code{\link{geom_raster}} optimised for static 23 | annotations that are the same in every panel. These annotations will not 24 | affect scales (i.e. the x and y axes will not grow to cover the range 25 | of the raster, and the raster must already have its own colours). 26 | } 27 | \details{ 28 | Most useful for adding bitmap images. 29 | } 30 | \examples{ 31 | # Generate data 32 | rainbow <- matrix(hcl(seq(0, 360, length.out = 50 * 50), 80, 70), nrow = 50) 33 | ggplot(mtcars, aes(mpg, wt)) + 34 | geom_point() + 35 | annotation_raster(rainbow, 15, 20, 3, 4) 36 | # To fill up whole plot 37 | ggplot(mtcars, aes(mpg, wt)) + 38 | annotation_raster(rainbow, -Inf, Inf, -Inf, Inf) + 39 | geom_point() 40 | 41 | rainbow2 <- matrix(hcl(seq(0, 360, length.out = 10), 80, 70), nrow = 1) 42 | ggplot(mtcars, aes(mpg, wt)) + 43 | annotation_raster(rainbow2, -Inf, Inf, -Inf, Inf) + 44 | geom_point() 45 | rainbow2 <- matrix(hcl(seq(0, 360, length.out = 10), 80, 70), nrow = 1) 46 | ggplot(mtcars, aes(mpg, wt)) + 47 | annotation_raster(rainbow2, -Inf, Inf, -Inf, Inf, interpolate = TRUE) + 48 | geom_point() 49 | } 50 | -------------------------------------------------------------------------------- /tests/testthat/test-layer.r: -------------------------------------------------------------------------------- 1 | context("Layer") 2 | 3 | 4 | # Parameters -------------------------------------------------------------- 5 | 6 | test_that("aesthetics go in aes_params", { 7 | l <- geom_point(size = "red") 8 | expect_equal(l$aes_params, list(size = "red")) 9 | }) 10 | 11 | test_that("unknown params create error", { 12 | expect_error(geom_point(blah = "red"), "Unknown parameters") 13 | }) 14 | 15 | # Calculated aesthetics --------------------------------------------------- 16 | 17 | test_that("Bare name surround by .. is calculated", { 18 | expect_true(is_calculated_aes(aes(..density..))) 19 | expect_true(is_calculated_aes(aes(..DENSITY..))) 20 | expect_false(is_calculated_aes(aes(a..x..b))) 21 | }) 22 | 23 | test_that("Calling using variable surround by .. is calculated", { 24 | expect_true(is_calculated_aes(aes(mean(..density..)))) 25 | expect_true(is_calculated_aes(aes(mean(..DENSITY..)))) 26 | expect_false(is_calculated_aes(aes(mean(a..x..b)))) 27 | }) 28 | 29 | test_that("strip_dots remove dots around calculated aesthetics", { 30 | expect_equal(strip_dots(aes(..density..))$x, quote(density)) 31 | expect_equal(strip_dots(aes(mean(..density..)))$x, quote(mean(density))) 32 | expect_equal(strip_dots(aes(sapply(..density.., function(x) mean(x)))$x), 33 | quote(sapply(density, function(x) mean(x)))) 34 | }) 35 | 36 | # Data extraction --------------------------------------------------------- 37 | 38 | test_that("layer_data returns a data.frame", { 39 | l <- geom_point() 40 | expect_equal(l$layer_data(mtcars), mtcars) 41 | l <- geom_point(data = head(mtcars)) 42 | expect_equal(l$layer_data(mtcars), head(mtcars)) 43 | l <- geom_point(data = head) 44 | expect_equal(l$layer_data(mtcars), head(mtcars)) 45 | l <- geom_point(data = nrow) 46 | expect_error(l$layer_data(mtcars), "Data function must return a data.frame") 47 | }) 48 | -------------------------------------------------------------------------------- /tests/testthat/test-aes.r: -------------------------------------------------------------------------------- 1 | context("Creating aesthetic mappings") 2 | 3 | test_that("aes() captures input expressions", { 4 | out <- aes(mpg, wt + 1) 5 | expect_equal(out$x, quote(mpg)) 6 | expect_equal(out$y, quote(wt + 1)) 7 | }) 8 | 9 | test_that("aes_q() uses quoted calls and formulas", { 10 | out <- aes_q(quote(mpg), ~ wt + 1) 11 | expect_equal(out$x, quote(mpg)) 12 | expect_equal(out$y, quote(wt + 1)) 13 | }) 14 | 15 | test_that("aes_string() parses strings", { 16 | expect_equal(aes_string("a + b")$x, quote(a + b)) 17 | }) 18 | 19 | test_that("aes_string() doesn't parse non-strings", { 20 | old <- options(OutDec = ",") 21 | on.exit(options(old)) 22 | 23 | expect_equal(aes_string(0.4)$x, 0.4) 24 | }) 25 | 26 | test_that("aes_q() & aes_string() preserves explicit NULLs", { 27 | expect_equal(aes_q(NULL), aes(NULL)) 28 | expect_equal(aes_q(x = NULL), aes(NULL)) 29 | expect_equal(aes_q(colour = NULL), aes(colour = NULL)) 30 | 31 | expect_equal(aes_string(NULL), aes(NULL)) 32 | expect_equal(aes_string(x = NULL), aes(NULL)) 33 | expect_equal(aes_string(colour = NULL), aes(colour = NULL)) 34 | }) 35 | 36 | test_that("aes_all() converts strings into mappings", { 37 | expect_equal( 38 | aes_all(c("x", "y", "col", "pch")), 39 | aes(x, y, colour = col, shape = pch) 40 | ) 41 | }) 42 | 43 | test_that("aes evaluated in environment where plot created", { 44 | df <- data.frame(x = 1, y = 1) 45 | p <- ggplot(df, aes(foo, y)) + geom_point() 46 | 47 | # Accessing an undefined variable should result in error 48 | expect_error(layer_data(p), "'foo' not found") 49 | 50 | # Once it's defined we should get it back 51 | foo <- 0 52 | expect_equal(layer_data(p)$x, 0) 53 | 54 | # And regular variable shadowing should work 55 | f <- function() { 56 | foo <- 10 57 | ggplot(df, aes(foo, y)) + geom_point() 58 | } 59 | expect_equal(layer_data(f())$x, 10) 60 | }) 61 | -------------------------------------------------------------------------------- /R/facet-.r: -------------------------------------------------------------------------------- 1 | #' Facet specification. 2 | #' 3 | #' Create new facetting specification. For internal use only. 4 | #' 5 | #' @param ... object fields 6 | #' @param shrink shrink scales to fit output of statistics, not raw data 7 | #' @keywords internal 8 | #' @export 9 | facet <- function(..., shrink = TRUE, subclass = c()) { 10 | structure(list(..., shrink = shrink), class = c(subclass, "facet")) 11 | } 12 | 13 | #' Is this object a facetting specification? 14 | #' 15 | #' @param x object to test 16 | #' @keywords internal 17 | #' @export 18 | is.facet <- function(x) inherits(x, "facet") 19 | 20 | 21 | # Figure out layout from data from plot and all layers. 22 | # 23 | # This creates the layout data frame which maps from data values to 24 | # panel coordinates: ROW, COL and PANEL. It also records the panels that 25 | # contribute to each x and y scale. 26 | # 27 | # @param data a list of data frames (one for the plot and one for each 28 | # layer) 29 | facet_train_layout <- function(facet, data) 30 | UseMethod("facet_train_layout") 31 | 32 | facet_map_layout <- function(facet, data, layout) 33 | UseMethod("facet_map_layout") 34 | 35 | facet_render <- function(facet, panels_grob, coord, theme, geom_grobs) 36 | UseMethod("facet_render") 37 | 38 | facet_strips <- function(facet, panel, theme) 39 | UseMethod("facet_strips") 40 | 41 | facet_panels <- function(facet, panel, coord, theme, geom_grobs) 42 | UseMethod("facet_panels") 43 | 44 | facet_axes <- function(facet, panel, coord, theme) 45 | UseMethod("facet_axes") 46 | 47 | # Text description of facetting variables 48 | facet_vars <- function(facet) 49 | UseMethod("facet_vars") 50 | 51 | 52 | #' @export 53 | format.facet <- function(x, ...) { 54 | name <- paste(rev(class(x)), collapse = "_") 55 | 56 | paste(name, "(", facet_vars(x), ")", sep = "") 57 | } 58 | 59 | #' @export 60 | print.facet <- function(x, ...) { 61 | cat(format(x, ...), "\n") 62 | } 63 | -------------------------------------------------------------------------------- /tests/testthat/test-utilities.r: -------------------------------------------------------------------------------- 1 | context("Utilities") 2 | 3 | test_that("finite.cases.data.frame", { 4 | # All finite -------------------------------------------------------------- 5 | expect_identical(finite.cases(data.frame(x = 4)), TRUE) # 1x1 6 | expect_identical(finite.cases(data.frame(x = 4, y = 11)), TRUE) # 1x2 7 | expect_identical(finite.cases(data.frame(x = 4:5)), c(TRUE, TRUE)) # 2x1 8 | expect_identical(finite.cases(data.frame(x = 4:5, y = 11:12)), c(TRUE, TRUE)) # 2x2 9 | 10 | # Has one NA -------------------------------------------------------------- 11 | expect_identical(finite.cases(data.frame(x = NA)), FALSE) # 1x1 12 | expect_identical(finite.cases(data.frame(x = 4, y = NA)), FALSE) # 1x2 13 | expect_identical(finite.cases(data.frame(x = c(4, NA))), c(TRUE, FALSE)) # 2x1 14 | expect_identical(finite.cases(data.frame(x = c(4, NA), y = c(11, NA))), c(TRUE, FALSE)) # 2x2 15 | expect_identical(finite.cases(data.frame(x = c(4, NA), y = c(NA, 12))), c(FALSE, FALSE)) # 2x2 16 | expect_identical(finite.cases(data.frame(x = c(4, 5), y = c(NA, 12))), c(FALSE, TRUE)) # 2x2 17 | 18 | # Testing NaN and Inf, using miscellaneous data shapes -------------------- 19 | expect_identical(finite.cases(data.frame(x = c(4, NaN))), c(TRUE, FALSE)) 20 | expect_identical(finite.cases(data.frame(x = Inf)), FALSE) 21 | expect_identical(finite.cases(data.frame(x = c(4, 5), y = c(-Inf, 12))), c(FALSE, TRUE)) 22 | }) 23 | 24 | test_that("add_group", { 25 | data <- data.frame(f=letters[7:9], x=1:3, y=4:6, group=c(1, -1, 1)) 26 | expect_true(has_groups(add_group(data[2:4]))) # explicit group column 27 | expect_true(has_groups(add_group(data[1:3]))) # discrete column 28 | expect_false(has_groups(add_group(data[2:3]))) # no group or discrete column 29 | }) 30 | -------------------------------------------------------------------------------- /R/geom-spoke.r: -------------------------------------------------------------------------------- 1 | #' A line segment parameterised by location, direction and distance. 2 | #' 3 | #' @section Aesthetics: 4 | #' \Sexpr[results=rd,stage=build]{lwplot:::rd_aesthetics("geom", "spoke")} 5 | #' 6 | #' @inheritParams layer 7 | #' @inheritParams geom_segment 8 | #' @export 9 | #' @examples 10 | #' df <- expand.grid(x = 1:10, y=1:10) 11 | #' df$angle <- runif(100, 0, 2*pi) 12 | #' df$speed <- runif(100, 0, sqrt(0.1 * df$x)) 13 | #' 14 | #' ggplot(df, aes(x, y)) + 15 | #' geom_point() + 16 | #' geom_spoke(aes(angle = angle), radius = 0.5) 17 | #' 18 | #' ggplot(df, aes(x, y)) + 19 | #' geom_point() + 20 | #' geom_spoke(aes(angle = angle, radius = speed)) 21 | geom_spoke <- function(mapping = NULL, data = NULL, 22 | stat = "identity", position = "identity", 23 | ..., 24 | na.rm = FALSE, 25 | show.legend = NA, 26 | inherit.aes = TRUE) { 27 | layer( 28 | data = data, 29 | mapping = mapping, 30 | geom = GeomSpoke, 31 | stat = stat, 32 | position = position, 33 | show.legend = show.legend, 34 | inherit.aes = inherit.aes, 35 | params = list( 36 | na.rm = na.rm, 37 | ... 38 | ) 39 | ) 40 | } 41 | 42 | #' @export 43 | #' @rdname geom_spoke 44 | #' @usage NULL 45 | stat_spoke <- function(...) { 46 | message("stat_spoke is deprecated, please use geom_spoke") 47 | geom_spoke(...) 48 | } 49 | 50 | #' @rdname ggplot2-ggproto 51 | #' @format NULL 52 | #' @usage NULL 53 | #' @export 54 | GeomSpoke <- ggproto("GeomSpoke", GeomSegment, 55 | setup_data = function(data, params) { 56 | data$radius <- data$radius %||% params$radius 57 | data$angle <- data$angle %||% params$angle 58 | 59 | transform(data, 60 | xend = x + cos(angle) * radius, 61 | yend = y + sin(angle) * radius 62 | ) 63 | }, 64 | required_aes = c("x", "y", "angle", "radius") 65 | ) 66 | -------------------------------------------------------------------------------- /man/position_dodge.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/position-dodge.r 3 | \name{position_dodge} 4 | \alias{position_dodge} 5 | \title{Adjust position by dodging overlaps to the side.} 6 | \usage{ 7 | position_dodge(width = NULL) 8 | } 9 | \arguments{ 10 | \item{width}{Dodging width, when different to the width of the individual 11 | elements. This is useful when you want to align narrow geoms with wider 12 | geoms. See the examples for a use case.} 13 | } 14 | \description{ 15 | Adjust position by dodging overlaps to the side. 16 | } 17 | \examples{ 18 | ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) + 19 | geom_bar(position = "dodge") 20 | \donttest{ 21 | ggplot(diamonds, aes(price, fill = cut)) + 22 | geom_histogram(position="dodge") 23 | # see ?geom_boxplot and ?geom_bar for more examples 24 | 25 | # To dodge items with different widths, you need to be explicit 26 | df <- data.frame(x=c("a","a","b","b"), y=2:5, g = rep(1:2, 2)) 27 | p <- ggplot(df, aes(x, y, group = g)) + 28 | geom_bar( 29 | stat = "identity", position = "dodge", 30 | fill = "grey50", colour = "black" 31 | ) 32 | p 33 | 34 | # A line range has no width: 35 | p + geom_linerange(aes(ymin = y-1, ymax = y+1), position = "dodge") 36 | # You need to explicitly specify the width for dodging 37 | p + geom_linerange(aes(ymin = y-1, ymax = y+1), 38 | position = position_dodge(width = 0.9)) 39 | 40 | # Similarly with error bars: 41 | p + geom_errorbar(aes(ymin = y-1, ymax = y+1), width = 0.2, 42 | position = "dodge") 43 | p + geom_errorbar(aes(ymin = y-1, ymax = y+1, width = 0.2), 44 | position = position_dodge(width = 0.90)) 45 | } 46 | } 47 | \seealso{ 48 | Other position adjustments: \code{\link{position_fill}}, 49 | \code{\link{position_identity}}, 50 | \code{\link{position_jitterdodge}}, 51 | \code{\link{position_jitter}}, 52 | \code{\link{position_nudge}} 53 | } 54 | \concept{position adjustments} 55 | -------------------------------------------------------------------------------- /R/geom-errorbar.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname geom_linerange 3 | geom_errorbar <- function(mapping = NULL, data = NULL, 4 | stat = "identity", position = "identity", 5 | ..., 6 | na.rm = FALSE, 7 | show.legend = NA, 8 | inherit.aes = TRUE) { 9 | layer( 10 | data = data, 11 | mapping = mapping, 12 | stat = stat, 13 | geom = GeomErrorbar, 14 | position = position, 15 | show.legend = show.legend, 16 | inherit.aes = inherit.aes, 17 | params = list( 18 | na.rm = na.rm, 19 | ... 20 | ) 21 | ) 22 | } 23 | 24 | #' @rdname ggplot2-ggproto 25 | #' @format NULL 26 | #' @usage NULL 27 | #' @export 28 | GeomErrorbar <- ggproto("GeomErrorbar", Geom, 29 | default_aes = aes(colour = "black", size = 0.5, linetype = 1, width = 0.5, 30 | alpha = NA), 31 | 32 | draw_key = draw_key_path, 33 | 34 | required_aes = c("x", "ymin", "ymax"), 35 | 36 | setup_data = function(data, params) { 37 | data$width <- data$width %||% 38 | params$width %||% (resolution(data$x, FALSE) * 0.9) 39 | 40 | transform(data, 41 | xmin = x - width / 2, xmax = x + width / 2, width = NULL 42 | ) 43 | }, 44 | 45 | draw_panel = function(data, panel_scales, coord, width = NULL) { 46 | GeomPath$draw_panel(data.frame( 47 | x = as.vector(rbind(data$xmin, data$xmax, NA, data$x, data$x, NA, data$xmin, data$xmax)), 48 | y = as.vector(rbind(data$ymax, data$ymax, NA, data$ymax, data$ymin, NA, data$ymin, data$ymin)), 49 | colour = rep(data$colour, each = 8), 50 | alpha = rep(data$alpha, each = 8), 51 | size = rep(data$size, each = 8), 52 | linetype = rep(data$linetype, each = 8), 53 | group = rep(1:(nrow(data)), each = 8), 54 | stringsAsFactors = FALSE, 55 | row.names = 1:(nrow(data) * 8) 56 | ), panel_scales, coord) 57 | } 58 | ) 59 | -------------------------------------------------------------------------------- /tests/testthat/test-ggsave.R: -------------------------------------------------------------------------------- 1 | context("ggsave") 2 | 3 | test_that("ggsave creates file", { 4 | path <- tempfile() 5 | on.exit(unlink(path)) 6 | 7 | p <- ggplot(mpg, aes(displ, hwy)) + geom_point() 8 | 9 | expect_false(file.exists(path)) 10 | ggsave(path, p, device = "pdf", width = 5, height = 5) 11 | expect_true(file.exists(path)) 12 | }) 13 | 14 | 15 | # plot_dim --------------------------------------------------------------- 16 | 17 | test_that("guesses and informs if dim not specified", { 18 | png(width = 10, height = 10, units = "in", res = 300) 19 | on.exit(capture.output(dev.off())) 20 | 21 | expect_message(out <- plot_dim(), "10 x 10") 22 | expect_equal(out, c(10, 10)) 23 | }) 24 | 25 | test_that("uses 7x7 if no graphics device open", { 26 | expect_equal(plot_dim(), c(7, 7)) 27 | }) 28 | 29 | test_that("warned about large plot unless limitsize = FALSE", { 30 | expect_error(plot_dim(c(50, 50)), "exceed 50 inches") 31 | expect_equal(plot_dim(c(50, 50), limitsize = FALSE), c(50, 50)) 32 | }) 33 | 34 | test_that("scale multiplies height & width", { 35 | expect_equal(plot_dim(c(10, 10), scale = 1), c(10, 10)) 36 | expect_equal(plot_dim(c(5, 5), scale = 2), c(10, 10)) 37 | }) 38 | 39 | 40 | # plot_dev --------------------------------------------------------------------- 41 | 42 | test_that("function passed back unchanged", { 43 | expect_equal(plot_dev(png), png) 44 | }) 45 | 46 | test_that("unknown device triggers error", { 47 | expect_error(plot_dev("xyz"), "Unknown graphics device") 48 | expect_error(plot_dev(NULL, "test.xyz"), "Unknown graphics device") 49 | }) 50 | 51 | 52 | test_that("text converted to function", { 53 | expect_identical(body(plot_dev("png"))[[1]], quote(grDevices::png)) 54 | expect_identical(body(plot_dev("pdf"))[[1]], quote(grDevices::pdf)) 55 | }) 56 | 57 | test_that("if device is NULL, guess from extension", { 58 | expect_identical(body(plot_dev(NULL, "test.png"))[[1]], quote(grDevices::png)) 59 | }) 60 | -------------------------------------------------------------------------------- /man/cut_interval.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utilities-break.r 3 | \name{cut_interval} 4 | \alias{cut_interval} 5 | \alias{cut_number} 6 | \alias{cut_width} 7 | \title{Cut up numeric vector into useful groups.} 8 | \usage{ 9 | cut_interval(x, n = NULL, length = NULL, ...) 10 | 11 | cut_number(x, n = NULL, ...) 12 | 13 | cut_width(x, width, center = NULL, boundary = NULL, 14 | closed = c("right", "left")) 15 | } 16 | \arguments{ 17 | \item{x}{numeric vector} 18 | 19 | \item{n}{number of intervals to create, OR} 20 | 21 | \item{length}{length of each interval} 22 | 23 | \item{...}{other arguments passed on to \code{\link{cut}}} 24 | 25 | \item{width}{The bin width.} 26 | 27 | \item{center, boundary}{Specify either the position of edge or the center of 28 | a bin. Since all bins are aligned, specifying the position of a single bin 29 | (which doesn't need to be in the range of the data) affects the location of 30 | all bins. If not specified, uses the "tile layers algorithm", and sets 31 | the boundary to half of the binwidth. 32 | 33 | To center on integers, \code{width = 1} and \code{center = 0}. 34 | \code{boundary = 0.5}.} 35 | 36 | \item{closed}{One of \code{"right"} or \code{"left"} indicating whether right 37 | or left edges of bins are included in the bin.} 38 | } 39 | \description{ 40 | \code{cut_interval} makes \code{n} groups with equal range, \code{cut_number} 41 | makes \code{n} groups with (approximately) equal numbers of observations; 42 | \code{cut_width} makes groups of width \code{width}. 43 | } 44 | \examples{ 45 | table(cut_interval(1:100, 10)) 46 | table(cut_interval(1:100, 11)) 47 | 48 | table(cut_number(runif(1000), 10)) 49 | 50 | table(cut_width(runif(1000), 0.1)) 51 | table(cut_width(runif(1000), 0.1, boundary = 0)) 52 | table(cut_width(runif(1000), 0.1, center = 0)) 53 | } 54 | \seealso{ 55 | \code{\link{cut_number}} 56 | } 57 | \author{ 58 | Randall Prium contributed most of the implementation of 59 | \code{cut_width}. 60 | } 61 | -------------------------------------------------------------------------------- /R/geom-curve.r: -------------------------------------------------------------------------------- 1 | #' @inheritParams grid::curveGrob 2 | #' @export 3 | #' @rdname geom_segment 4 | geom_curve <- function(mapping = NULL, data = NULL, 5 | stat = "identity", position = "identity", 6 | ..., 7 | curvature = 0.5, 8 | angle = 90, 9 | ncp = 5, 10 | arrow = NULL, 11 | lineend = "butt", 12 | na.rm = FALSE, 13 | show.legend = NA, 14 | inherit.aes = TRUE) { 15 | layer( 16 | data = data, 17 | mapping = mapping, 18 | stat = stat, 19 | geom = GeomCurve, 20 | position = position, 21 | show.legend = show.legend, 22 | inherit.aes = inherit.aes, 23 | params = list( 24 | arrow = arrow, 25 | curvature = curvature, 26 | angle = angle, 27 | ncp = ncp, 28 | lineend = lineend, 29 | na.rm = na.rm, 30 | ... 31 | ) 32 | ) 33 | } 34 | 35 | #' @rdname ggplot2-ggproto 36 | #' @include geom-segment.r 37 | #' @format NULL 38 | #' @usage NULL 39 | #' @export 40 | GeomCurve <- ggproto("GeomCurve", GeomSegment, 41 | draw_panel = function(data, panel_scales, coord, curvature = 0.5, angle = 90, 42 | ncp = 5, arrow = NULL, lineend = "butt", na.rm = FALSE) { 43 | if (!coord$is_linear()) { 44 | warning("geom_curve is not implemented for non-linear coordinates", 45 | call. = FALSE) 46 | } 47 | trans <- coord$transform(data, panel_scales) 48 | curveGrob( 49 | trans$x, trans$y, trans$xend, trans$yend, 50 | default.units = "native", 51 | curvature = curvature, angle = angle, ncp = ncp, 52 | square = FALSE, squareShape = 1, inflect = FALSE, open = TRUE, 53 | gp = gpar( 54 | col = alpha(trans$colour, trans$alpha), 55 | lwd = trans$size * .pt, 56 | lty = trans$linetype, 57 | lineend = trans$lineend), 58 | arrow = arrow 59 | ) 60 | } 61 | ) 62 | -------------------------------------------------------------------------------- /R/grob-dotstack.r: -------------------------------------------------------------------------------- 1 | dotstackGrob <- function( 2 | x = unit(0.5, "npc"), # x pos of the dotstack's origin 3 | y = unit(0.5, "npc"), # y pos of the dotstack's origin 4 | stackaxis = "y", 5 | dotdia = unit(1, "npc"), # Dot diameter in the non-stack axis, should be in npc 6 | stackposition = 0, # Position of each dot in the stack, relative to origin 7 | stackratio = 1, # Stacking height of dots (.75 means 25% dot overlap) 8 | default.units = "npc", name = NULL, gp = gpar(), vp = NULL) 9 | { 10 | if (!is.unit(x)) 11 | x <- unit(x, default.units) 12 | if (!is.unit(y)) 13 | y <- unit(y, default.units) 14 | if (!is.unit(dotdia)) 15 | dotdia <- unit(dotdia, default.units) 16 | if (attr(dotdia,"unit") != "npc") 17 | warning("Unit type of dotdia should be 'npc'") 18 | 19 | grob(x = x, y = y, stackaxis = stackaxis, dotdia = dotdia, 20 | stackposition = stackposition, stackratio = stackratio, 21 | name = name, gp = gp, vp = vp, cl = "dotstackGrob") 22 | } 23 | 24 | #' @export 25 | makeContext.dotstackGrob <- function(x, recording = TRUE) { 26 | # Need absolute coordinates because when using npc coords with circleGrob, 27 | # the radius is in the _smaller_ of the two axes. We need the radius 28 | # to instead be defined in terms of the non-stack axis. 29 | xmm <- convertX(x$x, "mm", valueOnly = TRUE) 30 | ymm <- convertY(x$y, "mm", valueOnly = TRUE) 31 | 32 | if (x$stackaxis == "x") { 33 | dotdiamm <- convertY(x$dotdia, "mm", valueOnly = TRUE) 34 | xpos <- xmm + dotdiamm * (x$stackposition * x$stackratio + (1 - x$stackratio) / 2) 35 | ypos <- ymm 36 | } else if (x$stackaxis == "y") { 37 | dotdiamm <- convertX(x$dotdia, "mm", valueOnly = TRUE) 38 | xpos <- xmm 39 | ypos <- ymm + dotdiamm * (x$stackposition * x$stackratio + (1 - x$stackratio) / 2) 40 | } 41 | 42 | circleGrob( 43 | x = xpos, y = ypos, r = dotdiamm / 2, default.units = "mm", 44 | name = x$name, gp = x$gp, vp = x$vp 45 | ) 46 | } 47 | -------------------------------------------------------------------------------- /R/scale-type.R: -------------------------------------------------------------------------------- 1 | find_scale <- function(aes, x, env = parent.frame()) { 2 | type <- scale_type(x) 3 | candidates <- paste("scale", aes, type, sep = "_") 4 | 5 | for (scale in candidates) { 6 | scale_f <- find_global(scale, env, mode = "function") 7 | if (!is.null(scale_f)) 8 | return(scale_f()) 9 | } 10 | 11 | # Failure to find a scale is not an error because some "aesthetics" don't 12 | # need scales (e.g. group), and it allows others to extend ggplot2 with 13 | # their own aesthetics 14 | 15 | return(NULL) 16 | } 17 | 18 | # Look for object first in parent environment and if not found, then in 19 | # ggplot2 namespace environment. This makes it possible to override default 20 | # scales by setting them in the parent environment. 21 | find_global <- function(name, env, mode = "any") { 22 | if (exists(name, envir = env, mode = mode)) { 23 | return(get(name, envir = env, mode = mode)) 24 | } 25 | 26 | nsenv <- asNamespace("lwplot") 27 | if (exists(name, envir = nsenv, mode = mode)) { 28 | return(get(name, envir = nsenv, mode = mode)) 29 | } 30 | 31 | NULL 32 | } 33 | 34 | # Determine default type of a scale 35 | scale_type <- function(x) UseMethod("scale_type") 36 | 37 | #' @export 38 | scale_type.default <- function(x) { 39 | message("Don't know how to automatically pick scale for object of type ", 40 | paste(class(x), collapse = "/"), ". Defaulting to continuous.") 41 | "continuous" 42 | } 43 | 44 | #' @export 45 | scale_type.AsIs <- function(x) "identity" 46 | 47 | #' @export 48 | scale_type.logical <- function(x) "discrete" 49 | 50 | #' @export 51 | scale_type.character <- function(x) "discrete" 52 | 53 | #' @export 54 | scale_type.ordered <- function(x) c("ordinal", "discrete") 55 | 56 | #' @export 57 | scale_type.factor <- function(x) "discrete" 58 | 59 | #' @export 60 | scale_type.POSIXt <- function(x) c("datetime", "continuous") 61 | 62 | #' @export 63 | scale_type.Date <- function(x) c("date", "continuous") 64 | 65 | #' @export 66 | scale_type.numeric <- function(x) "continuous" 67 | -------------------------------------------------------------------------------- /tests/testthat/test-coord-polar.r: -------------------------------------------------------------------------------- 1 | context("coord_polar") 2 | 3 | test_that("Polar distance calculation", { 4 | dat <- data.frame( 5 | theta = c(0, 2*pi, 2, 6, 6, 1, 1, 0), 6 | r = c(0, 0, 0.5, 0.5, 1, 1, 0.75, .5)) 7 | 8 | scales <- list( 9 | x = scale_x_continuous(limits = c(0, 2*pi)), 10 | y = scale_y_continuous(limits = c(0, 1)) 11 | ) 12 | coord <- coord_polar() 13 | dists <- coord$distance(dat$theta, dat$r, coord$train(scales)) 14 | 15 | # dists is normalized by dividing by this value, so we'll add it back 16 | # The maximum length of a spiral arc, from (t,r) = (0,0) to (2*pi,1) 17 | maxlen <- spiral_arc_length(1 / (2 * pi), 0, 2 * pi) 18 | 19 | # These are the expected lengths. I think they're correct... 20 | expect_equal(dists, 21 | c(0, -1.225737494, -2, -0.5, -5, -0.25, -0.6736885011) / maxlen) 22 | 23 | # The picture can be visualized with: 24 | # ggplot(dat, aes(x=theta, y=r)) + geom_path() + 25 | # geom_point(alpha=0.3) + coord_polar() 26 | }) 27 | 28 | 29 | 30 | test_that("Polar distance calculation ignores NA's", { 31 | 32 | # These are r and theta values; we'll swap them around for testing 33 | x1 <- c(0, 0.5, 0.5, NA, 1) 34 | x2 <- c(0, 1, 2, 0, 1) 35 | 36 | dists <- dist_polar(x1, x2) 37 | expect_equal(is.na(dists), c(FALSE, FALSE, TRUE, TRUE)) 38 | dists <- dist_polar(x2, x1) 39 | expect_equal(is.na(dists), c(FALSE, FALSE, TRUE, TRUE)) 40 | 41 | 42 | # NA on the end 43 | x1 <- c(0, 0.5, 0.5, 1, NA) 44 | x2 <- c(0, 1, 2, 0, 1) 45 | dists <- dist_polar(x1, x2) 46 | expect_equal(is.na(dists), c(FALSE, FALSE, FALSE, TRUE)) 47 | dists <- dist_polar(x2, x1) 48 | expect_equal(is.na(dists), c(FALSE, FALSE, FALSE, TRUE)) 49 | 50 | 51 | # NAs in each vector - also have NaN 52 | x1 <- c(0, 0.5, 0.5, 1, NA) 53 | x2 <- c(NaN, 1, 2, NA, 1) 54 | dists <- dist_polar(x1, x2) 55 | expect_equal(is.na(dists), c(TRUE, FALSE, TRUE, TRUE)) 56 | dists <- dist_polar(x2, x1) 57 | expect_equal(is.na(dists), c(TRUE, FALSE, TRUE, TRUE)) 58 | }) 59 | -------------------------------------------------------------------------------- /man/aes_.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/aes.r 3 | \name{aes_} 4 | \alias{aes_} 5 | \alias{aes_string} 6 | \alias{aes_q} 7 | \title{Define aesthetic mappings from strings, or quoted calls and formulas.} 8 | \usage{ 9 | aes_(x, y, ...) 10 | 11 | aes_string(x, y, ...) 12 | 13 | aes_q(x, y, ...) 14 | } 15 | \arguments{ 16 | \item{x, y, ...}{List of name value pairs. Elements must be either 17 | quoted calls, strings, one-sided formulas or constants.} 18 | } 19 | \description{ 20 | Aesthetic mappings describe how variables in the data are mapped to visual 21 | properties (aesthetics) of geoms. \code{\link{aes}} uses non-standard 22 | evaluation to capture the variable names. \code{aes_} and \code{aes_string} 23 | require you to explicitly quote the inputs either with \code{""} for 24 | \code{aes_string()}, or with \code{quote} or \code{~} for \code{aes_()}. 25 | (\code{aes_q} is an alias to \code{aes_}) 26 | } 27 | \details{ 28 | It's better to use \code{aes_q()}, because there's no easy way to create the 29 | equivalent to \code{aes(colour = "my colour")} or \code{aes{x = `X$1`}} 30 | with \code{aes_string()}. 31 | 32 | \code{aes_string} and \code{aes_} are particularly useful when writing 33 | functions that create plots because you can use strings or quoted 34 | names/calls to define the aesthetic mappings, rather than having to use 35 | \code{\link{substitute}} to generate a call to \code{aes()}. 36 | } 37 | \examples{ 38 | # Three ways of generating the same aesthetics 39 | aes(mpg, wt, col = cyl) 40 | aes_(quote(mpg), quote(wt), col = quote(cyl)) 41 | aes_(~mpg, ~wt, col = ~cyl) 42 | aes_string("mpg", "wt", col = "cyl") 43 | 44 | # You can't easily mimic these calls with aes_string 45 | aes(`$100`, colour = "smooth") 46 | aes_(~ `$100`, colour = "smooth") 47 | # Ok, you can, but it requires a _lot_ of quotes 48 | aes_string("`$100`", colour = '"smooth"') 49 | 50 | # Convert strings to names with as.name 51 | var <- "cyl" 52 | aes(col = x) 53 | aes_(col = as.name(var)) 54 | } 55 | \seealso{ 56 | \code{\link{aes}} 57 | } 58 | -------------------------------------------------------------------------------- /man/theme_update.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme.r 3 | \name{theme_update} 4 | \alias{theme_update} 5 | \alias{theme_replace} 6 | \alias{theme_get} 7 | \alias{theme_set} 8 | \title{Get, set and update themes.} 9 | \usage{ 10 | theme_update(...) 11 | 12 | theme_replace(...) 13 | 14 | theme_get() 15 | 16 | theme_set(new) 17 | } 18 | \arguments{ 19 | \item{...}{named list of theme settings} 20 | 21 | \item{new}{new theme (a list of theme elements)} 22 | } 23 | \description{ 24 | Use \code{theme_get} to get the current theme, and \code{theme_set} to 25 | completely override it. \code{theme_update} and \code{theme_replace} are 26 | shorthands for changing individual elements in the current theme. 27 | \code{theme_update} uses the \code{+} operator, so that any unspecified 28 | values in the theme element will default to the values they are set in the 29 | theme. \code{theme_replace} will completely replace the element, so any 30 | unspecified values will overwrite the current value in the theme with \code{NULL}s. 31 | } 32 | \examples{ 33 | p <- ggplot(mtcars, aes(mpg, wt)) + 34 | geom_point() 35 | p 36 | old <- theme_set(theme_bw()) 37 | p 38 | theme_set(old) 39 | p 40 | 41 | #theme_replace NULLs out the fill attribute of panel.background, 42 | #resulting in a white background: 43 | theme_get()$panel.background 44 | old <- theme_replace(panel.background = element_rect(colour = "pink")) 45 | theme_get()$panel.background 46 | p 47 | theme_set(old) 48 | 49 | #theme_update only changes the colour attribute, leaving the others intact: 50 | old <- theme_update(panel.background = element_rect(colour = "pink")) 51 | theme_get()$panel.background 52 | p 53 | theme_set(old) 54 | 55 | theme_get() 56 | 57 | 58 | ggplot(mtcars, aes(mpg, wt)) + 59 | geom_point(aes(color = mpg)) + 60 | theme(legend.position = c(0.95, 0.95), 61 | legend.justification = c(1, 1)) 62 | last_plot() + 63 | theme(legend.background = element_rect(fill = "white", colour = "white", size = 3)) 64 | 65 | } 66 | \seealso{ 67 | \code{\link{\%+replace\%}} and \code{\link{+.gg}} 68 | } 69 | -------------------------------------------------------------------------------- /R/coord-flip.r: -------------------------------------------------------------------------------- 1 | #' Flipped cartesian coordinates. 2 | #' 3 | #' Flipped cartesian coordinates so that horizontal becomes vertical, and 4 | #' vertical, horizontal. This is primarily useful for converting geoms and 5 | #' statistics which display y conditional on x, to x conditional on y. 6 | #' 7 | #' @export 8 | #' @inheritParams coord_cartesian 9 | #' @examples 10 | #' # Very useful for creating boxplots, and other interval 11 | #' # geoms in the horizontal instead of vertical position. 12 | #' 13 | #' ggplot(diamonds, aes(cut, price)) + 14 | #' geom_boxplot() + 15 | #' coord_flip() 16 | #' 17 | #' h <- ggplot(diamonds, aes(carat)) + 18 | #' geom_histogram() 19 | #' h 20 | #' h + coord_flip() 21 | #' h + coord_flip() + scale_x_reverse() 22 | #' 23 | #' # You can also use it to flip line and area plots: 24 | #' df <- data.frame(x = 1:5, y = (1:5) ^ 2) 25 | #' ggplot(df, aes(x, y)) + 26 | #' geom_area() 27 | #' last_plot() + coord_flip() 28 | coord_flip <- function(xlim = NULL, ylim = NULL, expand = TRUE) { 29 | ggproto(NULL, CoordFlip, 30 | limits = list(x = xlim, y = ylim), 31 | expand = expand 32 | ) 33 | } 34 | 35 | #' @rdname ggplot2-ggproto 36 | #' @format NULL 37 | #' @usage NULL 38 | #' @export 39 | CoordFlip <- ggproto("CoordFlip", CoordCartesian, 40 | 41 | transform = function(data, scale_details) { 42 | data <- flip_labels(data) 43 | CoordCartesian$transform(data, scale_details) 44 | }, 45 | 46 | range = function(scale_details) { 47 | list(x = scale_details$y.range, y = scale_details$x.range) 48 | }, 49 | 50 | train = function(self, scale_details) { 51 | trained <- ggproto_parent(CoordCartesian, self)$train(scale_details) 52 | flip_labels(trained) 53 | }, 54 | 55 | labels = function(scale_details) { 56 | flip_labels(CoordCartesian$labels(scale_details)) 57 | } 58 | ) 59 | 60 | 61 | flip_labels <- function(x) { 62 | old_names <- names(x) 63 | 64 | new_names <- old_names 65 | new_names <- gsub("^x", "z", new_names) 66 | new_names <- gsub("^y", "x", new_names) 67 | new_names <- gsub("^z", "y", new_names) 68 | 69 | setNames(x, new_names) 70 | } 71 | -------------------------------------------------------------------------------- /man/scale_identity.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/scale-identity.r, R/zxx.r 3 | \name{scale_identity} 4 | \alias{scale_identity} 5 | \alias{scale_colour_identity} 6 | \alias{scale_fill_identity} 7 | \alias{scale_shape_identity} 8 | \alias{scale_linetype_identity} 9 | \alias{scale_alpha_identity} 10 | \alias{scale_size_identity} 11 | \alias{scale_color_identity} 12 | \title{Use values without scaling.} 13 | \usage{ 14 | scale_colour_identity(..., guide = "none") 15 | 16 | scale_fill_identity(..., guide = "none") 17 | 18 | scale_shape_identity(..., guide = "none") 19 | 20 | scale_linetype_identity(..., guide = "none") 21 | 22 | scale_alpha_identity(..., guide = "none") 23 | 24 | scale_size_identity(..., guide = "none") 25 | } 26 | \arguments{ 27 | \item{...}{Other arguments passed on to \code{\link{discrete_scale}} or 28 | \code{\link{continuous_scale}}} 29 | 30 | \item{guide}{Guide to use for this scale - defaults to \code{"none"}.} 31 | } 32 | \description{ 33 | Use values without scaling. 34 | } 35 | \examples{ 36 | ggplot(luv_colours, aes(u, v)) + 37 | geom_point(aes(colour = col), size = 3) + 38 | scale_color_identity() + 39 | coord_equal() 40 | 41 | df <- data.frame( 42 | x = 1:4, 43 | y = 1:4, 44 | colour = c("red", "green", "blue", "yellow") 45 | ) 46 | ggplot(df, aes(x, y)) + geom_tile(aes(fill = colour)) 47 | ggplot(df, aes(x, y)) + 48 | geom_tile(aes(fill = colour)) + 49 | scale_fill_identity() 50 | 51 | # To get a legend guide, specify guide = "legend" 52 | ggplot(df, aes(x, y)) + 53 | geom_tile(aes(fill = colour)) + 54 | scale_fill_identity(guide = "legend") 55 | # But you'll typically also need to supply breaks and labels: 56 | ggplot(df, aes(x, y)) + 57 | geom_tile(aes(fill = colour)) + 58 | scale_fill_identity("trt", labels = letters[1:4], breaks = df$colour, 59 | guide = "legend") 60 | 61 | # cyl scaled to appropriate size 62 | ggplot(mtcars, aes(mpg, wt)) + geom_point(aes(size = cyl)) 63 | 64 | # cyl used as point size 65 | ggplot(mtcars, aes(mpg, wt)) + 66 | geom_point(aes(size = cyl)) + 67 | scale_size_identity() 68 | } 69 | -------------------------------------------------------------------------------- /R/aes-colour-fill-alpha.r: -------------------------------------------------------------------------------- 1 | #' Colour related aesthetics: colour, fill and alpha 2 | #' 3 | #' This page demonstrates the usage of a sub-group 4 | #' of aesthetics; colour, fill and alpha. 5 | #' 6 | #' @name aes_colour_fill_alpha 7 | #' @aliases colour color fill 8 | #' @examples 9 | #' \donttest{ 10 | #' 11 | #' # Bar chart example 12 | #' c <- ggplot(mtcars, aes(factor(cyl))) 13 | #' # Default plotting 14 | #' c + geom_bar() 15 | #' # To change the interior colouring use fill aesthetic 16 | #' c + geom_bar(fill = "red") 17 | #' # Compare with the colour aesthetic which changes just the bar outline 18 | #' c + geom_bar(colour = "red") 19 | #' # Combining both, you can see the changes more clearly 20 | #' c + geom_bar(fill = "white", colour = "red") 21 | #' 22 | #' # The aesthetic fill also takes different colouring scales 23 | #' # setting fill equal to a factor variable uses a discrete colour scale 24 | #' k <- ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) 25 | #' k + geom_bar() 26 | #' 27 | #' # Fill aesthetic can also be used with a continuous variable 28 | #' m <- ggplot(faithfuld, aes(waiting, eruptions)) 29 | #' m + geom_raster() 30 | #' m + geom_raster(aes(fill = density)) 31 | #' 32 | #' # Some geoms don't use both aesthetics (i.e. geom_point or geom_line) 33 | #' b <- ggplot(economics, aes(x = date, y = unemploy)) 34 | #' b + geom_line() 35 | #' b + geom_line(colour = "green") 36 | #' b + geom_point() 37 | #' b + geom_point(colour = "red") 38 | #' 39 | #' # For large datasets with overplotting the alpha 40 | #' # aesthetic will make the points more transparent 41 | #' df <- data.frame(x = rnorm(5000), y = rnorm(5000)) 42 | #' h <- ggplot(df, aes(x,y)) 43 | #' h + geom_point() 44 | #' h + geom_point(alpha = 0.5) 45 | #' h + geom_point(alpha = 1/10) 46 | #' 47 | #' # Alpha can also be used to add shading 48 | #' j <- b + geom_line() 49 | #' j 50 | #' yrng <- range(economics$unemploy) 51 | #' j <- j + geom_rect(aes(NULL, NULL, xmin = start, xmax = end, fill = party), 52 | #' ymin = yrng[1], ymax = yrng[2], data = presidential) 53 | #' j 54 | #' j + scale_fill_manual(values = alpha(c("blue", "red"), .3)) 55 | #' } 56 | NULL 57 | -------------------------------------------------------------------------------- /man/guides.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/guides-.r 3 | \name{guides} 4 | \alias{guides} 5 | \title{Set guides for each scale.} 6 | \usage{ 7 | guides(...) 8 | } 9 | \arguments{ 10 | \item{...}{List of scale guide pairs} 11 | } 12 | \value{ 13 | A list containing the mapping between scale and guide. 14 | } 15 | \description{ 16 | Guides for each scale can be set in call of \code{scale_*} with argument 17 | \code{guide}, or in \code{guides}. 18 | } 19 | \examples{ 20 | \donttest{ 21 | # ggplot object 22 | 23 | dat <- data.frame(x = 1:5, y = 1:5, p = 1:5, q = factor(1:5), 24 | r = factor(1:5)) 25 | p <- ggplot(dat, aes(x, y, colour = p, size = q, shape = r)) + geom_point() 26 | 27 | # without guide specification 28 | p 29 | 30 | # Show colorbar guide for colour. 31 | # All these examples below have a same effect. 32 | 33 | p + guides(colour = "colorbar", size = "legend", shape = "legend") 34 | p + guides(colour = guide_colorbar(), size = guide_legend(), 35 | shape = guide_legend()) 36 | p + 37 | scale_colour_continuous(guide = "colorbar") + 38 | scale_size_discrete(guide = "legend") + 39 | scale_shape(guide = "legend") 40 | 41 | # Remove some guides 42 | p + guides(colour = "none") 43 | p + guides(colour = "colorbar",size = "none") 44 | 45 | # Guides are integrated where possible 46 | 47 | p + guides(colour = guide_legend("title"), size = guide_legend("title"), 48 | shape = guide_legend("title")) 49 | # same as 50 | g <- guide_legend("title") 51 | p + guides(colour = g, size = g, shape = g) 52 | 53 | p + theme(legend.position = "bottom") 54 | 55 | # position of guides 56 | 57 | p + theme(legend.position = "bottom", legend.box = "horizontal") 58 | 59 | # Set order for multiple guides 60 | ggplot(mpg, aes(displ, cty)) + 61 | geom_point(aes(size = hwy, colour = cyl, shape = drv)) + 62 | guides( 63 | colour = guide_colourbar(order = 1), 64 | shape = guide_legend(order = 2), 65 | size = guide_legend(order = 3) 66 | ) 67 | } 68 | } 69 | \seealso{ 70 | Other guides: \code{\link{guide_colourbar}}, 71 | \code{\link{guide_legend}} 72 | } 73 | \concept{guides} 74 | --------------------------------------------------------------------------------