├── inst ├── .gitignore ├── staticdocs │ ├── README.md │ ├── footer.html │ └── head.html └── CITATION ├── visual_test ├── .gitignore ├── alpha.r ├── coord-cartesian-with-limits.r ├── geom-polygon.r ├── guide-axis.r ├── aesthetics.r ├── scale-breaks.r ├── stat-summary.r ├── geom-path.r ├── scale-date.r ├── aspect-ratio.r ├── minor-breaks.r ├── coord-map.r └── violin.r ├── .gitattributes ├── .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 ├── tests ├── testthat.R └── testthat │ ├── test-guides.R │ ├── test-stats.r │ ├── test-boxplot.r │ ├── test-stat-density.R │ ├── test-labels.r │ ├── test-range.r │ ├── test-aes-setting.r │ ├── test-stat-density2d.R │ ├── test-qplot.r │ ├── test-stats-function.r │ ├── test-stat-bin.R │ ├── helper-plot-data.r │ ├── test-geom-text.R │ ├── test-annotate.r │ ├── test-data.r │ ├── test-stat-bin2d.R │ ├── test-facet-labels.r │ ├── test-geom-rule.R │ ├── test-layer.r │ ├── test-fortify.r │ ├── test-coord-train.r │ ├── test-aes-grouping.r │ ├── test-stat-sum.R │ ├── test-facet-.r │ ├── test-sanitise-dim.r │ ├── test-build.r │ ├── test-aes.r │ ├── test-utilities.r │ └── test-ggsave.R ├── vignettes └── car.png ├── data-raw ├── mpg.R ├── seals.R ├── msleep.R ├── midwest.R ├── presidential.R ├── luv_colours.R ├── faithfuld.R ├── diamonds.R ├── presidential.csv └── economics.R ├── R ├── ggplot2.r ├── aaa-.r ├── position-identity.r ├── geom-freqpoly.r ├── plot-last.r ├── position-fill.r ├── scale-gradientn.r ├── zzz.r ├── geom-defaults.r ├── grob-null.r ├── autoplot.r ├── geom-line.r ├── bench.r ├── fortify.r ├── range.r ├── utilities-resolution.r ├── stat-unique.r ├── scale-linetype.r ├── scale-gradient2.r ├── utilities-help.r ├── guides-grid.r ├── geom-bin2d.r ├── utilities-grid.r ├── position-nudge.R ├── grob-absolute.r ├── summary.r ├── coord-quickmap.R ├── geom-hline.r ├── geom-vline.r ├── scale-alpha.r ├── utilities-matrix.r ├── scale-shape.r ├── stat-sum.r ├── geom-pointrange.r ├── utilities-table.r ├── scale-grey.r ├── grouping.r ├── aes-calculated.r ├── facet-viewports.r ├── aes-position.r ├── geom-blank.r ├── geom-step.r ├── geom-curve.r ├── coord-fixed.r ├── geom-spoke.r ├── geom-errorbar.r ├── facet-.r ├── zxx.r └── geom-jitter.r ├── .Rbuildignore ├── man ├── is.Coord.Rd ├── zeroGrob.Rd ├── is.rel.Rd ├── is.ggproto.Rd ├── is.theme.Rd ├── ggplotGrob.Rd ├── is.ggplot.Rd ├── last_plot.Rd ├── is.facet.Rd ├── element_blank.Rd ├── alpha.Rd ├── absoluteGrob.Rd ├── aes_auto.Rd ├── faithfuld.Rd ├── ggplot2-grid.Rd ├── facet.Rd ├── mean_se.Rd ├── presidential.Rd ├── aes_all.Rd ├── should_stop.Rd ├── rel.Rd ├── graphical-units.Rd ├── luv_colours.Rd ├── waiver.Rd ├── element_line.Rd ├── position_identity.Rd ├── add_theme.Rd ├── element_rect.Rd ├── summary.ggplot.Rd ├── benchplot.Rd ├── update_labels.Rd ├── as.list.ggproto.Rd ├── fortify.Rd ├── margin.Rd ├── limits.Rd ├── facet_null.Rd ├── format.ggproto.Rd ├── update_defaults.Rd ├── autoplot.Rd ├── seals.Rd ├── txhousing.Rd ├── coord_munch.Rd ├── print.ggproto.Rd ├── hmisc.Rd ├── print.ggplot.Rd ├── resolution.Rd ├── ggplot_build.Rd ├── expand_limits.Rd ├── fortify.map.Rd ├── mpg.Rd ├── ggplot_gtable.Rd ├── position_nudge.Rd ├── calc_element.Rd ├── remove_missing.Rd ├── element_text.Rd ├── scale_linetype.Rd ├── diamonds.Rd ├── annotation_map.Rd ├── borders.Rd ├── theme_update.Rd ├── scale_alpha.Rd ├── labs.Rd ├── economics.Rd ├── lims.Rd ├── msleep.Rd ├── midwest.Rd ├── gg_dep.Rd ├── position_jitterdodge.Rd ├── coord_flip.Rd ├── scale_shape.Rd ├── fortify.sp.Rd ├── fortify-multcomp.Rd ├── draw_key.Rd ├── scale_grey.Rd ├── stat_identity.Rd ├── map_data.Rd ├── coord_fixed.Rd ├── aes.Rd ├── ggproto.Rd ├── position_jitter.Rd ├── aes_position.Rd ├── stat_unique.Rd ├── annotate.Rd ├── annotation_raster.Rd ├── position_dodge.Rd ├── layer.Rd ├── guides.Rd └── cut_interval.Rd ├── ggplot2.Rproj ├── .travis.yml ├── cran-comments.md └── README.md /inst/.gitignore: -------------------------------------------------------------------------------- 1 | web 2 | -------------------------------------------------------------------------------- /inst/staticdocs/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /visual_test/.gitignore: -------------------------------------------------------------------------------- 1 | vtest 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /NEWS merge=union 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | inst/doc 5 | -------------------------------------------------------------------------------- /data/mpg.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/mpg.rda -------------------------------------------------------------------------------- /data/seals.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/seals.rda -------------------------------------------------------------------------------- /data/midwest.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/midwest.rda -------------------------------------------------------------------------------- /data/msleep.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/msleep.rda -------------------------------------------------------------------------------- /data/diamonds.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/diamonds.rda -------------------------------------------------------------------------------- /data/economics.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/economics.rda -------------------------------------------------------------------------------- /data/faithfuld.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/faithfuld.rda -------------------------------------------------------------------------------- /data/txhousing.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/txhousing.rda -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(ggplot2) 3 | 4 | test_check("ggplot2") 5 | -------------------------------------------------------------------------------- /vignettes/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/vignettes/car.png -------------------------------------------------------------------------------- /data/luv_colours.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/luv_colours.rda -------------------------------------------------------------------------------- /data/presidential.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/presidential.rda -------------------------------------------------------------------------------- /data/economics_long.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/butchland/ggplot2/master/data/economics_long.rda -------------------------------------------------------------------------------- /data-raw/mpg.R: -------------------------------------------------------------------------------- 1 | library(readr) 2 | 3 | mpg <- read_csv("data-raw/mpg.csv") 4 | use_data(mpg, overwrite = TRUE) 5 | -------------------------------------------------------------------------------- /R/ggplot2.r: -------------------------------------------------------------------------------- 1 | #' @import scales grid gtable 2 | #' @importFrom plyr defaults 3 | #' @importFrom stats setNames 4 | NULL 5 | -------------------------------------------------------------------------------- /data-raw/seals.R: -------------------------------------------------------------------------------- 1 | library(readr) 2 | 3 | seals <- read_csv("data-raw/seals.csv") 4 | use_data(seals, overwrite = TRUE) 5 | -------------------------------------------------------------------------------- /data-raw/msleep.R: -------------------------------------------------------------------------------- 1 | library(readr) 2 | 3 | msleep <- read_csv("data-raw/msleep.csv") 4 | use_data(msleep, overwrite = TRUE) 5 | -------------------------------------------------------------------------------- /data-raw/midwest.R: -------------------------------------------------------------------------------- 1 | library(readr) 2 | 3 | midwest <- read_csv("data-raw/midwest.csv") 4 | use_data(midwest, overwrite = TRUE) 5 | -------------------------------------------------------------------------------- /data-raw/presidential.R: -------------------------------------------------------------------------------- 1 | library(readr) 2 | presidential <- read_csv("data-raw/presidential.csv") 3 | devtools::use_data(presidential, overwrite = TRUE) 4 | -------------------------------------------------------------------------------- /data-raw/luv_colours.R: -------------------------------------------------------------------------------- 1 | luv_colours <- as.data.frame(convertColor(t(col2rgb(colors())), "sRGB", "Luv")) 2 | luv_colours$col <- colors() 3 | 4 | devtools::use_data(luv_colours, overwrite = TRUE) 5 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | visual_test 2 | ^.*\.Rproj$ 3 | ^\.Rproj\.user$ 4 | ^\.travis\.yml$ 5 | ^/\.gitattributes$ 6 | ^inst/web$ 7 | ^notes$ 8 | ^cran-comments.md$ 9 | ^data-raw$ 10 | ^CONTRIBUTING\.md$ 11 | -------------------------------------------------------------------------------- /visual_test/alpha.r: -------------------------------------------------------------------------------- 1 | vcontext("Alpha") 2 | 3 | qplot(1, 1, color = I("#cc000044"), size = I(50)) 4 | save_vtest("Alpha set in colour") 5 | 6 | qplot(1, 1, color = I("#cc0000"), size = I(50), alpha = I(0.27)) 7 | save_vtest("Alpha set in alpha") 8 | 9 | end_vcontext() -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /data-raw/faithfuld.R: -------------------------------------------------------------------------------- 1 | library(dplyr) 2 | 3 | f2d <- MASS::kde2d(faithful$eruptions, faithful$waiting, h = c(1, 10), n = 75) 4 | 5 | faithfuld <- expand.grid(eruptions = f2d$x, waiting = f2d$y) %>% 6 | tbl_df() %>% 7 | mutate(density = as.vector(f2d$z)) 8 | 9 | devtools::use_data(faithfuld, overwrite = TRUE) 10 | -------------------------------------------------------------------------------- /man/is.Coord.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 14 | -------------------------------------------------------------------------------- /man/zeroGrob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 14 | -------------------------------------------------------------------------------- /man/is.rel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 16 | -------------------------------------------------------------------------------- /man/is.ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 16 | -------------------------------------------------------------------------------- /man/is.theme.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 16 | -------------------------------------------------------------------------------- /man/ggplotGrob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 17 | -------------------------------------------------------------------------------- /man/is.ggplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 17 | -------------------------------------------------------------------------------- /man/last_plot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 16 | -------------------------------------------------------------------------------- /man/is.facet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 17 | -------------------------------------------------------------------------------- /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{ggplot2::Geom}, \code{ggplot2::Stat}, 8 | #' \code{ggplot2::Position}, or \code{ggplot2::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 | -------------------------------------------------------------------------------- /visual_test/coord-cartesian-with-limits.r: -------------------------------------------------------------------------------- 1 | vcontext("coord-cartesian-with-limits") 2 | ## test codes of coord_cartesion with range specification. 3 | 4 | p <- ggplot(mtcars, aes(wt, mpg)) + geom_point() 5 | 6 | p + coord_cartesian(xlim = c(0, 10), ylim = c(0, 50)) 7 | save_vtest("expand range") 8 | 9 | p + coord_cartesian(xlim = c(2, 4), ylim = c(20, 40)) 10 | save_vtest("contract range") 11 | 12 | end_vcontext() 13 | -------------------------------------------------------------------------------- /data-raw/diamonds.R: -------------------------------------------------------------------------------- 1 | library(readr) 2 | diamonds <- read_csv("data-raw/diamonds.csv", col_types = 3 | list( 4 | cut = col_factor(c("Fair", "Good", "Very Good", "Premium", "Ideal"), TRUE), 5 | color = col_factor(c("D", "E", "F", "G", "H", "I", "J"), TRUE), 6 | clarity = col_factor(c("I1", "SI2", "SI1", "VS2", "VS1", "VVS2", "VVS1", "IF"), TRUE) 7 | ) 8 | ) 9 | 10 | devtools::use_data(diamonds, overwrite = TRUE) 11 | -------------------------------------------------------------------------------- /man/element_blank.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 15 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/alpha.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/utilities.r 3 | \name{alpha} 4 | \alias{alpha} 5 | \title{Create a transparent colour.} 6 | \description{ 7 | Create a transparent colour. 8 | } 9 | \examples{ 10 | ggplot(mpg, aes(displ, hwy)) + 11 | geom_point(alpha = 0.5, colour = "blue") 12 | 13 | ggplot(mpg, aes(displ, hwy)) + 14 | geom_point(colour = alpha("blue", 0.5)) 15 | } 16 | 17 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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://had.co.nz/ggplot2/book", 10 | textVersion = "H. Wickham. ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York, 2009." 11 | ) -------------------------------------------------------------------------------- /R/geom-freqpoly.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname geom_histogram 3 | geom_freqpoly <- function(mapping = NULL, data = NULL, stat = "bin", 4 | position = "identity", show.legend = NA, inherit.aes = TRUE, ...) 5 | { 6 | layer( 7 | data = data, 8 | mapping = mapping, 9 | stat = stat, 10 | geom = GeomPath, 11 | position = position, 12 | show.legend = show.legend, 13 | inherit.aes = inherit.aes, 14 | params = list(...) 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /man/absoluteGrob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 18 | -------------------------------------------------------------------------------- /man/aes_auto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 19 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/faithfuld.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 17 | -------------------------------------------------------------------------------- /man/ggplot2-grid.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/utilities-grid.r 3 | \name{ggplot2-grid} 4 | \alias{arrow} 5 | \alias{ggplot2-grid} 6 | \alias{unit} 7 | \title{unit & arrow functions from grid.} 8 | \description{ 9 | See \code{\link[grid]{arrow}} and \code{\link[grid]{unit}} for more details. 10 | These functions are re-exported from grid by ggplot2 since they are 11 | so commonly used. 12 | } 13 | \keyword{internal} 14 | 15 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ggplot2.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 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /man/facet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 19 | -------------------------------------------------------------------------------- /visual_test/geom-polygon.r: -------------------------------------------------------------------------------- 1 | vcontext("geom-polygon") 2 | 3 | ggplot(faithful, aes(x = eruptions, y = waiting)) + 4 | stat_density2d(aes(colour = ..level..), geom = "path") + 5 | xlim(0.5, 6) + ylim(40, 110) 6 | save_vtest("stat_density2d with paths") 7 | 8 | ggplot(faithful, aes(x = eruptions, y = waiting)) + 9 | stat_density2d(aes(fill = ..level..), geom = "polygon", colour = "white") + 10 | xlim(0.5, 6) + ylim(40, 110) 11 | save_vtest("stat_density2d with filled polygons") 12 | 13 | end_vcontext() 14 | -------------------------------------------------------------------------------- /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/mean_se.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 21 | -------------------------------------------------------------------------------- /man/presidential.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 10 presidents from Eisenhower to Bush W.} 7 | \format{A data frame with 10 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 10 US presidents from Eisenhower to Bush W. 14 | } 15 | \keyword{datasets} 16 | 17 | -------------------------------------------------------------------------------- /man/aes_all.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 21 | -------------------------------------------------------------------------------- /man/should_stop.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 21 | -------------------------------------------------------------------------------- /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/rel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 22 | -------------------------------------------------------------------------------- /man/graphical-units.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/geom-.r 3 | \docType{data} 4 | \name{graphical-units} 5 | \alias{.pt} 6 | \alias{.stroke} 7 | \alias{graphical-units} 8 | \title{Graphical units} 9 | \format{\preformatted{ num 2.85 10 | }} 11 | \usage{ 12 | .pt 13 | 14 | .stroke 15 | } 16 | \description{ 17 | Multiply size in mm by these constants in order to convert to the units 18 | that grid uses internally for \code{lwd} and \code{fontsize}. 19 | } 20 | \keyword{datasets} 21 | 22 | -------------------------------------------------------------------------------- /man/luv_colours.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 20 | -------------------------------------------------------------------------------- /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/waiver.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 17 | -------------------------------------------------------------------------------- /data-raw/presidential.csv: -------------------------------------------------------------------------------- 1 | "name","start","end","party" 2 | "Eisenhower",1953-01-20,1961-01-20,"Republican" 3 | "Kennedy",1961-01-20,1963-11-22,"Democratic" 4 | "Johnson",1963-11-22,1969-01-20,"Democratic" 5 | "Nixon",1969-01-20,1974-08-09,"Republican" 6 | "Ford",1974-08-09,1977-01-20,"Republican" 7 | "Carter",1977-01-20,1981-01-20,"Democratic" 8 | "Reagan",1981-01-20,1989-01-20,"Republican" 9 | "Bush",1989-01-20,1993-01-20,"Republican" 10 | "Clinton",1993-01-20,2001-01-20,"Democratic" 11 | "Bush",2001-01-20,2009-01-20,"Republican" 12 | "Obama",2009-01-20,2017-01-20,"Democratic" 13 | -------------------------------------------------------------------------------- /man/element_line.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 25 | -------------------------------------------------------------------------------- /man/position_identity.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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_stack}}; 16 | \code{\link{position_jitterdodge}}; 17 | \code{\link{position_jitter}}; 18 | \code{\link{position_nudge}} 19 | } 20 | 21 | -------------------------------------------------------------------------------- /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_defaults = function(self, data) { 15 | if (!all(data$ymin == 0)) 16 | warning("Filling not well defined when ymin != 0", call. = FALSE) 17 | }, 18 | 19 | compute_layer = function(data, params, scales) { 20 | collide(data, NULL, "position_fill", pos_fill) 21 | } 22 | ) 23 | -------------------------------------------------------------------------------- /man/add_theme.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 24 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/element_rect.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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, linetype = NULL, 8 | 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 | 25 | -------------------------------------------------------------------------------- /tests/testthat/test-stat-density2d.R: -------------------------------------------------------------------------------- 1 | context("stat_density2d") 2 | 3 | test_that("uses scale limits, not data limits", { 4 | base <- ggplot(mtcars, aes(wt, mpg)) + 5 | stat_density2d() + 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/summary.ggplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 24 | -------------------------------------------------------------------------------- /man/benchplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 23 | -------------------------------------------------------------------------------- /man/update_labels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 25 | -------------------------------------------------------------------------------- /man/as.list.ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 21 | -------------------------------------------------------------------------------- /man/fortify.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 25 | -------------------------------------------------------------------------------- /man/margin.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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,b,r,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 convenience 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 | 25 | -------------------------------------------------------------------------------- /man/limits.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | ggplot2:::limits(c(1, 5), "x") 19 | ggplot2:::limits(c(5, 1), "x") 20 | ggplot2:::limits(c("A", "b", "c"), "x") 21 | ggplot2:::limits(c("A", "b", "c"), "fill") 22 | ggplot2:::limits(as.Date(c("2008-01-01", "2009-01-01")), "x") 23 | } 24 | \keyword{internal} 25 | 26 | -------------------------------------------------------------------------------- /man/facet_null.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 23 | -------------------------------------------------------------------------------- /man/format.ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 22 | -------------------------------------------------------------------------------- /visual_test/guide-axis.r: -------------------------------------------------------------------------------- 1 | vcontext("guide-axis") 2 | 3 | ## align the labels for facets 4 | 5 | qplot(hwy, reorder(model, hwy), data = mpg) + 6 | facet_grid(manufacturer ~ ., scales = "free", space = "free") + 7 | theme(strip.text.y = element_text(angle = 0)) 8 | save_vtest("align facet labels, facets horizontal") 9 | 10 | qplot(reorder(model, hwy), hwy, data = mpg) + 11 | facet_grid(. ~ manufacturer, scales = "free", space = "free") + 12 | theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5)) 13 | save_vtest("align facet labels, facets vertical") 14 | 15 | qplot(wt, mpg, data = mtcars) + 16 | theme(axis.line = element_line(size = 5, lineend = "square")) 17 | save_vtest("thick axis lines") 18 | 19 | end_vcontext() 20 | -------------------------------------------------------------------------------- /R/scale-gradientn.r: -------------------------------------------------------------------------------- 1 | #' @inheritParams scales::gradient_n_pal 2 | #' @param colours Vector of colours to use for n-colour gradient. 3 | #' @rdname scale_gradient 4 | #' @export 5 | scale_colour_gradientn <- function(..., colours, values = NULL, space = "Lab", na.value = "grey50", guide = "colourbar") { 6 | continuous_scale("colour", "gradientn", 7 | gradient_n_pal(colours, values, space), na.value = na.value, guide = guide, ...) 8 | } 9 | #' @rdname scale_gradient 10 | #' @export 11 | scale_fill_gradientn <- function(..., colours, values = NULL, space = "Lab", na.value = "grey50", guide = "colourbar") { 12 | continuous_scale("fill", "gradientn", 13 | gradient_n_pal(colours, values, space), na.value = na.value, guide = guide, ...) 14 | } 15 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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(strwrap(tip)) 15 | } 16 | -------------------------------------------------------------------------------- /man/update_defaults.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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} 16 | } 17 | \description{ 18 | Modify geom/stat aesthetic defaults for future plots 19 | } 20 | \examples{ 21 | update_geom_defaults("point", list(colour = "darkblue")) 22 | ggplot(mtcars, aes(mpg, wt)) + geom_point() 23 | update_geom_defaults("point", list(colour = "black")) 24 | } 25 | 26 | -------------------------------------------------------------------------------- /man/autoplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 26 | -------------------------------------------------------------------------------- /R/geom-defaults.r: -------------------------------------------------------------------------------- 1 | #' Modify geom/stat aesthetic defaults for future plots 2 | #' 3 | #' @param stat,geom name of geom/stat to modify 4 | #' @param new named list of aesthetics 5 | #' @export 6 | #' @examples 7 | #' update_geom_defaults("point", list(colour = "darkblue")) 8 | #' ggplot(mtcars, aes(mpg, wt)) + geom_point() 9 | #' update_geom_defaults("point", list(colour = "black")) 10 | #' @rdname update_defaults 11 | update_geom_defaults <- function(geom, new) { 12 | g <- find_subclass("Geom", geom) 13 | old <- g$default_aes 14 | g$default_aes <- defaults(new, old) 15 | } 16 | 17 | #' @rdname update_defaults 18 | #' @export 19 | update_stat_defaults <- function(stat, new) { 20 | g <- find_subclass("Stat", stat) 21 | old <- g$default_aes 22 | g$default_aes <- defaults(new, old) 23 | } 24 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tests/testthat/test-stat-bin.R: -------------------------------------------------------------------------------- 1 | context("stat_bar/stat_bin") 2 | 3 | test_that("stat_bin throws error when y aesthetic present", { 4 | dat <- data.frame(x = c("a", "b", "c"), y = c(1, 5, 10)) 5 | 6 | expect_error(ggplot_build(ggplot(dat, aes(x, y)) + stat_bin()), 7 | "must not be used with a y aesthetic.") 8 | 9 | expect_error(p <- ggplot_build(ggplot(dat, aes(x)) + stat_bin(y = 5)), 10 | "Unknown parameters: y") 11 | }) 12 | 13 | test_that("stat_bar throws error when y aesthetic present", { 14 | dat <- data.frame(x = c("a", "b", "c"), y = c(1, 5, 10)) 15 | 16 | expect_error(ggplot_build(ggplot(dat, aes(x, y)) + stat_bar()), 17 | "must not be used with a y aesthetic.") 18 | 19 | expect_error(p <- ggplot_build(ggplot(dat, aes(x)) + stat_bar(y = 5)), 20 | "Unknown parameters: y") 21 | }) 22 | -------------------------------------------------------------------------------- /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/geom-line.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname geom_path 3 | geom_line <- function(mapping = NULL, data = NULL, stat = "identity", 4 | position = "identity", show.legend = NA, 5 | inherit.aes = TRUE, na.rm = TRUE, ...) { 6 | layer( 7 | data = data, 8 | mapping = mapping, 9 | stat = stat, 10 | geom = GeomLine, 11 | position = position, 12 | show.legend = show.legend, 13 | inherit.aes = inherit.aes, 14 | params = list( 15 | na.rm = na.rm, 16 | ... 17 | ) 18 | ) 19 | } 20 | 21 | #' @rdname ggplot2-ggproto 22 | #' @format NULL 23 | #' @usage NULL 24 | #' @export 25 | #' @include geom-path.r 26 | GeomLine <- ggproto("GeomLine", GeomPath, 27 | setup_data = function(data, params) { 28 | data[order(data$PANEL, data$group, data$x), ] 29 | } 30 | ) 31 | -------------------------------------------------------------------------------- /man/seals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 24 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: R 2 | sudo: required 3 | warnings_are_errors: true 4 | 5 | r_packages: 6 | - rmarkdown 7 | 8 | r_github_packages: 9 | - hadley/staticdocs 10 | - jimhester/covr 11 | 12 | before_script: 13 | - sudo Rscript -e "library(stringi); stri_install_icudt()" 14 | 15 | after_success: 16 | - Rscript -e 'covr::codecov()' 17 | 18 | before_deploy: 19 | - R -e "staticdocs::build_site(examples = TRUE)" 20 | 21 | deploy: 22 | edge: true 23 | 24 | provider: s3 25 | access_key_id: AKIAJDM6KGIZ6LSGAK4Q 26 | secret_access_key: 27 | secure: "r3vSpvVNcpvIcjWFyk+GhYG55iuhfmy3mwuQHQS2EqjT3Skd3mOojnZuRIqy60XXElK5/nfa3qt7KH0GCSd4Is28cqPwh+1PtQ0ZVXfeKefAk2whTPDI4P+rgOA+srUxZraLALap9QGmvlzJyXbqBCRdDmXUjtXKi2ONE9PrUk4=" 28 | bucket: docs.ggplot2.org 29 | skip_cleanup: true 30 | local-dir: inst/web 31 | upload-dir: dev 32 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.default <- function(model, data, ...) { 20 | 21 | stop("ggplot2 doesn't know how to deal with data of class ", class(model), call. = FALSE) 22 | } 23 | -------------------------------------------------------------------------------- /man/txhousing.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 27 | -------------------------------------------------------------------------------- /man/coord_munch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 26 | -------------------------------------------------------------------------------- /man/print.ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 24 | -------------------------------------------------------------------------------- /visual_test/aesthetics.r: -------------------------------------------------------------------------------- 1 | vcontext("Aesthetics") 2 | 3 | dat <- data.frame(xvar = letters[1:3], yvar = 7:9) 4 | 5 | ggplot(dat, aes(x = xvar, y = yvar)) + geom_bar(stat = "identity") 6 | save_vtest("stat='identity'") 7 | 8 | ggplot(dat, aes(x = xvar, y = yvar)) + geom_bar(stat = "identity", width = 0.5) 9 | save_vtest("stat='identity', width=0.5") 10 | 11 | ggplot(dat, aes(x = xvar, y = yvar)) + geom_bar(stat = "identity", aes(width = 0.5)) 12 | save_vtest("stat='identity', aes(width=0.5)") 13 | 14 | 15 | ggplot(dat, aes(x = xvar)) + geom_bar(stat = "bin") 16 | save_vtest("stat='bin'") 17 | 18 | ggplot(dat, aes(x = xvar)) + geom_bar(stat = "bin", width = 0.5) 19 | save_vtest("stat='bin', width=0.5") 20 | 21 | ggplot(dat, aes(x = xvar)) + geom_bar(stat = "bin", aes(width = 0.5)) 22 | save_vtest("stat='bin', aes(width=0.5)") 23 | 24 | #TODO: Clean these up a bit 25 | 26 | end_vcontext() 27 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/hmisc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 34 | -------------------------------------------------------------------------------- /man/print.ggplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/plot.r 3 | \name{print.ggplot} 4 | \alias{plot.ggplot} 5 | \alias{print.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 | 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 | -------------------------------------------------------------------------------- /man/resolution.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 32 | -------------------------------------------------------------------------------- /man/ggplot_build.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | \title{Build ggplot for rendering.} 7 | \usage{ 8 | ggplot_build(plot) 9 | 10 | layer_data(plot, i = 1L) 11 | } 12 | \arguments{ 13 | \item{plot}{ggplot object} 14 | } 15 | \description{ 16 | \code{ggplot_build} takes the plot object, and performs all steps necessary 17 | to produce an object that can be rendered. This function outputs two pieces: 18 | a list of data frames (one for each layer), and a panel object, which 19 | contain all information about axis limits, breaks etc. \code{layer_data} 20 | is a helper function which returns the data for a given layer. 21 | } 22 | \seealso{ 23 | \code{\link{print.ggplot}} and \code{\link{benchplot}} for 24 | for functions that contain the complete set of steps for generating 25 | a ggplot2 plot. 26 | } 27 | \keyword{internal} 28 | 29 | -------------------------------------------------------------------------------- /visual_test/scale-breaks.r: -------------------------------------------------------------------------------- 1 | vcontext("scale-breaks") 2 | dat <- data.frame(x = 1:3, y = 1:3) 3 | 4 | 5 | ggplot(dat, aes(x = x, y = y)) + geom_point() + scale_x_continuous(breaks = NULL) 6 | save_vtest("no x breaks") 7 | 8 | ggplot(dat, aes(x = x, y = y)) + geom_point() + scale_y_continuous(breaks = NULL) 9 | save_vtest("no y breaks") 10 | 11 | ggplot(dat, aes(x = 1, y = y, alpha = x)) + geom_point() + scale_alpha_continuous(breaks = NULL) 12 | save_vtest("no alpha breaks (no legend)") 13 | 14 | ggplot(dat, aes(x = 1, y = y, size = x)) + geom_point() + scale_size_continuous(breaks = NULL) 15 | save_vtest("no size breaks (no legend)") 16 | 17 | ggplot(dat, aes(x = 1, y = y, fill = x)) + geom_point(shape = 21) + scale_fill_continuous(breaks = NULL) 18 | save_vtest("no fill breaks (no legend)") 19 | 20 | ggplot(dat, aes(x = 1, y = y, colour = x)) + geom_point() + scale_colour_continuous(breaks = NULL) 21 | save_vtest("no colour breaks (no legend)") 22 | 23 | end_vcontext() 24 | -------------------------------------------------------------------------------- /visual_test/stat-summary.r: -------------------------------------------------------------------------------- 1 | vcontext("stat-summary") 2 | 3 | ggplot(mtcars, aes(x = cyl, y = mpg, colour = factor(vs))) + 4 | geom_point() + 5 | stat_summary(fun.y = mean, geom = "line", size = 2) 6 | save_vtest("summary with color and lines") 7 | 8 | # It is not possible to make this behave as expected without breaking the 9 | # summary with color and lines, because of the way grouping works with 10 | # stat_summary. 11 | ggplot(mtcars, aes(x = cyl, y = mpg)) + 12 | geom_point() + 13 | stat_summary( 14 | fun.data = mean_cl_boot, 15 | colour = "red", 16 | geom = "crossbar", 17 | width = 0.2 18 | ) 19 | save_vtest("summary with crossbars, no grouping (looks wrong)") 20 | 21 | ggplot(mtcars, aes(x = cyl, y = mpg, group = cyl)) + 22 | geom_point() + 23 | stat_summary( 24 | fun.data = mean_cl_boot, 25 | colour = "red", 26 | geom = "crossbar", 27 | width = 0.2 28 | ) 29 | save_vtest("summary with crossbars, manual grouping") 30 | 31 | end_vcontext() 32 | -------------------------------------------------------------------------------- /man/expand_limits.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 31 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /visual_test/geom-path.r: -------------------------------------------------------------------------------- 1 | vcontext("geom-path") 2 | set.seed(1) 3 | 4 | nCategory <- 5 5 | nItem <- 6 6 | df <- data.frame(category = rep(LETTERS[1:nCategory], 1, each = nItem), 7 | item = paste("Item#", rep(1:nItem, nCategory, each = 1), sep = ''), 8 | value = rep(1:nItem, nCategory, each = 1) + runif(nCategory * nItem) * 0.8) 9 | 10 | df2 <- df[c(1, 2, 7, 8, 13, 14, 3:6, 9:12, 15:nrow(df)), ] 11 | 12 | ggplot(df) + geom_path(aes(x = value, y = category, group = item)) 13 | save_vtest("lines") 14 | 15 | ggplot(df2) + geom_path(aes(x = value, y = category, group = item)) 16 | save_vtest("lines with changed data order, should have same appearance") 17 | 18 | ggplot(df) + geom_path(aes(x = value, y = category, group = item, colour = item)) 19 | save_vtest("lines, colour") 20 | 21 | ggplot(df2) + geom_path(aes(x = value, y = category, group = item, colour = item)) 22 | save_vtest("lines, colour, with changed data order, should have same appearance") 23 | 24 | end_vcontext() 25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/fortify.map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 (require("maps")) { 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 | 37 | -------------------------------------------------------------------------------- /R/stat-unique.r: -------------------------------------------------------------------------------- 1 | #' Remove duplicates. 2 | #' 3 | #' @section Aesthetics: 4 | #' \Sexpr[results=rd,stage=build]{ggplot2:::rd_aesthetics("stat", "unique")} 5 | #' 6 | #' @export 7 | #' @inheritParams stat_identity 8 | #' @examples 9 | #' ggplot(mtcars, aes(vs, am)) + geom_point(alpha = 0.1) 10 | #' ggplot(mtcars, aes(vs, am)) + geom_point(alpha = 0.1, stat="unique") 11 | stat_unique <- function(mapping = NULL, data = NULL, geom = "point", 12 | position = "identity", show.legend = NA, 13 | inherit.aes = TRUE, ...) { 14 | layer( 15 | data = data, 16 | mapping = mapping, 17 | stat = StatUnique, 18 | geom = geom, 19 | position = position, 20 | show.legend = show.legend, 21 | inherit.aes = inherit.aes, 22 | params = list(...) 23 | ) 24 | } 25 | 26 | #' @rdname ggplot2-ggproto 27 | #' @format NULL 28 | #' @usage NULL 29 | #' @export 30 | StatUnique <- ggproto("StatUnique", Stat, 31 | compute_panel = function(data, scales) unique(data) 32 | ) 33 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | This submission of ggplot2 fixes \donttest{} examples. 2 | 3 | ## Test environments 4 | * OS X, R 3.1.3 5 | * OS X, R-devel 6 | * Ubuntu 14.04, R 3.1.3 7 | * win-builder (devel and release) 8 | 9 | ## R CMD check results 10 | 11 | There were no ERRORs or WARNINGs in R 3.1.3. On R-devel with --as-cran, there was also this NOTE: 12 | 13 | Found the following (possibly) invalid URLs: 14 | URL: http://fueleconomy.gov 15 | From: man/mpg.Rd 16 | Status: 404 17 | Message: Not Found 18 | 19 | This URL is accessible through a web browser, though apparently not via R CMD check. 20 | 21 | 22 | On R-devel for Windows x64, the tests hung and did not complete. We encountered some similar strange errors in our local testing, until we rebuilt and reinstalled packages from source. After doing that, the R CMD CHECK passed as above without problems. 23 | 24 | ## Downstream dependencies 25 | We did not run checks on downstream dependencies, because there were no behaviour modifying changes to the code. 26 | 27 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/mpg.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 32 | -------------------------------------------------------------------------------- /man/ggplot_gtable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 31 | -------------------------------------------------------------------------------- /man/position_nudge.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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_stack}}; 34 | \code{\link{position_identity}}; 35 | \code{\link{position_jitterdodge}}; 36 | \code{\link{position_jitter}} 37 | } 38 | 39 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /data-raw/economics.R: -------------------------------------------------------------------------------- 1 | # Download from http://research.stlouisfed.org 2 | 3 | library(readr) 4 | library(dplyr) 5 | library(purrr) 6 | library(tidyr) 7 | library(dplyr) 8 | 9 | series <- c("PCE", "POP", "PSAVERT", "UEMPMED", "UNEMPLOY") 10 | url <- paste0("http://research.stlouisfed.org/fred2/series/", series, "/downloaddata/", series, ".csv") 11 | 12 | fields <- lapply(url, read_csv) 13 | 14 | economics <- fields %>% 15 | map2(tolower(series), function(x, series) setNames(x, c("date", series))) %>% 16 | reduce(inner_join, by = "date") %>% 17 | mutate(date = structure(date, class = "Date")) # Not sure why this is lost 18 | 19 | write.csv(economics, "data-raw/economics.csv", row.names = FALSE, quote = FALSE) 20 | devtools::use_data(economics, overwrite = TRUE) 21 | 22 | rescale01 <- function(x) (x - min(x)) / diff(range(x)) 23 | economics_long <- economics %>% 24 | gather(variable, value, -date) %>% 25 | group_by(variable) %>% 26 | mutate(value01 = rescale01(value)) %>% 27 | ungroup() 28 | 29 | devtools::use_data(economics_long, overwrite = TRUE) 30 | -------------------------------------------------------------------------------- /man/calc_element.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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/remove_missing.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 30 | -------------------------------------------------------------------------------- /README.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 | -------------------------------------------------------------------------------- /man/element_text.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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, size = NULL, 8 | hjust = NULL, vjust = NULL, angle = NULL, lineheight = NULL, 9 | color = NULL, margin = 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 | \description{ 35 | Theme element: text. 36 | } 37 | 38 | -------------------------------------------------------------------------------- /R/scale-gradient2.r: -------------------------------------------------------------------------------- 1 | #' @inheritParams scales::div_gradient_pal 2 | #' @param midpoint The midpoint (in data value) of the diverging scale. 3 | #' Defaults to 0. 4 | #' @rdname scale_gradient 5 | #' @export 6 | scale_colour_gradient2 <- function(..., low = muted("red"), mid = "white", high = muted("blue"), midpoint = 0, space = "Lab", na.value = "grey50", guide = "colourbar") { 7 | continuous_scale("colour", "gradient2", 8 | div_gradient_pal(low, mid, high, space), na.value = na.value, guide = guide, ..., 9 | rescaler = mid_rescaler(mid = midpoint)) 10 | } 11 | 12 | #' @rdname scale_gradient 13 | #' @export 14 | scale_fill_gradient2 <- function(..., low = muted("red"), mid = "white", high = muted("blue"), midpoint = 0, space = "Lab", na.value = "grey50", guide = "colourbar") { 15 | continuous_scale("fill", "gradient2", 16 | div_gradient_pal(low, mid, high, space), na.value = na.value, guide = guide, ..., 17 | rescaler = mid_rescaler(mid = midpoint)) 18 | } 19 | 20 | mid_rescaler <- function(mid) { 21 | function(x, to = c(0, 1), from = range(x, na.rm = TRUE)) { 22 | rescale_mid(x, to, from, mid) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /man/scale_linetype.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 35 | -------------------------------------------------------------------------------- /man/diamonds.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 30 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /visual_test/scale-date.r: -------------------------------------------------------------------------------- 1 | vcontext("scale-date") 2 | 3 | set.seed(321) 4 | df <- data.frame( 5 | dx = seq(as.Date("2012-02-29"), len = 100, by = "1 day")[sample(100, 50)], 6 | price = runif(50) 7 | ) 8 | df <- df[order(df$dx), ] 9 | 10 | dt <- qplot(dx, price, data = df, geom = "line") 11 | dt 12 | save_vtest("dates along x, default breaks") 13 | dt + scale_x_date(breaks = date_breaks("2 weeks")) 14 | save_vtest("scale_x_date(breaks = date_breaks(\"2 weeks\"))") 15 | dt + scale_x_date(breaks = "3 weeks") 16 | save_vtest("scale_x_date(breaks = \"3 weeks\")") 17 | 18 | dt + scale_x_date(labels = date_format("%m/%d")) 19 | save_vtest("scale_x_date(labels = date_format(\"%m/%d\"))") 20 | 21 | dt + scale_x_date(labels = date_format("%W"), "week") 22 | save_vtest("scale_x_date(labels = date_format(\"%W\"), \"week\")") 23 | 24 | dt <- qplot(price, dx, data = df, geom = "line") 25 | dt 26 | save_vtest("dates along y, default breaks") 27 | dt + scale_y_date(breaks = date_breaks("2 weeks")) 28 | save_vtest("scale_y_date(breaks = date_breaks(\"2 weeks\"))") 29 | dt + scale_y_date(breaks = "3 weeks") 30 | save_vtest("scale_y_date(breaks = \"3 weeks\")") 31 | 32 | end_vcontext() 33 | -------------------------------------------------------------------------------- /inst/staticdocs/head.html: -------------------------------------------------------------------------------- 1 | 2 | {{pagetitle}}. {{#package}}{{package}} {{version}}{{/package}} 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 28 | -------------------------------------------------------------------------------- /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/geom-bin2d.r: -------------------------------------------------------------------------------- 1 | #' Add heatmap of 2d bin counts. 2 | #' 3 | #' @section Aesthetics: 4 | #' \Sexpr[results=rd,stage=build]{ggplot2:::rd_aesthetics("stat", "bin2d")} 5 | #' 6 | #' @export 7 | #' @inheritParams geom_point 8 | #' @param geom,stat Use to override the default connection between 9 | #' \code{geom_bin2d} and \code{stat_bin2d}. 10 | #' @seealso \code{\link{stat_binhex}} for hexagonal binning 11 | #' @examples 12 | #' d <- ggplot(diamonds, aes(x, y)) + xlim(4, 10) + ylim(4, 10) 13 | #' d + geom_bin2d() 14 | #' 15 | #' # You can control the size of the bins by specifying the number of 16 | #' # bins in each direction: 17 | #' d + geom_bin2d(bins = 10) 18 | #' d + geom_bin2d(bins = 30) 19 | #' 20 | #' # Or by specifying the width of the bins 21 | #' d + geom_bin2d(binwidth = c(0.1, 0.1)) 22 | geom_bin2d <- function(mapping = NULL, data = NULL, stat = "bin2d", 23 | position = "identity", show.legend = NA, inherit.aes = TRUE, ...) { 24 | 25 | layer( 26 | data = data, 27 | mapping = mapping, 28 | stat = stat, 29 | geom = GeomTile, 30 | position = position, 31 | show.legend = show.legend, 32 | inherit.aes = inherit.aes, 33 | params = list(...) 34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /R/utilities-grid.r: -------------------------------------------------------------------------------- 1 | #' unit & arrow functions from grid. 2 | #' 3 | #' See \code{\link[grid]{arrow}} and \code{\link[grid]{unit}} for more details. 4 | #' These functions are re-exported from grid by ggplot2 since they are 5 | #' so commonly used. 6 | #' 7 | #' @name ggplot2-grid 8 | #' @export unit arrow 9 | #' @aliases unit arrow 10 | #' @keywords internal 11 | NULL 12 | 13 | # Name ggplot grid object 14 | # Convenience function to name grid objects 15 | # 16 | # @keyword internal 17 | ggname <- function(prefix, grob) { 18 | grob$name <- grobName(grob, prefix) 19 | grob 20 | } 21 | 22 | width_cm <- function(x) { 23 | if (is.grob(x)) { 24 | convertWidth(grobWidth(x), "cm", TRUE) 25 | } else if (is.list(x)) { 26 | vapply(x, width_cm, numeric(1)) 27 | } else if (is.unit(x)) { 28 | convertWidth(x, "cm", TRUE) 29 | } else { 30 | stop("Unknown input") 31 | } 32 | } 33 | height_cm <- function(x) { 34 | if (is.grob(x)) { 35 | convertWidth(grobHeight(x), "cm", TRUE) 36 | } else if (is.list(x)) { 37 | vapply(x, height_cm, numeric(1)) 38 | } else if (is.unit(x)) { 39 | convertHeight(x, "cm", TRUE) 40 | } else { 41 | stop("Unknown input") 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /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 = NULL, 35 | y = NULL, 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, scales) { 44 | transform_position(data, function(x) x + params$x, function(y) y + params$y) 45 | } 46 | ) 47 | -------------------------------------------------------------------------------- /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), tol = 1e-7) 12 | expect_equal(out$xmax, c(1.25, 2), tol = 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 (4.1.1): 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 (require("maps")) { 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 | 38 | -------------------------------------------------------------------------------- /visual_test/aspect-ratio.r: -------------------------------------------------------------------------------- 1 | vcontext("aspect-ratio") 2 | 3 | p <- ggplot(data.frame(x = 1:8, y = 1:8, f = gl(2,4), expand.grid(f1 = 1:2, f2 = 1:2, rep = 1:2)), aes(x, y)) + geom_point() 4 | 5 | p + theme(aspect.ratio = 3) 6 | save_vtest("height is 3 times width") 7 | p + facet_wrap(~f) + theme(aspect.ratio = 3) 8 | save_vtest("height is 3 times width, 2 wrap facets") 9 | p + facet_grid(.~f) + theme(aspect.ratio = 3) 10 | save_vtest("height is 3 times width, 2 column facets") 11 | p + facet_grid(f~.) + theme(aspect.ratio = 3) 12 | save_vtest("height is 3 times width, 2 row facets") 13 | p + facet_grid(f1~f2) + theme(aspect.ratio = 3) 14 | save_vtest("height is 3 times width, 2x2 facets") 15 | 16 | 17 | p + theme(aspect.ratio = 1/3) 18 | save_vtest("width is 3 times height") 19 | p + facet_wrap(~f) + theme(aspect.ratio = 1/3) 20 | save_vtest("width is 3 times height, 2 wrap facets") 21 | p + facet_grid(.~f) + theme(aspect.ratio = 1/3) 22 | save_vtest("width is 3 times height, 2 column facets") 23 | p + facet_grid(f~.) + theme(aspect.ratio = 1/3) 24 | save_vtest("width is 3 times height, 2 row facets") 25 | p + facet_grid(f1~f2) + theme(aspect.ratio = 1/3) 26 | save_vtest("width is 3 times height, 2x2 facets") 27 | 28 | end_vcontext() 29 | -------------------------------------------------------------------------------- /man/borders.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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, colour = "grey50", 8 | ...) 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{...}{other arguments passed onto \code{\link{geom_polygon}}} 20 | } 21 | \description{ 22 | Create a layer of map borders. 23 | } 24 | \examples{ 25 | if (require("maps")) { 26 | 27 | ia <- map_data("county", "iowa") 28 | mid_range <- function(x) mean(range(x)) 29 | seats <- plyr::ddply(ia, "subregion", plyr::colwise(mid_range, c("lat", "long"))) 30 | ggplot(ia, aes(long, lat)) + 31 | geom_polygon(aes(group = group), fill = NA, colour = "grey60") + 32 | geom_text(aes(label = subregion), data = seats, size = 2, angle = 45) 33 | 34 | data(us.cities) 35 | capitals <- subset(us.cities, capital == 2) 36 | ggplot(capitals, aes(long, lat)) + 37 | borders("state") + 38 | geom_point(aes(size = pop)) + 39 | scale_size_area() 40 | 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /man/theme_update.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/theme.r 3 | \name{theme_update} 4 | \alias{theme_get} 5 | \alias{theme_set} 6 | \alias{theme_update} 7 | \title{Get, set and update themes.} 8 | \usage{ 9 | theme_update(...) 10 | 11 | theme_get() 12 | 13 | theme_set(new) 14 | } 15 | \arguments{ 16 | \item{...}{named list of theme settings} 17 | 18 | \item{new}{new theme (a list of theme elements)} 19 | } 20 | \description{ 21 | Use \code{theme_update} to modify a small number of elements of the current 22 | theme or use \code{theme_set} to completely override it. 23 | } 24 | \examples{ 25 | p <- ggplot(mtcars, aes(mpg, wt)) + 26 | geom_point() 27 | p 28 | old <- theme_set(theme_bw()) 29 | p 30 | theme_set(old) 31 | p 32 | 33 | old <- theme_update(panel.background = element_rect(colour = "pink")) 34 | p 35 | theme_set(old) 36 | theme_get() 37 | 38 | ggplot(mtcars, aes(mpg, wt)) + 39 | geom_point(aes(color = mpg)) + 40 | theme(legend.position = c(0.95, 0.95), 41 | legend.justification = c(1, 1)) 42 | last_plot() + 43 | theme(legend.background = element_rect(fill = "white", colour = "white", size = 3)) 44 | } 45 | \seealso{ 46 | \code{\link{\%+replace\%}} and \code{\link{+.gg}} 47 | } 48 | 49 | -------------------------------------------------------------------------------- /man/scale_alpha.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 39 | -------------------------------------------------------------------------------- /man/labs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/labels.r 3 | \name{labs} 4 | \alias{ggtitle} 5 | \alias{labs} 6 | \alias{xlab} 7 | \alias{ylab} 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 | 47 | -------------------------------------------------------------------------------- /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/economics.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 34 | -------------------------------------------------------------------------------- /R/coord-quickmap.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname coord_map 3 | coord_quickmap <- function(xlim = NULL, ylim = NULL, expand = TRUE) { 4 | ggproto(NULL, CoordQuickmap, 5 | limits = list(x = xlim, y = ylim), 6 | expand = expand 7 | ) 8 | } 9 | 10 | #' @rdname ggplot2-ggproto 11 | #' @format NULL 12 | #' @usage NULL 13 | #' @export 14 | CoordQuickmap <- ggproto("CoordQuickmap", CoordCartesian, 15 | 16 | aspect = function(ranges) { 17 | # compute coordinates of center point of map 18 | x.center <- sum(ranges$x.range) / 2 19 | y.center <- sum(ranges$y.range) / 2 20 | 21 | # compute distance corresponding to 1 degree in either direction 22 | # from the center 23 | x.dist <- dist_central_angle(x.center + c(-0.5, 0.5), rep(y.center, 2)) 24 | y.dist <- dist_central_angle(rep(x.center, 2), y.center + c(-0.5, 0.5)) 25 | # NB: this makes the projection correct in the center of the plot and 26 | # increasingly less correct towards the edges. For regions of reasonnable 27 | # size, this seems to give better results than computing this ratio from 28 | # the total lat and lon span. 29 | 30 | # scale the plot with this aspect ratio 31 | ratio <- y.dist / x.dist 32 | 33 | diff(ranges$y.range) / diff(ranges$x.range) * ratio 34 | } 35 | ) 36 | -------------------------------------------------------------------------------- /tests/testthat/test-facet-labels.r: -------------------------------------------------------------------------------- 1 | context("Facet Labels") 2 | 3 | test_that("labellers handle facet labels properly", { 4 | labels <- list(var1 = letters[1:2], var2 = letters[3:4]) 5 | 6 | expect_identical(label_value(labels), labels) 7 | expect_identical(label_value(labels, FALSE), list(c("a, c", "b, d"))) 8 | 9 | expect_identical(label_both(labels), list(c("var1: a", "var1: b"), c("var2: c", "var2: d"))) 10 | expect_identical(label_both(labels, FALSE), list(c("var1, var2: a, c", "var1, var2: b, d"))) 11 | }) 12 | 13 | test_that("labellers handle plotmath expressions", { 14 | labels <- list(var1 = c("alpha", "beta"), var2 = letters[3:4]) 15 | 16 | expected_parsed <- list( 17 | list(expression(alpha), expression(beta)), 18 | list(expression(c), expression(d)) 19 | ) 20 | expect_identical(label_parsed(labels), expected_parsed) 21 | 22 | expected_parsed_multi <- list(list( 23 | expression(list(alpha, c)), 24 | expression(list(beta, d)) 25 | )) 26 | expect_identical(label_parsed(labels, FALSE), expected_parsed_multi) 27 | }) 28 | 29 | test_that("label_value() handles factors", { 30 | labels_chr <- list(var1 = letters[1:2], var2 = letters[3:4]) 31 | labels <- lapply(labels_chr, factor) 32 | 33 | expect_identical(label_value(labels), labels_chr) 34 | }) 35 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/lims.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 50 | -------------------------------------------------------------------------------- /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, show.legend = NA, 7 | yintercept, ...) { 8 | 9 | # Act like an annotation 10 | if (!missing(yintercept)) { 11 | data <- data.frame(yintercept = yintercept) 12 | mapping <- aes(yintercept = yintercept) 13 | show.legend <- FALSE 14 | } 15 | 16 | layer( 17 | data = data, 18 | mapping = mapping, 19 | stat = StatIdentity, 20 | geom = GeomHline, 21 | position = PositionIdentity, 22 | show.legend = show.legend, 23 | inherit.aes = FALSE, 24 | params = list(...) 25 | ) 26 | } 27 | 28 | #' @rdname ggplot2-ggproto 29 | #' @format NULL 30 | #' @usage NULL 31 | #' @export 32 | GeomHline <- ggproto("GeomHline", Geom, 33 | draw_panel = function(data, panel_scales, coord) { 34 | ranges <- coord$range(panel_scales) 35 | 36 | data$x <- ranges$x[1] 37 | data$xend <- ranges$x[2] 38 | data$y <- data$yintercept 39 | data$yend <- data$yintercept 40 | 41 | GeomSegment$draw_panel(unique(data), panel_scales, coord) 42 | }, 43 | 44 | default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA), 45 | required_aes = "yintercept", 46 | 47 | draw_key = draw_key_path 48 | ) 49 | -------------------------------------------------------------------------------- /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, show.legend = NA, 7 | xintercept, ...) { 8 | 9 | # Act like an annotation 10 | if (!missing(xintercept)) { 11 | data <- data.frame(xintercept = xintercept) 12 | mapping <- aes(xintercept = xintercept) 13 | show.legend <- FALSE 14 | } 15 | 16 | layer( 17 | data = data, 18 | mapping = mapping, 19 | stat = StatIdentity, 20 | geom = GeomVline, 21 | position = PositionIdentity, 22 | show.legend = show.legend, 23 | inherit.aes = FALSE, 24 | params = list(...) 25 | ) 26 | } 27 | 28 | #' @rdname ggplot2-ggproto 29 | #' @format NULL 30 | #' @usage NULL 31 | #' @export 32 | GeomVline <- ggproto("GeomVline", Geom, 33 | draw_panel = function(data, panel_scales, coord) { 34 | ranges <- coord$range(panel_scales) 35 | 36 | data$x <- data$xintercept 37 | data$xend <- data$xintercept 38 | data$y <- ranges$y[1] 39 | data$yend <- ranges$y[2] 40 | 41 | GeomSegment$draw_panel(unique(data), panel_scales, coord) 42 | }, 43 | 44 | default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA), 45 | required_aes = "xintercept", 46 | 47 | draw_key = draw_key_vline 48 | ) 49 | -------------------------------------------------------------------------------- /man/msleep.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 37 | -------------------------------------------------------------------------------- /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/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 | scale_shape_discrete <- scale_shape 34 | 35 | #' @rdname scale_shape 36 | #' @export 37 | scale_shape_continuous <- function(...) { 38 | stop("A continuous variable can not be mapped to shape", call. = FALSE) 39 | } 40 | -------------------------------------------------------------------------------- /R/stat-sum.r: -------------------------------------------------------------------------------- 1 | #' @inheritParams stat_identity 2 | #' @section Computed variables: 3 | #' \describe{ 4 | #' \item{n}{number of observations at position} 5 | #' \item{prop}{percent of points in that panel at that position} 6 | #' } 7 | #' @export 8 | #' @rdname geom_count 9 | stat_sum <- function(mapping = NULL, data = NULL, geom = "point", 10 | position = "identity", show.legend = NA, 11 | inherit.aes = TRUE, ...) { 12 | layer( 13 | data = data, 14 | mapping = mapping, 15 | stat = StatSum, 16 | geom = geom, 17 | position = position, 18 | show.legend = show.legend, 19 | inherit.aes = inherit.aes, 20 | params = list(...) 21 | ) 22 | } 23 | 24 | #' @rdname ggplot2-ggproto 25 | #' @format NULL 26 | #' @usage NULL 27 | #' @export 28 | StatSum <- ggproto("StatSum", Stat, 29 | default_aes = aes(size = ..n..), 30 | 31 | required_aes = c("x", "y"), 32 | 33 | compute_panel = function(data, scales) { 34 | if (is.null(data$weight)) data$weight <- 1 35 | 36 | group_by <- setdiff(intersect(names(data), .all_aesthetics), "weight") 37 | 38 | counts <- plyr::count(data, group_by, wt_var = "weight") 39 | counts <- plyr::rename(counts, c(freq = "n"), warn_missing = FALSE) 40 | counts$prop <- stats::ave(counts$n, counts$group, FUN = prop.table) 41 | counts 42 | } 43 | ) 44 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /R/geom-pointrange.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname geom_linerange 3 | geom_pointrange <- function(mapping = NULL, data = NULL, stat = "identity", 4 | position = "identity", show.legend = NA, 5 | inherit.aes = TRUE, fatten = 4, ...) { 6 | layer( 7 | data = data, 8 | mapping = mapping, 9 | stat = stat, 10 | geom = GeomPointrange, 11 | position = position, 12 | show.legend = show.legend, 13 | inherit.aes = inherit.aes, 14 | params = list(..., fatten = fatten) 15 | ) 16 | } 17 | 18 | #' @rdname ggplot2-ggproto 19 | #' @format NULL 20 | #' @usage NULL 21 | #' @export 22 | GeomPointrange <- ggproto("GeomPointrange", Geom, 23 | default_aes = aes(colour = "black", size = 0.5, linetype = 1, shape = 19, 24 | fill = NA, alpha = NA, stroke = 1), 25 | 26 | draw_key = draw_key_pointrange, 27 | 28 | required_aes = c("x", "y", "ymin", "ymax"), 29 | 30 | draw_panel = function(data, panel_scales, coord, fatten = 4) { 31 | if (is.null(data$y)) 32 | return(GeomLinerange$draw_panel(data, panel_scales, coord)) 33 | 34 | ggname("geom_pointrange", 35 | gTree(children = gList( 36 | GeomLinerange$draw_panel(data, panel_scales, coord), 37 | GeomPoint$draw_panel(transform(data, size = size * fatten), panel_scales, coord) 38 | )) 39 | ) 40 | } 41 | ) 42 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/midwest.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 46 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/gg_dep.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 38 | -------------------------------------------------------------------------------- /man/position_jitterdodge.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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_stack}}; 34 | \code{\link{position_identity}}; 35 | \code{\link{position_jitter}}; 36 | \code{\link{position_nudge}} 37 | } 38 | 39 | -------------------------------------------------------------------------------- /man/coord_flip.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 44 | -------------------------------------------------------------------------------- /man/scale_shape.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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_continuous} 6 | \alias{scale_shape_discrete} 7 | \title{Scale for shapes, aka glyphs.} 8 | \usage{ 9 | scale_shape(..., solid = TRUE) 10 | 11 | scale_shape_discrete(..., solid = TRUE) 12 | 13 | scale_shape_continuous(...) 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{solid}{Are the shapes solid, \code{TRUE}, or hollow \code{FALSE}?} 21 | } 22 | \description{ 23 | A continuous variable can not be mapped to shape. 24 | } 25 | \examples{ 26 | dsmall <- diamonds[sample(nrow(diamonds), 100), ] 27 | 28 | (d <- ggplot(dsmall, aes(carat, price)) + geom_point(aes(shape = cut))) 29 | d + scale_shape(solid = TRUE) # the default 30 | d + scale_shape(solid = FALSE) 31 | d + scale_shape(name = "Cut of diamond") 32 | d + scale_shape(name = "Cut of\\ndiamond") 33 | 34 | # To change order of levels, change order of 35 | # underlying factor 36 | levels(dsmall$cut) <- c("Fair", "Good", "Very Good", "Premium", "Ideal") 37 | 38 | # Need to recreate plot to pick up new data 39 | ggplot(dsmall, aes(price, carat)) + geom_point(aes(shape = cut)) 40 | 41 | # Or for short: 42 | d \%+\% dsmall 43 | } 44 | 45 | -------------------------------------------------------------------------------- /visual_test/minor-breaks.r: -------------------------------------------------------------------------------- 1 | vcontext("minor-breaks") 2 | p <- ggplot(NULL, aes(1:3, 1:3)) + geom_point() + 3 | scale_x_continuous(breaks = 1:3, minor_breaks = c(1.25, 2.75)) + 4 | scale_y_continuous(breaks = 1:3, minor_breaks = c(1.25, 2.75)) 5 | 6 | p 7 | save_vtest("manual minor breaks") 8 | p + coord_polar() 9 | save_vtest("manual minor breaks with coord_polar") 10 | 11 | 12 | set.seed(342) 13 | df <- data.frame( 14 | date = seq(as.Date("2012-2-29"), len = 100, by = "1 day")[sample(100, 50)], 15 | price = runif(50) 16 | ) 17 | df <- df[order(df$date), ] 18 | library(scales) 19 | p <- qplot(date, price, data = df, geom = "line") + 20 | scale_x_date( 21 | labels = date_format("%m/%d"), 22 | breaks = date_breaks("month"), 23 | minor_breaks = date_breaks("week") 24 | ) 25 | 26 | p 27 | save_vtest("major breaks: months, minor breaks: weeks") 28 | 29 | p + coord_polar() 30 | save_vtest("major breaks: months, minor breaks: weeks, with coord_polar") 31 | 32 | ggplot(NULL, aes(letters[1:3], 1:3)) + geom_point() 33 | save_vtest("default breaks") 34 | 35 | qplot(1:1e4, 1:1e4) + scale_x_continuous(trans = log2_trans()) + scale_y_log10() 36 | save_vtest("scale_x_continuous(trans = log2_trans()) + scale_y_log10") 37 | 38 | qplot(1:5, 1:5) + scale_x_continuous(trans = exp_trans(2)) + scale_y_continuous(trans = exp_trans(2)) 39 | save_vtest("scale_x_continuous(trans = exp_trans(2)) + scale_y_continuous(trans = exp_trans(2))") 40 | 41 | end_vcontext() 42 | -------------------------------------------------------------------------------- /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 | expect_false(any_NA_major_minor(coord_map()$train(scales))) 35 | }) 36 | -------------------------------------------------------------------------------- /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-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/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 | -------------------------------------------------------------------------------- /man/fortify.sp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/fortify-spatial.r 3 | \name{fortify.sp} 4 | \alias{fortify.Line} 5 | \alias{fortify.Lines} 6 | \alias{fortify.Polygon} 7 | \alias{fortify.Polygons} 8 | \alias{fortify.SpatialLinesDataFrame} 9 | \alias{fortify.SpatialPolygons} 10 | \alias{fortify.SpatialPolygonsDataFrame} 11 | \alias{fortify.sp} 12 | \title{Fortify method for classes from the sp package.} 13 | \usage{ 14 | \method{fortify}{SpatialPolygonsDataFrame}(model, data, region = NULL, ...) 15 | 16 | \method{fortify}{SpatialPolygons}(model, data, ...) 17 | 18 | \method{fortify}{Polygons}(model, data, ...) 19 | 20 | \method{fortify}{Polygon}(model, data, ...) 21 | 22 | \method{fortify}{SpatialLinesDataFrame}(model, data, ...) 23 | 24 | \method{fortify}{Lines}(model, data, ...) 25 | 26 | \method{fortify}{Line}(model, data, ...) 27 | } 28 | \arguments{ 29 | \item{model}{\code{SpatialPolygonsDataFrame} to convert into a dataframe.} 30 | 31 | \item{data}{not used by this method} 32 | 33 | \item{region}{name of variable used to split up regions} 34 | 35 | \item{...}{not used by this method} 36 | } 37 | \description{ 38 | To figure out the correct variable name for region, inspect 39 | \code{as.data.frame(model)}. 40 | } 41 | \examples{ 42 | if (require("maptools")) { 43 | sids <- system.file("shapes/sids.shp", package="maptools") 44 | nc1 <- readShapePoly(sids, 45 | proj4string = CRS("+proj=longlat +datum=NAD27")) 46 | nc1_df <- fortify(nc1) 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 | -------------------------------------------------------------------------------- /man/fortify-multcomp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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.cld} 6 | \alias{fortify.confint.glht} 7 | \alias{fortify.glht} 8 | \alias{fortify.summary.glht} 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 | 52 | -------------------------------------------------------------------------------- /man/draw_key.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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_abline} 6 | \alias{draw_key_blank} 7 | \alias{draw_key_boxplot} 8 | \alias{draw_key_crossbar} 9 | \alias{draw_key_dotplot} 10 | \alias{draw_key_label} 11 | \alias{draw_key_path} 12 | \alias{draw_key_point} 13 | \alias{draw_key_pointrange} 14 | \alias{draw_key_polygon} 15 | \alias{draw_key_rect} 16 | \alias{draw_key_smooth} 17 | \alias{draw_key_text} 18 | \alias{draw_key_vline} 19 | \title{Key drawing functions} 20 | \usage{ 21 | draw_key_point(data, params) 22 | 23 | draw_key_abline(data, params) 24 | 25 | draw_key_rect(data, params) 26 | 27 | draw_key_polygon(data, params) 28 | 29 | draw_key_blank(data, params) 30 | 31 | draw_key_boxplot(data, params) 32 | 33 | draw_key_crossbar(data, params) 34 | 35 | draw_key_path(data, params) 36 | 37 | draw_key_dotplot(data, params) 38 | 39 | draw_key_pointrange(data, params) 40 | 41 | draw_key_smooth(data, params) 42 | 43 | draw_key_text(data, params) 44 | 45 | draw_key_label(data, params) 46 | 47 | draw_key_vline(data, params) 48 | } 49 | \arguments{ 50 | \item{data}{A single row data frame containing the scaled aesthetics to 51 | display in this key} 52 | 53 | \item{params}{A list of additional parameters supplied to the geom.} 54 | } 55 | \value{ 56 | A grid grob. 57 | } 58 | \description{ 59 | Each Geom has an associated function that draws the key when the geom needs 60 | to be displayed in a legend. These are the options built into ggplot2. 61 | } 62 | \keyword{internal} 63 | 64 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/scale_grey.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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_color_grey} 5 | \alias{scale_colour_grey} 6 | \alias{scale_fill_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}{gray value at low end of palette} 18 | 19 | \item{end}{gray 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 | 50 | -------------------------------------------------------------------------------- /man/stat_identity.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/stat-identity.r 3 | \name{stat_identity} 4 | \alias{stat_identity} 5 | \title{Identity statistic.} 6 | \usage{ 7 | stat_identity(mapping = NULL, data = NULL, geom = "point", 8 | position = "identity", show.legend = NA, inherit.aes = TRUE, ...) 9 | } 10 | \arguments{ 11 | \item{mapping}{The aesthetic mapping, usually constructed with 12 | \code{\link{aes}} or \code{\link{aes_string}}. Only needs to be set 13 | at the layer level if you are overriding the plot defaults.} 14 | 15 | \item{data}{A layer specific dataset - only needed if you want to override 16 | the plot defaults.} 17 | 18 | \item{geom}{The geometric object to use display the data} 19 | 20 | \item{position}{The position adjustment to use for overlapping points 21 | on this layer} 22 | 23 | \item{show.legend}{logical. Should this layer be included in the legends? 24 | \code{NA}, the default, includes if any aesthetics are mapped. 25 | \code{FALSE} never includes, and \code{TRUE} always includes.} 26 | 27 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 28 | rather than combining with them. This is most useful for helper functions 29 | that define both data and aesthetics and shouldn't inherit behaviour from 30 | the default plot specification, e.g. \code{\link{borders}}.} 31 | 32 | \item{...}{other arguments passed on to \code{\link{layer}}. This can 33 | include aesthetics whose values you want to set, not map. See 34 | \code{\link{layer}} for more details.} 35 | } 36 | \description{ 37 | The identity statistic leaves the data unchanged. 38 | } 39 | \keyword{internal} 40 | 41 | -------------------------------------------------------------------------------- /man/map_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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")) { 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 | 47 | -------------------------------------------------------------------------------- /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/coord_fixed.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/coord-fixed.r 3 | \name{coord_fixed} 4 | \alias{coord_equal} 5 | \alias{coord_fixed} 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 | 42 | -------------------------------------------------------------------------------- /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 geom_point 8 | #' @examples 9 | #' ggplot(mtcars, aes(wt, mpg)) + geom_blank() 10 | #' # Nothing to see here! 11 | #' 12 | #' # Take the following scatter plot 13 | #' a <- ggplot(mtcars, aes(x = wt, y = mpg), . ~ cyl) + geom_point() 14 | #' # Add to that some lines with geom_abline() 15 | #' df <- data.frame(a = rnorm(10, 25), b = rnorm(10, 0)) 16 | #' a + geom_abline(aes(intercept = a, slope = b), data = df) 17 | #' # Suppose you then wanted to remove the geom_point layer 18 | #' # If you just remove geom_point, you will get an error 19 | #' b <- ggplot(mtcars, aes(x = wt, y = mpg)) 20 | #' \dontrun{b + geom_abline(aes(intercept = a, slope = b), data = df)} 21 | #' # Switching to geom_blank() gets the desired plot 22 | #' c <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_blank() 23 | #' c + geom_abline(aes(intercept = a, slope = b), data = df) 24 | geom_blank <- function(mapping = NULL, data = NULL, stat = "identity", 25 | position = "identity", show.legend = NA, 26 | inherit.aes = TRUE, ...) { 27 | layer( 28 | data = data, 29 | mapping = mapping, 30 | stat = stat, 31 | geom = GeomBlank, 32 | position = position, 33 | show.legend = show.legend, 34 | inherit.aes = inherit.aes, 35 | params = list(...) 36 | ) 37 | } 38 | 39 | 40 | #' @rdname ggplot2-ggproto 41 | #' @format NULL 42 | #' @usage NULL 43 | #' @export 44 | GeomBlank <- ggproto("GeomBlank", Geom, 45 | default_aes = aes(), 46 | draw_panel = function(...) nullGrob() 47 | ) 48 | -------------------------------------------------------------------------------- /R/geom-step.r: -------------------------------------------------------------------------------- 1 | #' @param direction direction of stairs: 'vh' for vertical then horizontal, or 2 | #' 'hv' for horizontal then vertical 3 | #' @export 4 | #' @rdname geom_path 5 | geom_step <- function(mapping = NULL, data = NULL, stat = "identity", 6 | position = "identity", direction = "hv", 7 | show.legend = NA, inherit.aes = TRUE, ...) { 8 | layer( 9 | data = data, 10 | mapping = mapping, 11 | stat = stat, 12 | geom = GeomStep, 13 | position = position, 14 | show.legend = show.legend, 15 | inherit.aes = inherit.aes, 16 | params = list( 17 | direction = direction, 18 | ... 19 | ) 20 | ) 21 | } 22 | 23 | #' @rdname ggplot2-ggproto 24 | #' @format NULL 25 | #' @usage NULL 26 | #' @export 27 | #' @include geom-path.r 28 | GeomStep <- ggproto("GeomStep", GeomPath, 29 | draw_panel = function(data, panel_scales, coord, direction = "hv") { 30 | data <- plyr::ddply(data, "group", stairstep, direction = direction) 31 | GeomPath$draw_panel(data, panel_scales, coord) 32 | } 33 | ) 34 | 35 | # Calculate stairsteps 36 | # Used by \code{\link{geom_step}} 37 | # 38 | # @keyword internal 39 | stairstep <- function(data, direction="hv") { 40 | direction <- match.arg(direction, c("hv", "vh")) 41 | data <- as.data.frame(data)[order(data$x), ] 42 | n <- nrow(data) 43 | 44 | if (direction == "vh") { 45 | xs <- rep(1:n, each = 2)[-2*n] 46 | ys <- c(1, rep(2:n, each = 2)) 47 | } else { 48 | ys <- rep(1:n, each = 2)[-2*n] 49 | xs <- c(1, rep(2:n, each = 2)) 50 | } 51 | 52 | data.frame( 53 | x = data$x[xs], 54 | y = data$y[ys], 55 | data[xs, setdiff(names(data), c("x", "y"))] 56 | ) 57 | } 58 | -------------------------------------------------------------------------------- /R/geom-curve.r: -------------------------------------------------------------------------------- 1 | #' @inheritParams grid::curveGrob 2 | #' @export 3 | #' @rdname geom_segment 4 | geom_curve <- function(mapping = NULL, data = NULL, stat = "identity", 5 | position = "identity", curvature = 0.5, angle = 90, ncp = 5, arrow = NULL, 6 | lineend = "butt", na.rm = FALSE, inherit.aes = TRUE, ...) 7 | { 8 | layer( 9 | data = data, 10 | mapping = mapping, 11 | stat = stat, 12 | geom = GeomCurve, 13 | position = position, 14 | inherit.aes = inherit.aes, 15 | params = list( 16 | arrow = arrow, 17 | curvature = curvature, 18 | angle = angle, 19 | ncp = ncp, 20 | lineend = lineend, 21 | na.rm = na.rm, 22 | ... 23 | ) 24 | ) 25 | } 26 | 27 | #' @rdname ggplot2-ggproto 28 | #' @include geom-segment.r 29 | #' @format NULL 30 | #' @usage NULL 31 | #' @export 32 | GeomCurve <- ggproto("GeomCurve", GeomSegment, 33 | draw_panel = function(data, panel_scales, coord, curvature = 0.5, angle = 90, 34 | ncp = 5, arrow = NULL, lineend = "butt", na.rm = FALSE) { 35 | if (!coord$is_linear()) { 36 | warning("geom_curve is not implemented for non-linear coordinates", 37 | call. = FALSE) 38 | } 39 | trans <- coord$transform(data, panel_scales) 40 | curveGrob( 41 | trans$x, trans$y, trans$xend, trans$yend, 42 | default.units = "native", 43 | curvature = curvature, angle = angle, ncp = ncp, 44 | square = FALSE, squareShape = 1, inflect = FALSE, open = TRUE, 45 | gp = gpar( 46 | col = alpha(trans$colour, trans$alpha), 47 | lwd = trans$size * .pt, 48 | lty = trans$linetype, 49 | lineend = trans$lineend), 50 | arrow = arrow 51 | ) 52 | } 53 | ) 54 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/aes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 51 | -------------------------------------------------------------------------------- /R/geom-spoke.r: -------------------------------------------------------------------------------- 1 | #' A line segment parameterised by location, direction and distance. 2 | #' 3 | #' @section Aesthetics: 4 | #' \Sexpr[results=rd,stage=build]{ggplot2:::rd_aesthetics("geom", "spoke")} 5 | #' 6 | #' @inheritParams geom_segment 7 | #' @export 8 | #' @examples 9 | #' df <- expand.grid(x = 1:10, y=1:10) 10 | #' df$angle <- runif(100, 0, 2*pi) 11 | #' df$speed <- runif(100, 0, sqrt(0.1 * df$x)) 12 | #' 13 | #' ggplot(df, aes(x, y)) + 14 | #' geom_point() + 15 | #' geom_spoke(aes(angle = angle), radius = 0.5) 16 | #' 17 | #' ggplot(df, aes(x, y)) + 18 | #' geom_point() + 19 | #' geom_spoke(aes(angle = angle, radius = speed)) 20 | geom_spoke <- function(mapping = NULL, data = NULL, stat = "identity", 21 | position = "identity", show.legend = NA, 22 | inherit.aes = TRUE, ...) { 23 | layer( 24 | data = data, 25 | mapping = mapping, 26 | geom = GeomSpoke, 27 | stat = stat, 28 | position = position, 29 | show.legend = show.legend, 30 | inherit.aes = inherit.aes, 31 | params = list(...) 32 | ) 33 | } 34 | 35 | #' @export 36 | #' @rdname geom_spoke 37 | #' @usage NULL 38 | stat_spoke <- function(...) { 39 | message("stat_spoke is deprecated, please use geom_spoke") 40 | geom_spoke(...) 41 | } 42 | 43 | #' @rdname ggplot2-ggproto 44 | #' @format NULL 45 | #' @usage NULL 46 | #' @export 47 | GeomSpoke <- ggproto("GeomSpoke", GeomSegment, 48 | setup_data = function(data, params) { 49 | data$radius <- data$radius %||% params$radius 50 | data$angle <- data$angle %||% params$angle 51 | 52 | transform(data, 53 | xend = x + cos(angle) * radius, 54 | yend = y + sin(angle) * radius 55 | ) 56 | }, 57 | required_aes = c("x", "y", "angle", "radius") 58 | ) 59 | -------------------------------------------------------------------------------- /man/ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | -------------------------------------------------------------------------------- /R/geom-errorbar.r: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname geom_linerange 3 | geom_errorbar <- function(mapping = NULL, data = NULL, stat = "identity", 4 | position = "identity", show.legend = NA, 5 | inherit.aes = TRUE, ...) { 6 | layer( 7 | data = data, 8 | mapping = mapping, 9 | stat = stat, 10 | geom = GeomErrorbar, 11 | position = position, 12 | show.legend = show.legend, 13 | inherit.aes = inherit.aes, 14 | params = list(...) 15 | ) 16 | } 17 | 18 | #' @rdname ggplot2-ggproto 19 | #' @format NULL 20 | #' @usage NULL 21 | #' @export 22 | GeomErrorbar <- ggproto("GeomErrorbar", Geom, 23 | default_aes = aes(colour = "black", size = 0.5, linetype = 1, width = 0.5, 24 | alpha = NA), 25 | 26 | draw_key = draw_key_path, 27 | 28 | required_aes = c("x", "ymin", "ymax"), 29 | 30 | setup_data = function(data, params) { 31 | data$width <- data$width %||% 32 | params$width %||% (resolution(data$x, FALSE) * 0.9) 33 | 34 | transform(data, 35 | xmin = x - width / 2, xmax = x + width / 2, width = NULL 36 | ) 37 | }, 38 | 39 | draw_panel = function(data, panel_scales, coord, width = NULL) { 40 | GeomPath$draw_panel(data.frame( 41 | x = as.vector(rbind(data$xmin, data$xmax, NA, data$x, data$x, NA, data$xmin, data$xmax)), 42 | y = as.vector(rbind(data$ymax, data$ymax, NA, data$ymax, data$ymin, NA, data$ymin, data$ymin)), 43 | colour = rep(data$colour, each = 8), 44 | alpha = rep(data$alpha, each = 8), 45 | size = rep(data$size, each = 8), 46 | linetype = rep(data$linetype, each = 8), 47 | group = rep(1:(nrow(data)), each = 8), 48 | stringsAsFactors = FALSE, 49 | row.names = 1:(nrow(data) * 8) 50 | ), panel_scales, coord) 51 | } 52 | ) 53 | -------------------------------------------------------------------------------- /man/position_jitter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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_stack}}; 45 | \code{\link{position_identity}}; 46 | \code{\link{position_jitterdodge}}; 47 | \code{\link{position_nudge}} 48 | } 49 | 50 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /visual_test/coord-map.r: -------------------------------------------------------------------------------- 1 | vcontext("coord-map") 2 | 3 | library(maps) 4 | 5 | # World map 6 | world_map <- map_data("world") 7 | pworld <- ggplot(world_map, aes(x = long, y = lat, group = group)) + 8 | geom_polygon() 9 | 10 | 11 | pworld 12 | save_vtest("no projection") 13 | 14 | 15 | pworld + coord_map(projection = "mercator") 16 | save_vtest("mercator projection") 17 | 18 | 19 | pworld + coord_map(projection = "ortho") + 20 | scale_y_continuous(breaks = (-2:2) * 30) + 21 | scale_x_continuous(breaks = (-4:4) * 45) 22 | save_vtest("ortho projection, default orientation (centered on north pole)") 23 | 24 | pworld + coord_map(projection = "ortho", orientation = c(41, -74 ,0)) + 25 | scale_y_continuous(breaks = (-2:2) * 30) + 26 | scale_x_continuous(breaks = (-4:4) * 45) 27 | save_vtest("ortho projection, custom orientation (centered on New York)") 28 | 29 | 30 | # Need to set limits here so left-most longitude line shows up 31 | pworld + coord_map(projection = "aitoff") + 32 | scale_y_continuous(breaks = (-2:2) * 30) + 33 | scale_x_continuous(breaks = (-4:4) * 45, limits = c(-180, 180)) 34 | save_vtest("aitoff projection, default orientation") 35 | 36 | 37 | # This drops half of the world, which probably isn't desirable. 38 | # It might require rethinking about how limits work. 39 | pworld + coord_map(projection = "aitoff", orientation = c(90, 180, 0)) + 40 | scale_y_continuous(breaks = (-2:2) * 30) + 41 | scale_x_continuous(breaks = (0:8) * 45, limits = c(0, 360)) 42 | save_vtest("aitoff projection, custom orientation (centered on date line)") 43 | 44 | 45 | # USA state map 46 | states_map <- map_data("state") 47 | pstate <- ggplot(states_map, aes(x = long, y = lat, group = group)) 48 | 49 | pstate + geom_polygon() + coord_map("mercator") 50 | save_vtest("USA map, mercator projection") 51 | 52 | end_vcontext() 53 | -------------------------------------------------------------------------------- /man/aes_position.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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{xend} 7 | \alias{xmax} 8 | \alias{xmin} 9 | \alias{y} 10 | \alias{yend} 11 | \alias{ymax} 12 | \alias{ymin} 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 | # Generate data: means and standard errors of means for prices 20 | # for each type of cut 21 | dmod <- lm(price ~ cut, data = diamonds) 22 | cuts <- data.frame(cut = unique(diamonds$cut), predict(dmod, data.frame(cut = 23 | unique(diamonds$cut)), se = TRUE)[c("fit", "se.fit")]) 24 | se <- ggplot(cuts, aes(x = cut, y = fit, ymin = fit - se.fit, 25 | ymax = fit + se.fit, colour = cut)) 26 | se + geom_pointrange() 27 | 28 | # Using annotate 29 | p <- ggplot(mtcars, aes(wt, mpg)) + geom_point() 30 | p + annotate("rect", xmin = 2, xmax = 3.5, ymin = 2, ymax = 25, 31 | fill = "dark grey", alpha = .5) 32 | 33 | # Geom_segment examples 34 | p + geom_segment(aes(x = 2, y = 15, xend = 2, yend = 25), 35 | arrow = arrow(length = unit(0.5, "cm"))) 36 | p + geom_segment(aes(x = 2, y = 15, xend = 3, yend = 15), 37 | arrow = arrow(length = unit(0.5, "cm"))) 38 | p + geom_segment(aes(x = 5, y = 30, xend = 3.5, yend = 25), 39 | arrow = arrow(length = unit(0.5, "cm"))) 40 | 41 | # You can also use geom_segment to recreate plot(type = "h") : 42 | counts <- as.data.frame(table(x = rpois(100, 5))) 43 | counts$x <- as.numeric(as.character(counts$x)) 44 | with(counts, plot(x, Freq, type = "h", lwd = 10)) 45 | 46 | ggplot(counts, aes(x, Freq)) + 47 | geom_segment(aes(yend = 0, xend = x), size = 10) 48 | } 49 | 50 | -------------------------------------------------------------------------------- /man/stat_unique.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/stat-unique.r 3 | \name{stat_unique} 4 | \alias{stat_unique} 5 | \title{Remove duplicates.} 6 | \usage{ 7 | stat_unique(mapping = NULL, data = NULL, geom = "point", 8 | position = "identity", show.legend = NA, inherit.aes = TRUE, ...) 9 | } 10 | \arguments{ 11 | \item{mapping}{The aesthetic mapping, usually constructed with 12 | \code{\link{aes}} or \code{\link{aes_string}}. Only needs to be set 13 | at the layer level if you are overriding the plot defaults.} 14 | 15 | \item{data}{A layer specific dataset - only needed if you want to override 16 | the plot defaults.} 17 | 18 | \item{geom}{The geometric object to use display the data} 19 | 20 | \item{position}{The position adjustment to use for overlapping points 21 | on this layer} 22 | 23 | \item{show.legend}{logical. Should this layer be included in the legends? 24 | \code{NA}, the default, includes if any aesthetics are mapped. 25 | \code{FALSE} never includes, and \code{TRUE} always includes.} 26 | 27 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 28 | rather than combining with them. This is most useful for helper functions 29 | that define both data and aesthetics and shouldn't inherit behaviour from 30 | the default plot specification, e.g. \code{\link{borders}}.} 31 | 32 | \item{...}{other arguments passed on to \code{\link{layer}}. This can 33 | include aesthetics whose values you want to set, not map. See 34 | \code{\link{layer}} for more details.} 35 | } 36 | \description{ 37 | Remove duplicates. 38 | } 39 | \section{Aesthetics}{ 40 | 41 | \Sexpr[results=rd,stage=build]{ggplot2:::rd_aesthetics("stat", "unique")} 42 | } 43 | \examples{ 44 | ggplot(mtcars, aes(vs, am)) + geom_point(alpha = 0.1) 45 | ggplot(mtcars, aes(vs, am)) + geom_point(alpha = 0.1, stat="unique") 46 | } 47 | 48 | -------------------------------------------------------------------------------- /man/annotate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/annotation.r 3 | \name{annotate} 4 | \alias{annotate} 5 | \title{Create an annotation layer.} 6 | \usage{ 7 | annotate(geom, x = NULL, y = NULL, xmin = NULL, xmax = NULL, 8 | ymin = NULL, ymax = NULL, xend = NULL, yend = NULL, ...) 9 | } 10 | \arguments{ 11 | \item{geom}{name of geom to use for annotation} 12 | 13 | \item{x,y,xmin,ymin,xmax,ymax,xend,yend}{positioning aesthetics - 14 | you must specify at least one of these.} 15 | 16 | \item{...}{other aesthetics. These are not scaled so you can do (e.g.) 17 | \code{colour = "red"} to get a red point.} 18 | } 19 | \description{ 20 | This function adds geoms to a plot. Unlike typical a geom function, 21 | the properties of the geoms are not mapped from variables of a data frame, 22 | but are instead passed in as vectors. This is useful for adding small annotations 23 | (such as text labels) or if you have your data in vectors, and for some 24 | reason don't want to put them in a data frame. 25 | } 26 | \details{ 27 | Note that all position aesthetics are scaled (i.e. they will expand the 28 | limits of the plot so they are visible), but all other aesthetics are 29 | set. This means that layers created with this function will never 30 | affect the legend. 31 | } 32 | \examples{ 33 | p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() 34 | p + annotate("text", x = 4, y = 25, label = "Some text") 35 | p + annotate("text", x = 2:5, y = 25, label = "Some text") 36 | p + annotate("rect", xmin = 3, xmax = 4.2, ymin = 12, ymax = 21, 37 | alpha = .2) 38 | p + annotate("segment", x = 2.5, xend = 4, y = 15, yend = 25, 39 | colour = "blue") 40 | p + annotate("pointrange", x = 3.5, y = 20, ymin = 12, ymax = 28, 41 | colour = "red", size = 1.5) 42 | 43 | p + annotate("text", x = 2:3, y = 20:21, label = c("my label", "label 2")) 44 | } 45 | 46 | -------------------------------------------------------------------------------- /man/annotation_raster.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | 51 | -------------------------------------------------------------------------------- /visual_test/violin.r: -------------------------------------------------------------------------------- 1 | vcontext("violin") 2 | 3 | set.seed(111) 4 | dat <- data.frame(x = LETTERS[1:3], y = rnorm(90)) 5 | dat <- dat[dat$x != "C" | c(T, F),] # Keep half the C's 6 | 7 | 8 | ggplot(dat, aes(x = x, y = y)) + geom_violin() 9 | save_vtest("basic") 10 | 11 | ggplot(dat, aes(x = x, y = y)) + geom_violin(scale = "count") 12 | save_vtest("scale area to sample size (C is smaller)") 13 | 14 | ggplot(dat, aes(x = x, y = y)) + geom_violin(width = .5) 15 | save_vtest("narrower (width=.5)") 16 | 17 | 18 | ggplot(dat, aes(x = x, y = y)) + geom_violin(trim = FALSE) + geom_point(shape = 21) 19 | save_vtest("with tails and points") 20 | 21 | ggplot(dat, aes(x = x, y = y)) + geom_violin(adjust = .3) + geom_point(shape = 22 | 21) 23 | save_vtest("with smaller bandwidth and points") 24 | 25 | 26 | ggplot(dat, aes(x = "foo", y = y, fill = x)) + geom_violin() 27 | save_vtest("dodging") 28 | 29 | ggplot(dat, aes(x = x, y = y)) + geom_violin() + coord_polar() 30 | save_vtest("coord_polar") 31 | 32 | ggplot(dat, aes(x = x, y = y)) + geom_violin() + coord_flip() 33 | save_vtest("coord_flip") 34 | 35 | ggplot(dat, aes(x = "foo", y = y, fill = x)) + geom_violin() + coord_flip() 36 | save_vtest("dodging and coord_flip") 37 | 38 | ggplot(dat, aes(x = as.numeric(x), y = y)) + geom_violin() 39 | save_vtest("continuous x axis, multiple groups (center should be at 2.0)") 40 | 41 | ggplot(dat, aes(x = as.numeric(1), y = y)) + geom_violin() 42 | save_vtest("continuous x axis, single group (center should be at 1.0)") 43 | 44 | dat2 <- data.frame(x = LETTERS[1:3], y = rnorm(90), g = letters[5:6]) 45 | 46 | ggplot(dat2, aes(x = x, y = y, fill = g)) + geom_violin() 47 | save_vtest("grouping on x and fill") 48 | 49 | ggplot(dat2, aes(x = x, y = y, fill = g)) + 50 | geom_violin(position = position_dodge(width = .5)) 51 | save_vtest("grouping on x and fill, dodge width = 0.5") 52 | 53 | end_vcontext() 54 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /R/zxx.r: -------------------------------------------------------------------------------- 1 | # Default scales ------------------------------------------------------------- 2 | 3 | #' @export 4 | #' @rdname scale_hue 5 | #' @usage NULL 6 | scale_colour_discrete <- scale_colour_hue 7 | 8 | #' @export 9 | #' @rdname scale_gradient 10 | #' @usage NULL 11 | scale_colour_continuous <- scale_colour_gradient 12 | 13 | #' @export 14 | #' @rdname scale_hue 15 | #' @usage NULL 16 | scale_fill_discrete <- scale_fill_hue 17 | 18 | #' @export 19 | #' @rdname scale_gradient 20 | #' @usage NULL 21 | scale_fill_continuous <- scale_fill_gradient 22 | 23 | # British to American spellings ---------------------------------------------- 24 | 25 | #' @export 26 | #' @rdname scale_brewer 27 | #' @usage NULL 28 | scale_color_brewer <- scale_colour_brewer 29 | 30 | #' @export 31 | #' @rdname scale_brewer 32 | #' @usage NULL 33 | scale_color_distiller <- scale_colour_distiller 34 | 35 | #' @export 36 | #' @rdname scale_gradient 37 | #' @usage NULL 38 | scale_color_continuous <- scale_colour_gradient 39 | 40 | #' @export 41 | #' @rdname scale_hue 42 | #' @usage NULL 43 | scale_color_discrete <- scale_colour_hue 44 | 45 | #' @export 46 | #' @rdname scale_gradient 47 | #' @usage NULL 48 | scale_color_gradient <- scale_colour_gradient 49 | 50 | #' @export 51 | #' @rdname scale_gradient 52 | #' @usage NULL 53 | scale_color_gradient2 <- scale_colour_gradient2 54 | 55 | #' @export 56 | #' @rdname scale_gradient 57 | #' @usage NULL 58 | scale_color_gradientn <- scale_colour_gradientn 59 | 60 | #' @export 61 | #' @rdname scale_grey 62 | #' @usage NULL 63 | scale_color_grey <- scale_colour_grey 64 | 65 | #' @export 66 | #' @rdname scale_hue 67 | #' @usage NULL 68 | scale_color_hue <- scale_colour_hue 69 | 70 | #' @export 71 | #' @rdname scale_identity 72 | #' @usage NULL 73 | scale_color_identity <- scale_colour_identity 74 | 75 | #' @export 76 | #' @rdname scale_manual 77 | #' @usage NULL 78 | scale_color_manual <- scale_colour_manual 79 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/position_dodge.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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_stack}}; 50 | \code{\link{position_identity}}; 51 | \code{\link{position_jitterdodge}}; 52 | \code{\link{position_jitter}}; 53 | \code{\link{position_nudge}} 54 | } 55 | 56 | -------------------------------------------------------------------------------- /R/geom-jitter.r: -------------------------------------------------------------------------------- 1 | #' Points, jittered to reduce overplotting. 2 | #' 3 | #' The jitter geom is a convenient default for geom_point with position = 4 | #' 'jitter'. It's a useful way of handling overplotting caused by discreteness 5 | #' in smaller datasets. 6 | #' 7 | #' @section Aesthetics: 8 | #' \Sexpr[results=rd,stage=build]{ggplot2:::rd_aesthetics("geom", "point")} 9 | #' 10 | #' @inheritParams geom_point 11 | #' @inheritParams position_jitter 12 | #' @seealso 13 | #' \code{\link{geom_point}} for regular, unjittered points, 14 | #' \code{\link{geom_boxplot}} for another way of looking at the conditional 15 | #' distribution of a variable 16 | #' @export 17 | #' @examples 18 | #' p <- ggplot(mpg, aes(cyl, hwy)) 19 | #' p + geom_point() 20 | #' p + geom_jitter() 21 | #' 22 | #' # Add aesthetic mappings 23 | #' p + geom_jitter(aes(colour = class)) 24 | #' 25 | #' # Use smaller width/height to emphasise categories 26 | #' ggplot(mpg, aes(cyl, hwy)) + geom_jitter() 27 | #' ggplot(mpg, aes(cyl, hwy)) + geom_jitter(width = 0.25) 28 | #' 29 | #' # Use larger width/height to completely smooth away discreteness 30 | #' ggplot(mpg, aes(cty, hwy)) + geom_jitter() 31 | #' ggplot(mpg, aes(cty, hwy)) + geom_jitter(width = 0.5, height = 0.5) 32 | geom_jitter <- function(mapping = NULL, data = NULL, 33 | width = NULL, height = NULL, stat = "identity", position = "jitter", 34 | na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, ...) 35 | { 36 | if (!missing(width) || !missing(height)) { 37 | if (!missing(position)) { 38 | stop("Specify either `position` or `width`/`height`", call. = FALSE) 39 | } 40 | 41 | position <- position_jitter(width = width, height = height) 42 | } 43 | 44 | layer( 45 | data = data, 46 | mapping = mapping, 47 | stat = stat, 48 | geom = GeomPoint, 49 | position = position, 50 | show.legend = show.legend, 51 | inherit.aes = inherit.aes, 52 | params = list(..., na.rm = na.rm) 53 | ) 54 | } 55 | -------------------------------------------------------------------------------- /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/layer.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/layer.r 3 | \name{layer} 4 | \alias{layer} 5 | \title{Create a new layer} 6 | \usage{ 7 | layer(geom = NULL, stat = NULL, data = NULL, mapping = NULL, 8 | position = NULL, params = list(), inherit.aes = TRUE, subset = NULL, 9 | show.legend = NA) 10 | } 11 | \arguments{ 12 | \item{geom,stat,position}{Geom, stat and position adjustment to use in 13 | this layer. Can either be the name of a ggproto object, or the object 14 | itself.} 15 | 16 | \item{data}{A data frame. If specified, overrides the default data frame 17 | defined at the top level of the plot.} 18 | 19 | \item{mapping}{Set of aesthetic mappings created by \code{\link{aes}} or 20 | \code{\link{aes_}}. If specified and \code{inherit.aes = TRUE} (the 21 | default), is combined with the default mapping at the top level of the 22 | plot. You only need to supply \code{mapping} if there isn't a mapping 23 | defined for the plot.} 24 | 25 | \item{params}{Additional parameters to the \code{geom} and \code{stat}.} 26 | 27 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 28 | rather than combining with them. This is most useful for helper functions 29 | that define both data and aesthetics and shouldn't inherit behaviour from 30 | the default plot specification, e.g. \code{\link{borders}}.} 31 | 32 | \item{subset}{DEPRECATED. An older way of subsetting the dataset used in a 33 | layer.} 34 | 35 | \item{show.legend}{logical. Should this layer be included in the legends? 36 | \code{NA}, the default, includes if any aesthetics are mapped. 37 | \code{FALSE} never includes, and \code{TRUE} always includes.} 38 | } 39 | \description{ 40 | Create a new layer 41 | } 42 | \examples{ 43 | # geom calls are just a short cut for layer 44 | ggplot(mpg, aes(displ, hwy)) + geom_point() 45 | # shortcut for 46 | ggplot(mpg, aes(displ, hwy)) + 47 | layer(geom = "point", stat = "identity", position = "identity") 48 | } 49 | 50 | -------------------------------------------------------------------------------- /man/guides.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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 | # Guides are integrated where possible 42 | 43 | p + guides(colour = guide_legend("title"), size = guide_legend("title"), 44 | shape = guide_legend("title")) 45 | # same as 46 | g <- guide_legend("title") 47 | p + guides(colour = g, size = g, shape = g) 48 | 49 | p + theme(legend.position = "bottom") 50 | 51 | # position of guides 52 | 53 | p + theme(legend.position = "bottom", legend.box = "horizontal") 54 | 55 | # Set order for multiple guides 56 | ggplot(mpg, aes(displ, cty)) + 57 | geom_point(aes(size = hwy, colour = cyl, shape = drv)) + 58 | guides( 59 | colour = guide_colourbar(order = 1), 60 | shape = guide_legend(order = 2), 61 | size = guide_legend(order = 3) 62 | ) 63 | } 64 | } 65 | \seealso{ 66 | Other guides: \code{\link{guide_colorbar}}, 67 | \code{\link{guide_colourbar}}; \code{\link{guide_legend}} 68 | } 69 | 70 | -------------------------------------------------------------------------------- /man/cut_interval.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): 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, closed = c("right", 14 | "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 | \author{ 55 | Randall Prium contributed most of the implementation of 56 | \code{cut_width}. 57 | } 58 | \seealso{ 59 | \code{\link{cut_number}} 60 | } 61 | 62 | --------------------------------------------------------------------------------