├── .Rbuildignore ├── .github └── FUNDING.yml ├── .gitignore ├── .travis.yml ├── CONDUCT.md ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── annotate_textp.r ├── annotation_ticks.r ├── coord_proj.r ├── formatters.r ├── fortify.r ├── geom2plotly.r ├── geom_ash.r ├── geom_bkde.r ├── geom_bkde2d.r ├── geom_cartogram.r ├── geom_dumbbell.R ├── geom_encircle.r ├── geom_horizon.r ├── geom_lollipop.r ├── geom_spikelines.R ├── geom_table.r ├── geom_twoway_bar.r ├── geom_ubar.r ├── geom_xspline.r ├── geom_xspline2.r ├── ggalt-package.r ├── grob_absolute.r ├── guide_axis.r ├── position-dodgev.R ├── stat-stepribbon.r ├── stateface.r ├── utils.r └── zzz.r ├── README.Rmd ├── README.md ├── README_figs ├── README-annoticks-1.png ├── README-annoticks-2.png ├── README-annoticks-3.png ├── README-bkde2d-1.png ├── README-bkde2d-2.png ├── README-bkde_ash-1.png ├── README-bkde_ash-2.png ├── README-bkde_ash-3.png ├── README-bkde_ash-4.png ├── README-bkde_ash-5.png ├── README-bkde_ash-6.png ├── README-bkde_ash-7.png ├── README-bkde_ash-8.png ├── README-coord_proj-1.png ├── README-dumbbell-1.png ├── README-dumbbell2-1.png ├── README-encircle-1.png ├── README-encircle-2.png ├── README-encircle-3.png ├── README-encircle-4.png ├── README-encircle-5.png ├── README-encircle-6.png ├── README-encircle-7.png ├── README-horizon-1.png ├── README-lollipop-1.png ├── README-spikelines-1.png ├── README-splines-1.png ├── README-splines-2.png ├── README-splines-3.png ├── README-splines-4.png ├── README-splines-5.png ├── README-splines-6.png ├── README-splines-7.png ├── README-splines-8.png ├── README-stateface-1.png ├── README-stepribbon-1.png └── README-stepribbon-2.png ├── appveyor.yml ├── cran-comments.md ├── ggalt.Rproj ├── inst └── fonts │ └── stateface-regular-webfont.ttf ├── man ├── absoluteGrob.Rd ├── annotate_textp.Rd ├── annotation_ticks.Rd ├── byte_format.Rd ├── coord_proj.Rd ├── figures │ ├── coordproj01.png │ ├── geombkde01.png │ ├── geombkde2d01.png │ ├── geomencircle01.png │ ├── geomlollipop01.png │ ├── geomstateface01.png │ ├── geomxspline01.png │ └── statash01.png ├── fortify.table.Rd ├── geom_bkde.Rd ├── geom_bkde2d.Rd ├── geom_cartogram.Rd ├── geom_dumbbell.Rd ├── geom_encircle.Rd ├── geom_horizon.Rd ├── geom_lollipop.Rd ├── geom_spikelines.Rd ├── geom_stateface.Rd ├── geom_ubar.Rd ├── geom_xspline.Rd ├── geom_xspline2.Rd ├── ggalt-ggproto.Rd ├── ggalt.Rd ├── ggplot2-ggproto.Rd ├── load_stateface.Rd ├── macros │ └── aesthetics.Rd ├── plotly_helpers.Rd ├── position-dodgev.Rd ├── show_stateface.Rd ├── stat_ash.Rd └── stat_stepribbon.Rd ├── revdep └── checks.rds ├── tests ├── testthat.R └── testthat │ └── test-ggalt.R └── vignettes └── ggalt_examples.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^README.*$ 4 | ^\.travis\.yml$ 5 | ^CONDUCT\.md$ 6 | ^cran-comments\.md$ 7 | ^revdep$ 8 | ^appveyor\.yml$ 9 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: hrbrmstr 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | inst/doc 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: r 2 | warnings_are_errors: true 3 | sudo: required 4 | 5 | cache: packages 6 | 7 | apt_packages: 8 | - binutils 9 | - libproj-dev 10 | - gdal-bin 11 | 12 | env: 13 | global: 14 | - CRAN: http://cran.rstudio.com 15 | 16 | notifications: 17 | email: 18 | on_success: change 19 | on_failure: change 20 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http:contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: ggalt 2 | Title: Extra Coordinate Systems, 'Geoms', Statistical Transformations, Scales 3 | and Fonts for 'ggplot2' 4 | Version: 0.6.1 5 | Maintainer: Bob Rudis 6 | Authors@R: c( 7 | person("Bob", "Rudis", email = "bob@rud.is", role = c("aut", "cre"), 8 | comment = c(ORCID = "0000-0001-5670-2640")), 9 | person("Ben", "Bolker", comment="Encircling & additional splines", role = c("aut", "ctb")), 10 | person("Ben", "Marwick", comment="General codebase cleanup", role = c("ctb")), 11 | person("Jan", "Schulz", comment="Annotations", role = c("aut", "ctb")), 12 | person("Rosen", "Matev", role="ctb", comment="Original annotate_textp implementation on stackoverflow"), 13 | person("ProPublica", role="dtc", comment="StateFace font"), 14 | person("Aditya", "Kothari", role=c("aut", "ctb"), comment="Core functionality of horizon plots"), 15 | person("Ather", role="dtc", comment="Core functionality of horizon plots"), 16 | person("Jonathan","Sidi", role=c("aut","ctb"), comment="Annotation ticks"), 17 | person("Tarcisio","Fedrizzi", role="ctb", comment="Bytes formatter") 18 | ) 19 | Description: A compendium of new geometries, coordinate systems, statistical 20 | transformations, scales and fonts for 'ggplot2', including splines, 1d and 2d densities, 21 | univariate average shifted histograms, a new map coordinate system based on the 22 | 'PROJ.4'-library along with geom_cartogram() that mimics the original functionality of 23 | geom_map(), formatters for "bytes", a stat_stepribbon() function, increased 'plotly' 24 | compatibility and the 'StateFace' open source font 'ProPublica'. Further new 25 | functionality includes lollipop charts, dumbbell charts, the ability to encircle 26 | points and coordinate-system-based text annotations. 27 | License: MIT + file LICENSE 28 | LazyData: true 29 | URL: https://github.com/hrbrmstr/ggalt 30 | BugReports: https://github.com/hrbrmstr/ggalt/issues 31 | Encoding: UTF-8 32 | Depends: 33 | R (>= 3.2.0), 34 | ggplot2 (>= 2.2.1) 35 | Suggests: 36 | testthat, 37 | gridExtra, 38 | knitr, 39 | rmarkdown, 40 | ggthemes, 41 | reshape2 42 | Imports: 43 | utils, 44 | graphics, 45 | datasets, 46 | grDevices, 47 | plyr, 48 | dplyr, 49 | RColorBrewer, 50 | KernSmooth, 51 | proj4, 52 | scales, 53 | grid, 54 | gtable, 55 | ash, 56 | maps, 57 | MASS, 58 | extrafont, 59 | tibble, 60 | plotly (>= 3.4.1) 61 | RoxygenNote: 7.2.3 62 | VignetteBuilder: knitr 63 | Collate: 64 | 'annotate_textp.r' 65 | 'annotation_ticks.r' 66 | 'coord_proj.r' 67 | 'formatters.r' 68 | 'fortify.r' 69 | 'position-dodgev.R' 70 | 'geom2plotly.r' 71 | 'geom_ash.r' 72 | 'geom_bkde.r' 73 | 'geom_bkde2d.r' 74 | 'geom_spikelines.R' 75 | 'geom_dumbbell.R' 76 | 'geom_cartogram.r' 77 | 'geom_encircle.r' 78 | 'geom_horizon.r' 79 | 'geom_lollipop.r' 80 | 'geom_table.r' 81 | 'geom_twoway_bar.r' 82 | 'geom_xspline.r' 83 | 'geom_xspline2.r' 84 | 'geom_ubar.r' 85 | 'stat-stepribbon.r' 86 | 'ggalt-package.r' 87 | 'grob_absolute.r' 88 | 'guide_axis.r' 89 | 'stateface.r' 90 | 'utils.r' 91 | 'zzz.r' 92 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2017 2 | COPYRIGHT HOLDER: Bob Rudis 3 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(fortify,table) 4 | S3method(grid.draw,absoluteGrob) 5 | S3method(grobHeight,absoluteGrob) 6 | S3method(grobWidth,absoluteGrob) 7 | S3method(grobX,absoluteGrob) 8 | S3method(grobY,absoluteGrob) 9 | export(CoordProj) 10 | export(Gb) 11 | export(GeomBkde) 12 | export(GeomBkde2d) 13 | export(GeomCartogram) 14 | export(GeomDumbbell) 15 | export(GeomEncircle) 16 | export(GeomHorizon) 17 | export(GeomLollipop) 18 | export(GeomSpikelines) 19 | export(GeomStateface) 20 | export(GeomTicks) 21 | export(GeomUbar) 22 | export(GeomXSpline2) 23 | export(GeomXspline) 24 | export(Kb) 25 | export(Mb) 26 | export(PositionDodgev) 27 | export(StatAsh) 28 | export(StatBkde) 29 | export(StatBkde2d) 30 | export(StatHorizon) 31 | export(StatStepribbon) 32 | export(StatXspline) 33 | export(annotate_textp) 34 | export(annotation_ticks) 35 | export(byte_format) 36 | export(bytes) 37 | export(coord_proj) 38 | export(geom_bkde) 39 | export(geom_bkde2d) 40 | export(geom_cartogram) 41 | export(geom_dumbbell) 42 | export(geom_encircle) 43 | export(geom_horizon) 44 | export(geom_lollipop) 45 | export(geom_spikelines) 46 | export(geom_stateface) 47 | export(geom_ubar) 48 | export(geom_xspline) 49 | export(load_stateface) 50 | export(position_dodgev) 51 | export(show_stateface) 52 | export(stat_ash) 53 | export(stat_bkde) 54 | export(stat_bkde2d) 55 | export(stat_horizon) 56 | export(stat_stepribbon) 57 | export(stat_xspline) 58 | export(to_basic.GeomBkde2d) 59 | export(to_basic.GeomStateface) 60 | export(to_basic.GeomXspline) 61 | import(KernSmooth) 62 | import(MASS) 63 | import(ash) 64 | import(datasets) 65 | import(ggplot2) 66 | import(grDevices) 67 | import(graphics) 68 | import(grid) 69 | import(maps) 70 | import(proj4) 71 | import(utils) 72 | importFrom(RColorBrewer,brewer.pal) 73 | importFrom(dplyr,filter) 74 | importFrom(extrafont,fonts) 75 | importFrom(extrafont,loadfonts) 76 | importFrom(extrafont,ttf_import) 77 | importFrom(grid,gList) 78 | importFrom(grid,gTree) 79 | importFrom(grid,gpar) 80 | importFrom(grid,grid.draw) 81 | importFrom(grid,grobHeight) 82 | importFrom(grid,grobName) 83 | importFrom(grid,grobTree) 84 | importFrom(grid,grobWidth) 85 | importFrom(grid,grobX) 86 | importFrom(grid,grobY) 87 | importFrom(grid,pointsGrob) 88 | importFrom(grid,polygonGrob) 89 | importFrom(grid,segmentsGrob) 90 | importFrom(grid,textGrob) 91 | importFrom(grid,unit.c) 92 | importFrom(grid,viewport) 93 | importFrom(gtable,gtable_col) 94 | importFrom(gtable,gtable_height) 95 | importFrom(gtable,gtable_row) 96 | importFrom(gtable,gtable_width) 97 | importFrom(scales,comma) 98 | importFrom(scales,expand_range) 99 | importFrom(scales,rescale) 100 | importFrom(tibble,as_tibble) 101 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | 0.5.0 2 | ===================== 3 | * `geom_ubar()` : uniform bar charts based on `geom_segment()` 4 | 5 | 0.4.0 6 | ===================== 7 | * Fixed `coord_proj()` 8 | * Removed pokemon colors (et al) 9 | * Added dotted-gridline guide for `geom\_dumbbell()` 10 | * Complete parameter re-write to `geom\_dumbbell()` 11 | * New geoms & stats by Ben Bolker, Jan Schulz and Carson Sievert 12 | * Ben Marwick also did his best to keep up with my fat-fingering but I'm snuck a few in before the release 13 | 14 | 0.3.0 15 | ===================== 16 | * Added `geom_lollipop()` to make it easer to create lollipop charts 17 | 18 | 0.2.0 19 | ===================== 20 | * Incorporated ProPublica StateFace font 21 | * `geom_encircle()` contributed by Ben Bolker 22 | 23 | 0.1.5 24 | ===================== 25 | * Pokemon discrete color scales! 26 | * `byte_format` (et al) scales (e.g. 10000 => 10 Kb) 27 | -------------------------------------------------------------------------------- /R/annotate_textp.r: -------------------------------------------------------------------------------- 1 | globalVariables(c("Stepribbon")) 2 | 3 | #' Text annotations in plot coordinate system 4 | #' 5 | #' Annotates the plot with text. Compared to \code{annotate("text",...)}, the 6 | #' placement of the annotations is specified in plot coordinates (from 0 to 1) 7 | #' instead of data coordinates. 8 | #' 9 | #' @param label text annotation to be placed on the plot 10 | #' @param x,y positions of the individual annotations, in plot coordinates 11 | #' (0..1) instead of data coordinates! 12 | #' @param facets facet positions of the individual annotations 13 | #' @param hjust,vjust horizontal and vertical justification of the text relative 14 | #' to the bounding box 15 | #' @param color, alpha, family, size, fontface, lineheight font properties 16 | #' @param box_just placement of the bounding box for the text relative to x,y 17 | #' coordinates. Per default, the box is placed to the center of the plot. Be 18 | #' aware that parts of the box which are outside of the visible region of the 19 | #' plot will not be shown. 20 | #' @param margin margins of the bounding box 21 | #' @param alpha,family,size,fontface,lineheight standard aesthetic customizations 22 | #' @examples 23 | #' p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() 24 | #' p <- p + geom_smooth(method = "lm", se = FALSE) 25 | #' p + annotate_textp(x = 0.9, y = 0.35, label="A relative linear\nrelationship", hjust=1, color="red") 26 | #' @export 27 | annotate_textp <- function(label, x, y, facets=NULL, hjust=0, vjust=0, color='black', alpha=NA, 28 | family=theme_get()$text$family, size=theme_get()$text$size, fontface=1, lineheight=1.0, 29 | box_just=ifelse(c(x,y)<0.5,0,1), margin=unit(size/2, 'pt')) { 30 | # based on https://stackoverflow.com/questions/22488563/ggplot2-annotate-layer-position-in-r/22500252#22500252 31 | if (x < 0 || x > 1){ 32 | stop("x values must be in plot coordinates (between 0 and 1)") 33 | } 34 | if (y < 0 || y > 1){ 35 | stop("y values must be in plot coordinates (between 0 and 1)") 36 | } 37 | x <- scales::squish_infinite(x) 38 | y <- scales::squish_infinite(y) 39 | data <- if (is.null(facets)) data.frame(x=NA) else data.frame(x=NA, facets) 40 | 41 | tg <- grid::textGrob( 42 | label, x=0, y=0, hjust=hjust, vjust=vjust, 43 | gp=grid::gpar(col=alpha(color, alpha), fontsize=size, fontfamily=family, fontface=fontface, lineheight=lineheight) 44 | ) 45 | ts <- grid::unit.c(grid::grobWidth(tg), grid::grobHeight(tg)) 46 | vp <- grid::viewport(x=x, y=y, width=ts[1], height=ts[2], just=box_just) 47 | tg <- grid::editGrob(tg, x=ts[1]*hjust, y=ts[2]*vjust, vp=vp) 48 | inner <- grid::grobTree(tg, vp=grid::viewport(width=unit(1, 'npc')-margin*2, height=unit(1, 'npc')-margin*2)) 49 | 50 | layer( 51 | data = NULL, 52 | stat = StatIdentity, 53 | position = PositionIdentity, 54 | geom = GeomCustomAnn, 55 | inherit.aes = TRUE, 56 | params = list( 57 | grob=grid::grobTree(inner), 58 | xmin=-Inf, 59 | xmax=Inf, 60 | ymin=-Inf, 61 | ymax=Inf 62 | ) 63 | ) 64 | } 65 | -------------------------------------------------------------------------------- /R/formatters.r: -------------------------------------------------------------------------------- 1 | #' Bytes formatter: convert to byte measurement and display symbol. 2 | #' 3 | #' @return a function with three parameters, \code{x}, a numeric vector that 4 | #' returns a character vector, \code{symbol} a single or a vector of byte 5 | #' symbol(s) (e.g. "\code{Kb}") desired and the measurement \code{units} 6 | #' (traditional \code{binary} or \code{si} for ISI metric units). 7 | #' @param x a numeric vector to format 8 | #' @param symbol byte symbol to use. If "\code{auto}" the symbol used will be 9 | #' determined by the maximum value of \code{x}. Valid symbols are 10 | #' "\code{b}", "\code{K}", "\code{Mb}", "\code{Gb}", "\code{Tb}", "\code{Pb}", 11 | #' "\code{Eb}", "\code{Zb}", and "\code{Yb}", along with their upper case 12 | #' equivalents and "\code{iB}" equivalents. 13 | #' @param units which unit base to use, "\code{binary}" (1024 base) or 14 | #' "\code{si}" (1000 base) for ISI units. 15 | #' @param only_highest Whether to use the unit of the highest number or 16 | #' each number uses its own unit. 17 | #' @references Units of Information (Wikipedia) : 18 | #' \url{http://en.wikipedia.org/wiki/Units_of_information} 19 | #' @export 20 | #' @examples 21 | #' byte_format()(sample(3000000000, 10)) 22 | #' bytes(sample(3000000000, 10)) 23 | #' Kb(sample(3000000000, 10)) 24 | #' Mb(sample(3000000000, 10)) 25 | #' Gb(sample(3000000000, 10)) 26 | byte_format <- function (symbol = "auto", units = "binary", only_highest = TRUE) { 27 | function(x) bytes(x, symbol, units, only_highest) 28 | } 29 | 30 | #' @export 31 | #' @rdname byte_format 32 | Kb <- byte_format("Kb", "binary") 33 | 34 | #' @export 35 | #' @rdname byte_format 36 | Mb <- byte_format("Mb", "binary") 37 | 38 | #' @export 39 | #' @rdname byte_format 40 | Gb <- byte_format("Gb", "binary") 41 | 42 | #' @export 43 | #' @rdname byte_format 44 | bytes <- function (x, symbol = "auto", units = c("binary", "si"), 45 | only_highest = FALSE) { 46 | bin_names <- c("bytes", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb") 47 | si_names <- c("bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB") 48 | units <- match.arg(units, c("binary", "si")) 49 | valid_names <- c("auto", if (units == "binary") { 50 | c(bin_names, toupper(bin_names)) 51 | } else { 52 | si_names 53 | }) 54 | symbol <- valid_names[pmatch(symbol, valid_names, duplicates.ok = TRUE)] 55 | if (any(is.na(symbol))) { 56 | stop(gettextf("Symbol must be one of %s", paste(dQuote(valid_names), collapse = ", "))) 57 | } 58 | base <- switch(units, binary = 1024, si = 1000) 59 | out_names <- switch(units, binary = bin_names, si = si_names) 60 | sym_len <- length(symbol) 61 | inp_len <- length(x) 62 | if (sym_len == 1) { 63 | symbol <- rep(symbol, inp_len) 64 | sym_len <- inp_len 65 | } 66 | if (sym_len != inp_len) { 67 | stop("Symbols argument must be either long 1 or of the same length as the input vector.") 68 | } 69 | symbol <- ifelse(symbol == "auto", 70 | pmax(floor(log(x, base)), 0), 71 | match(tolower(symbol), tolower(out_names)) - 1) 72 | if (only_highest) { 73 | symbol <- max(symbol, na.rm = TRUE) 74 | } 75 | res <- paste(scales::comma(round(x / base^symbol, 1L)), 76 | out_names[symbol + 1]) 77 | ifelse(!is.na(x), res, x) 78 | } 79 | 80 | 81 | -------------------------------------------------------------------------------- /R/fortify.r: -------------------------------------------------------------------------------- 1 | #' Fortify contingency tables 2 | #' 3 | #' @param model the contingency table 4 | #' @param data data (unused) 5 | #' @param ... (unused) 6 | #' @export 7 | fortify.table <- function(model, data, ...) { 8 | as_tibble(as.data.frame(model, stringsAsFactors=FALSE)) 9 | } 10 | -------------------------------------------------------------------------------- /R/geom2plotly.r: -------------------------------------------------------------------------------- 1 | #' @name plotly_helpers 2 | #' @title Plotly helpers 3 | #' @description Helper functions to make it easier to automatically create plotly charts 4 | #' @export 5 | to_basic.GeomXspline <- to_basic.GeomXspline2 <- 6 | getFromNamespace("to_basic.GeomLine", asNamespace("plotly")) 7 | 8 | #' @rdname plotly_helpers 9 | #' @export 10 | to_basic.GeomBkde2d <- 11 | getFromNamespace("to_basic.GeomDensity2d", asNamespace("plotly")) 12 | 13 | #' @rdname plotly_helpers 14 | #' @param data,prestats_data,layout,params,p,... plotly interface parameters 15 | #' @keywords internal 16 | #' @export 17 | to_basic.GeomStateface <- function(data, prestats_data, layout, params, p, ...) { 18 | prefix_class(data, "GeomText") 19 | } 20 | 21 | prefix_class <- function(x, y) { 22 | structure(x, class = unique(c(y, class(x)))) 23 | } 24 | -------------------------------------------------------------------------------- /R/geom_ash.r: -------------------------------------------------------------------------------- 1 | #' Compute and display a univariate averaged shifted histogram (polynomial kernel) 2 | #' 3 | #' See \code{\link[ash]{bin1}} & \code{\link[ash]{ash1}} for more information. 4 | #' 5 | #' \if{html}{ 6 | #' A sample of the output from \code{stat_ash()}: 7 | #' 8 | #' \figure{statash01.png}{options: width="100\%" alt="Figure: statash01.png"} 9 | #' } 10 | #' 11 | #' \if{latex}{ 12 | #' A sample of the output from \code{stat_ash()}: 13 | #' 14 | #' \figure{statash01.png}{options: width=10cm} 15 | #' } 16 | #' 17 | #' @inheritParams ggplot2::geom_area 18 | #' @param geom Use to override the default Geom 19 | #' @param ab half-open interval for bins \emph{[a,b)}. If no value is specified, 20 | #' the range of x is stretched by \code{5\%} at each end and used the 21 | #' interval. 22 | #' @param nbin number of bins desired. Default \code{50}. 23 | #' @param m integer smoothing parameter; Default \code{5}. 24 | #' @param kopt vector of length 2 specifying the kernel, which is proportional 25 | #' to \emph{( 1 - abs(i/m)^kopt(1) )i^kopt(2)}; (2,2)=biweight (default); 26 | #' (0,0)=uniform; (1,0)=triangle; (2,1)=Epanechnikov; (2,3)=triweight. 27 | #' @references David Scott (1992), \emph{"Multivariate Density Estimation,"} 28 | #' John Wiley, (chapter 5 in particular).\cr 29 | #' \cr 30 | #' B. W. Silverman (1986), \emph{"Density Estimation for Statistics 31 | #' and Data Analysis,"} Chapman & Hall. 32 | #' @section Aesthetics: 33 | #' \code{geom_ash} understands the following aesthetics (required aesthetics 34 | #' are in bold): 35 | #' \itemize{ 36 | #' \item \strong{\code{x}} 37 | #' \item \code{alpha} 38 | #' \item \code{color} 39 | #' \item \code{fill} 40 | #' \item \code{linetype} 41 | #' \item \code{size} 42 | #' } 43 | #' @section Computed variables: 44 | #' \describe{ 45 | #' \item{\code{density}}{ash density estimate} 46 | #' } 47 | #' @export 48 | #' @examples 49 | #' # compare 50 | #' library(gridExtra) 51 | #' set.seed(1492) 52 | #' dat <- data.frame(x=rnorm(100)) 53 | #' grid.arrange(ggplot(dat, aes(x)) + stat_ash(), 54 | #' ggplot(dat, aes(x)) + stat_bkde(), 55 | #' ggplot(dat, aes(x)) + stat_density(), 56 | #' nrow=3) 57 | #' 58 | #' cols <- RColorBrewer::brewer.pal(3, "Dark2") 59 | #' ggplot(dat, aes(x)) + 60 | #' stat_ash(alpha=1/2, fill=cols[3]) + 61 | #' stat_bkde(alpha=1/2, fill=cols[2]) + 62 | #' stat_density(alpha=1/2, fill=cols[1]) + 63 | #' geom_rug() + 64 | #' labs(x=NULL, y="density/estimate") + 65 | #' scale_x_continuous(expand=c(0,0)) + 66 | #' theme_bw() + 67 | #' theme(panel.grid=element_blank()) + 68 | #' theme(panel.border=element_blank()) 69 | stat_ash <- function(mapping = NULL, data = NULL, geom = "area", 70 | position = "stack", 71 | ab = NULL, nbin = 50, m = 5, kopt = c(2, 2), 72 | na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, ...) { 73 | 74 | layer( 75 | data = data, 76 | mapping = mapping, 77 | stat = StatAsh, 78 | geom = geom, 79 | position = position, 80 | show.legend = show.legend, 81 | inherit.aes = inherit.aes, 82 | params = list( 83 | na.rm = na.rm, 84 | ab = ab, 85 | nbin = nbin, 86 | m = m, 87 | kopt = kopt, 88 | ... 89 | ) 90 | ) 91 | 92 | } 93 | 94 | #' Geom Proto 95 | #' @rdname ggalt-ggproto 96 | #' @format NULL 97 | #' @usage NULL 98 | #' @keywords internal 99 | #' @export 100 | StatAsh <- ggproto("StatAsh", Stat, 101 | 102 | required_aes = c("x"), 103 | 104 | default_aes = aes(y = ..density.., colour = NA, fill = "gray20", size = 0.5, 105 | linetype = 1, alpha = NA), 106 | 107 | 108 | setup_params = function(data, params) { 109 | if (!is.null(data$y) || !is.null(params$y)) { 110 | stop("stat_ash() must not be used with a y aesthetic.", call. = FALSE) 111 | } 112 | params 113 | }, 114 | 115 | compute_group = function(data, scales, ab = NULL, 116 | nbin = 50, m = 5, kopt = c(2, 2)) { 117 | 118 | if (is.null(ab)) ab <- nicerange(data$x) 119 | 120 | bin_res <- ash::bin1(data$x, ab, nbin) 121 | ash_msg <- capture.output(ash_res <- ash1(bin_res)) 122 | 123 | if (ash_res$ier == 1) message("Estimate nonzero outside interval ab.") 124 | 125 | data.frame(x=ash_res$x, density=ash_res$y) 126 | 127 | } 128 | 129 | ) 130 | 131 | nicerange <- function (x, beta = 0.1) { 132 | ab <- range(x) 133 | del <- ((ab[2] - ab[1]) * beta)/2 134 | return(c(ab + c(-del, del))) 135 | } 136 | -------------------------------------------------------------------------------- /R/geom_bkde.r: -------------------------------------------------------------------------------- 1 | #' Display a smooth density estimate. 2 | #' 3 | #' A kernel density estimate, useful for displaying the distribution of 4 | #' variables with underlying smoothness. 5 | #' 6 | #' \if{html}{ 7 | #' A sample of the output from \code{geom_bkde()}: 8 | #' 9 | #' \figure{geombkde01.png}{options: width="100\%" alt="Figure: geombkde01.png"} 10 | #' } 11 | #' 12 | #' \if{latex}{ 13 | #' A sample of the output from \code{geom_bkde()}: 14 | #' 15 | #' \figure{geombkde01.png}{options: width=10cm} 16 | #' } 17 | #' 18 | #' @section Aesthetics: 19 | #' \code{geom_bkde} understands the following aesthetics (required aesthetics 20 | #' are in bold): 21 | #' \itemize{ 22 | #' \item \strong{\code{x}} 23 | #' \item \strong{\code{y}} 24 | #' \item \code{alpha} 25 | #' \item \code{color} 26 | #' \item \code{fill} 27 | #' \item \code{linetype} 28 | #' \item \code{size} 29 | #' } 30 | #' @inheritParams ggplot2::geom_point 31 | #' @param geom,stat Use to override the default connection between 32 | #' \code{geom_bkde} and \code{stat_bkde}. 33 | #' @seealso See \code{\link{geom_histogram}}, \code{\link{geom_freqpoly}} for 34 | #' other methods of displaying continuous distribution. 35 | #' See \code{\link{geom_violin}} for a compact density display. 36 | #' @export 37 | geom_bkde <- function(mapping = NULL, data = NULL, stat = "bkde", 38 | position = "identity", bandwidth=NULL, range.x=NULL, 39 | na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, 40 | ...) { 41 | 42 | layer( 43 | data = data, 44 | mapping = mapping, 45 | stat = stat, 46 | geom = GeomBkde, 47 | position = position, 48 | show.legend = show.legend, 49 | inherit.aes = inherit.aes, 50 | params = list(bandwidth=bandwidth, 51 | range.x=range.x, 52 | na.rm=na.rm, 53 | ...) 54 | ) 55 | } 56 | 57 | #' Geom Proto 58 | #' @rdname ggalt-ggproto 59 | #' @format NULL 60 | #' @usage NULL 61 | #' @keywords internal 62 | #' @export 63 | GeomBkde <- ggproto("GeomBkde", GeomArea, 64 | default_aes = aes(colour = NA, fill = "gray20", size = 0.5, 65 | linetype = 1, alpha = NA) 66 | ) 67 | 68 | 69 | #' @param bandwidth the kernel bandwidth smoothing parameter. see 70 | #' \code{\link[KernSmooth]{bkde}} for details. If \code{NULL}, 71 | #' it will be computed for you but will most likely not yield optimal 72 | #' results. 73 | #' @param kernel character string which determines the smoothing kernel. see 74 | #' \code{\link[KernSmooth]{bkde}} for details 75 | #' @param canonical logical flag: if TRUE, canonically scaled kernels are used. 76 | #' see \code{\link[KernSmooth]{bkde}} for details 77 | #' @param gridsize the number of equally spaced points at which to estimate the 78 | #' density. see \code{\link[KernSmooth]{bkde}} for details. 79 | #' @param range.x vector containing the minimum and maximum values of x at which 80 | #' to compute the estimate. see \code{\link[KernSmooth]{bkde}} for details 81 | #' @param truncate logical flag: if TRUE, data with x values outside the range 82 | #' specified by range.x are ignored. see \code{\link[KernSmooth]{bkde}} 83 | #' for details 84 | #' @section Computed variables: 85 | #' \describe{ 86 | #' \item{density}{density estimate} 87 | #' \item{count}{density * number of points - useful for stacked density 88 | #' plots} 89 | #' \item{scaled}{density estimate, scaled to maximum of 1} 90 | #' } 91 | #' @export 92 | #' @rdname geom_bkde 93 | #' @examples 94 | #' data(geyser, package="MASS") 95 | #' 96 | #' ggplot(geyser, aes(x=duration)) + 97 | #' stat_bkde(alpha=1/2) 98 | #' 99 | #' ggplot(geyser, aes(x=duration)) + 100 | #' geom_bkde(alpha=1/2) 101 | #' 102 | #' ggplot(geyser, aes(x=duration)) + 103 | #' stat_bkde(bandwidth=0.25) 104 | #' 105 | #' ggplot(geyser, aes(x=duration)) + 106 | #' geom_bkde(bandwidth=0.25) 107 | stat_bkde <- function(mapping = NULL, data = NULL, geom = "area", 108 | position = "stack", kernel="normal", canonical=FALSE, 109 | bandwidth = NULL, gridsize=410, range.x=NULL, 110 | truncate=TRUE, na.rm=FALSE, show.legend = NA, inherit.aes = TRUE, 111 | ...) { 112 | 113 | layer( 114 | data = data, 115 | mapping = mapping, 116 | stat = StatBkde, 117 | geom = geom, 118 | position = position, 119 | show.legend = show.legend, 120 | inherit.aes = inherit.aes, 121 | params = list( 122 | kernel=kernel, 123 | canonical=canonical, 124 | bandwidth=bandwidth, 125 | gridsize=gridsize, 126 | range.x=range.x, 127 | truncate=truncate, 128 | na.rm=na.rm, 129 | ... 130 | ) 131 | ) 132 | } 133 | 134 | #' @rdname ggalt-ggproto 135 | #' @format NULL 136 | #' @usage NULL 137 | #' @export 138 | StatBkde <- ggproto("StatBkde", Stat, 139 | 140 | required_aes = "x", 141 | 142 | default_aes = aes(y = ..density.., colour = NA, fill = "gray20", size = 0.5, 143 | linetype = 1, alpha = NA), 144 | 145 | compute_group = function(data, scales, kernel="normal", canonical=FALSE, 146 | bandwidth=NULL, gridsize=410, range.x=NULL, 147 | truncate=TRUE, na.rm = TRUE) { 148 | 149 | # KernSmooth::dpik uses a generated normal distribution as part of its 150 | # operation but doesn't do this seed save/create/restore. When bandwidth 151 | # is NULL the only way to produce consistency in calculated resuts is to use 152 | # a dedicated random seed. This might be a candidate for parameterization. 153 | 154 | if (is.null(bandwidth)) { 155 | tmp <- tempfile() 156 | on.exit(unlink(tmp)) 157 | save(".Random.seed", file=tmp) 158 | set.seed(1492) 159 | bandwidth <- KernSmooth::dpik(data$x) 160 | message( 161 | sprintf("Bandwidth not specified. Using '%3.2f', via KernSmooth::dpik.", 162 | bandwidth)) 163 | load(tmp) 164 | } 165 | 166 | if (is.null(range.x)) range.x <- range(data$x) 167 | 168 | compute_bkde(data$x, kernel=kernel, canonical=canonical, 169 | bandwidth=bandwidth, gridsize=gridsize, range.x=range.x, 170 | truncate=truncate, na.rm) 171 | 172 | } 173 | 174 | ) 175 | 176 | compute_bkde <- function(x, kernel="normal", canonical=FALSE, 177 | bandwidth, gridsize=410, range.x, truncate=TRUE, na.rm=TRUE) { 178 | 179 | n <- length(x) 180 | 181 | if (missing(range.x) | is.null(range.x)) range.x <- range(x) 182 | 183 | dens <- KernSmooth::bkde(x, kernel, canonical, bandwidth, gridsize, range.x, truncate) 184 | 185 | data.frame( 186 | x = dens$x, 187 | density = dens$y, 188 | scaled = dens$y / max(dens$y, na.rm = na.rm), 189 | count = dens$y * n, 190 | n = n 191 | ) 192 | } 193 | -------------------------------------------------------------------------------- /R/geom_bkde2d.r: -------------------------------------------------------------------------------- 1 | #' Contours from a 2d density estimate. 2 | #' 3 | #' @inheritParams ggplot2::geom_point 4 | #' @inheritParams ggplot2::geom_path 5 | #' @export 6 | #' @examples 7 | #' m <- ggplot(faithful, aes(x = eruptions, y = waiting)) + 8 | #' geom_point() + 9 | #' xlim(0.5, 6) + 10 | #' ylim(40, 110) 11 | #' 12 | #' m + geom_bkde2d(bandwidth=c(0.5, 4)) 13 | #' 14 | #' m + stat_bkde2d(bandwidth=c(0.5, 4), aes(fill = ..level..), geom = "polygon") 15 | #' 16 | #' # If you map an aesthetic to a categorical variable, you will get a 17 | #' # set of contours for each value of that variable 18 | #' set.seed(4393) 19 | #' dsmall <- diamonds[sample(nrow(diamonds), 1000), ] 20 | #' d <- ggplot(dsmall, aes(x, y)) + 21 | #' geom_bkde2d(bandwidth=c(0.5, 0.5), aes(colour = cut)) 22 | #' d 23 | #' 24 | #' # If we turn contouring off, we can use use geoms like tiles: 25 | #' d + stat_bkde2d(bandwidth=c(0.5, 0.5), geom = "raster", 26 | #' aes(fill = ..density..), contour = FALSE) 27 | #' 28 | #' # Or points: 29 | #' d + stat_bkde2d(bandwidth=c(0.5, 0.5), geom = "point", 30 | #' aes(size = ..density..), contour = FALSE) 31 | geom_bkde2d <- function(mapping = NULL, data = NULL, stat = "bkde2d", 32 | position = "identity", bandwidth=NULL, range.x=NULL, 33 | lineend = "butt", contour=TRUE, 34 | linejoin = "round", linemitre = 1, 35 | na.rm = FALSE, show.legend = NA, 36 | inherit.aes = TRUE, ...) { 37 | layer( 38 | data = data, 39 | mapping = mapping, 40 | stat = stat, 41 | geom = GeomBkde2d, 42 | position = position, 43 | show.legend = show.legend, 44 | inherit.aes = inherit.aes, 45 | params = list( 46 | lineend = lineend, 47 | linejoin = linejoin, 48 | linemitre = linemitre, 49 | bandwidth = bandwidth, 50 | range.x = range.x, 51 | na.rm = na.rm, 52 | ... 53 | ) 54 | ) 55 | } 56 | 57 | 58 | #' Geom Proto 59 | #' @rdname ggalt-ggproto 60 | #' @format NULL 61 | #' @usage NULL 62 | #' @keywords internal 63 | #' @export 64 | GeomBkde2d <- ggproto("GeomBkde2d", GeomPath, 65 | default_aes = aes(colour = "#3366FF", size = 0.5, linetype = 1, alpha = NA) 66 | ) 67 | 68 | 69 | #' Contours from a 2d density estimate. 70 | #' 71 | #' Perform a 2D kernel density estimation using \code{bkde2D} and display the 72 | #' results with contours. This can be useful for dealing with overplotting 73 | #' 74 | #' \if{html}{ 75 | #' A sample of the output from \code{geom_bkde2d()}: 76 | #' 77 | #' \figure{geombkde2d01.png}{options: width="100\%" alt="Figure: geombkde2d01.png"} 78 | #' } 79 | #' 80 | #' \if{latex}{ 81 | #' A sample of the output from \code{geom_bkde2d()}: 82 | #' 83 | #' \figure{geombkde2d01.png}{options: width=10cm} 84 | #' } 85 | #' 86 | #' @param bandwidth the kernel bandwidth smoothing parameter. see 87 | #' \code{\link[KernSmooth]{bkde2D}} for details. If \code{NULL}, 88 | #' it will be computed for you but will most likely not yield optimal 89 | #' results. see \code{\link[KernSmooth]{bkde2D}} for details 90 | #' @param grid_size vector containing the number of equally spaced points in each 91 | #' direction over which the density is to be estimated. see 92 | #' \code{\link[KernSmooth]{bkde2D}} for details 93 | #' @param geom default geom to use with this stat 94 | #' @param range.x a list containing two vectors, where each vector contains the 95 | #' minimum and maximum values of x at which to compute the estimate for 96 | #' each direction. see \code{\link[KernSmooth]{bkde2D}} for details 97 | #' @param truncate logical flag: if TRUE, data with x values outside the range 98 | #' specified by range.x are ignored. see \code{\link[KernSmooth]{bkde2D}} 99 | #' for details 100 | #' @param contour If \code{TRUE}, contour the results of the 2d density 101 | #' estimation 102 | #' @section Computed variables: 103 | #' Same as \code{\link{stat_contour}} 104 | #' @seealso \code{\link{geom_contour}} for contour drawing geom, 105 | #' \code{\link{stat_sum}} for another way of dealing with overplotting 106 | #' @rdname geom_bkde2d 107 | #' @export 108 | stat_bkde2d <- function(mapping = NULL, data = NULL, geom = "density2d", 109 | position = "identity", contour = TRUE, 110 | bandwidth=NULL, grid_size=c(51, 51), range.x=NULL, 111 | truncate=TRUE, na.rm = FALSE, show.legend = NA, 112 | inherit.aes = TRUE, ...) { 113 | layer( 114 | data = data, 115 | mapping = mapping, 116 | stat = StatBkde2d, 117 | geom = geom, 118 | position = position, 119 | show.legend = show.legend, 120 | inherit.aes = inherit.aes, 121 | params = list( 122 | bandwidth = bandwidth, 123 | grid_size = grid_size, 124 | range.x = range.x, 125 | truncate = truncate, 126 | contour = contour, 127 | na.rm = na.rm, 128 | ... 129 | ) 130 | ) 131 | } 132 | 133 | #' @rdname ggalt-ggproto 134 | #' @format NULL 135 | #' @usage NULL 136 | #' @export 137 | StatBkde2d <- ggproto("StatBkde2d", Stat, 138 | 139 | default_aes = aes(colour = "#3366FF", size = 0.5), 140 | 141 | required_aes = c("x", "y"), 142 | 143 | compute_group = function(data, scales, contour=TRUE, bandwidth=NULL, 144 | grid_size=c(51, 51), range.x=NULL, 145 | truncate=TRUE) { 146 | 147 | # See geom_bkde/stat_bkde 148 | if (is.null(bandwidth)) { 149 | tmp <- tempfile() 150 | on.exit(unlink(tmp)) 151 | save(".Random.seed", file=tmp) 152 | set.seed(1492) 153 | bandwidth <- c(KernSmooth::dpik(data$x), 154 | KernSmooth::dpik(data$y)) 155 | message( 156 | sprintf("Bandwidth not specified. Using ['%3.2f', '%3.2f'], via KernSmooth::dpik.", 157 | bandwidth[1], bandwidth[2])) 158 | load(tmp) 159 | } 160 | 161 | if (is.null(range.x)) { 162 | x_range <- range(data$x) 163 | y_range <- range(data$y) 164 | x_range[1] <- x_range[1] - 1.75 * bandwidth[1] 165 | x_range[2] <- x_range[2] + 1.75 * bandwidth[1] 166 | y_range[1] <- y_range[1] - 1.75 * bandwidth[2] 167 | y_range[2] <- y_range[2] + 1.75 * bandwidth[2] 168 | range.x <- list(x_range, y_range) 169 | } 170 | 171 | dens <- KernSmooth::bkde2D( 172 | as.matrix(data.frame(x=data$x, y=data$y)), 173 | bandwidth, 174 | grid_size, 175 | range.x, 176 | truncate 177 | ) 178 | 179 | df <- data.frame(expand.grid(x=dens$x1, 180 | y=dens$x2), 181 | z=as.vector(dens$fhat)) 182 | df$group <- data$group[1] 183 | 184 | if (contour) { 185 | StatContour$compute_panel(df, scales) 186 | } else { 187 | names(df) <- c("x", "y", "density", "group") 188 | df$level <- 1 189 | df$piece <- 1 190 | df 191 | } 192 | 193 | } 194 | 195 | ) 196 | -------------------------------------------------------------------------------- /R/geom_cartogram.r: -------------------------------------------------------------------------------- 1 | #' Map polygons layer enabling the display of show statistical information 2 | #' 3 | #' This replicates the old behaviour of \code{geom_map()}, enabling specifying of 4 | #' \code{x} and \code{y} aesthetics. 5 | #' 6 | #' @section Aesthetics: 7 | #' \code{geom_cartogram} understands the following aesthetics (required aesthetics are in bold): 8 | #' \itemize{ 9 | #' \item \code{map_id} 10 | #' \item \code{alpha} 11 | #' \item \code{colour} 12 | #' \item \code{fill} 13 | #' \item \code{group} 14 | #' \item \code{linetype} 15 | #' \item \code{size} 16 | #' \item \code{x} 17 | #' \item \code{y} 18 | #' } 19 | #' 20 | #' @export 21 | #' @param map Data frame that contains the map coordinates. This will 22 | #' typically be created using \code{\link{fortify}} on a spatial object. 23 | #' It must contain columns \code{x}, \code{long} or \code{longitude}, 24 | #' \code{y}, \code{lat} or \code{latitude} and \code{region} or \code{id}. 25 | #' @inheritParams ggplot2::layer 26 | #' @inheritParams ggplot2::geom_point 27 | #' @examples \dontrun{ 28 | #' # When using geom_polygon, you will typically need two data frames: 29 | #' # one contains the coordinates of each polygon (positions), and the 30 | #' # other the values associated with each polygon (values). An id 31 | #' # variable links the two together 32 | #' 33 | #' ids <- factor(c("1.1", "2.1", "1.2", "2.2", "1.3", "2.3")) 34 | #' 35 | #' values <- data.frame( 36 | #' id = ids, 37 | #' value = c(3, 3.1, 3.1, 3.2, 3.15, 3.5) 38 | #' ) 39 | #' 40 | #' positions <- data.frame( 41 | #' id = rep(ids, each = 4), 42 | #' x = c(2, 1, 1.1, 2.2, 1, 0, 0.3, 1.1, 2.2, 1.1, 1.2, 2.5, 1.1, 0.3, 43 | #' 0.5, 1.2, 2.5, 1.2, 1.3, 2.7, 1.2, 0.5, 0.6, 1.3), 44 | #' y = c(-0.5, 0, 1, 0.5, 0, 0.5, 1.5, 1, 0.5, 1, 2.1, 1.7, 1, 1.5, 45 | #' 2.2, 2.1, 1.7, 2.1, 3.2, 2.8, 2.1, 2.2, 3.3, 3.2) 46 | #' ) 47 | #' 48 | #' ggplot() + 49 | #' geom_cartogram(aes(x, y, map_id = id), map = positions, data=positions) 50 | #' 51 | #' ggplot() + 52 | #' geom_cartogram(aes(x, y, map_id = id), map = positions, data=positions) + 53 | #' geom_cartogram(data=values, map=positions, aes(fill = value, map_id=id)) 54 | #' 55 | #' ggplot() + 56 | #' geom_cartogram(aes(x, y, map_id = id), map = positions, data=positions) + 57 | #' geom_cartogram(data=values, map=positions, aes(fill = value, map_id=id)) + 58 | #' ylim(0, 3) 59 | #' 60 | #' # Better example 61 | #' crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests) 62 | #' crimesm <- reshape2::melt(crimes, id = 1) 63 | #' 64 | #' if (require(maps)) { 65 | #' 66 | #' states_map <- map_data("state") 67 | #' 68 | #' ggplot() + 69 | #' geom_cartogram(aes(long, lat, map_id = region), map = states_map, data=states_map) + 70 | #' geom_cartogram(aes(fill = Murder, map_id = state), map=states_map, data=crimes) 71 | #' 72 | #' last_plot() + coord_map("polyconic") 73 | #' 74 | #' ggplot() + 75 | #' geom_cartogram(aes(long, lat, map_id=region), map = states_map, data=states_map) + 76 | #' geom_cartogram(aes(fill = value, map_id=state), map = states_map, data=crimesm) + 77 | #' coord_map("polyconic") + 78 | #' facet_wrap( ~ variable) 79 | #' } 80 | #' } 81 | geom_cartogram <- function(mapping = NULL, data = NULL, 82 | stat = "identity", 83 | ..., 84 | map, 85 | na.rm = FALSE, 86 | show.legend = NA, 87 | inherit.aes = TRUE) { 88 | 89 | # Get map input into correct form 90 | 91 | stopifnot(is.data.frame(map)) 92 | 93 | if (!is.null(map$latitude)) map$y <- map$latitude 94 | if (!is.null(map$lat)) map$y <- map$lat 95 | 96 | if (!is.null(map$longitude)) map$x <- map$longitude 97 | if (!is.null(map$long)) map$x <- map$long 98 | 99 | if (!is.null(map$region)) map$id <- map$region 100 | 101 | stopifnot(all(c("x", "y", "id") %in% names(map))) 102 | 103 | layer( 104 | data = data, 105 | mapping = mapping, 106 | stat = stat, 107 | geom = GeomCartogram, 108 | position = PositionIdentity, 109 | show.legend = show.legend, 110 | inherit.aes = inherit.aes, 111 | params = list( 112 | map = map, 113 | na.rm = na.rm, 114 | ... 115 | ) 116 | ) 117 | } 118 | 119 | #' Geom Cartogram 120 | #' @rdname ggplot2-ggproto 121 | #' @format NULL 122 | #' @usage NULL 123 | #' @export 124 | GeomCartogram <- ggproto("GeomCartogram", GeomPolygon, 125 | draw_panel = function(data, panel_scales, coord, map) { 126 | # Only use matching data and map ids 127 | common <- intersect(data$map_id, map$id) 128 | data <- data[data$map_id %in% common, , drop = FALSE] 129 | map <- map[map$id %in% common, , drop = FALSE] 130 | 131 | # Munch, then set up id variable for polygonGrob - 132 | # must be sequential integers 133 | coords <- coord_munch(coord, map, panel_scales) 134 | coords$group <- coords$group %||% coords$id 135 | grob_id <- match(coords$group, unique(coords$group)) 136 | 137 | # Align data with map 138 | data_rows <- match(coords$id[!duplicated(grob_id)], data$map_id) 139 | data <- data[data_rows, , drop = FALSE] 140 | 141 | grid::polygonGrob(coords$x, coords$y, default.units = "native", id = grob_id, 142 | gp = gpar( 143 | col = data$colour, fill = alpha(data$fill, data$alpha), 144 | lwd = data$size * .pt 145 | ) 146 | ) 147 | }, 148 | 149 | optional_aes = c("x", "y"), 150 | required_aes = c("map_id") 151 | 152 | ) 153 | -------------------------------------------------------------------------------- /R/geom_dumbbell.R: -------------------------------------------------------------------------------- 1 | #' Dumbbell charts 2 | #' 3 | #' The dumbbell geom is used to create dumbbell charts. 4 | #' 5 | #' Dumbbell dot plots — dot plots with two or more series of data — are an 6 | #' alternative to the clustered bar chart or slope graph. 7 | #' 8 | #' @section Aesthetics: 9 | #' \Sexpr[results=rd,stage=build]{ggplot2:::rd_aesthetics("geom", "segment")} 10 | #' @inheritParams ggplot2::layer 11 | #' @param na.rm If \code{FALSE} (the default), removes missing values with 12 | #' a warning. If \code{TRUE} silently removes missing values. 13 | #' @param ... other arguments passed on to \code{\link{layer}}. These are 14 | #' often aesthetics, used to set an aesthetic to a fixed value, like 15 | #' \code{color = "red"} or \code{size = 3}. They may also be parameters 16 | #' to the paired geom/stat. 17 | #' @param size_x the size of the start point 18 | #' @param colour_x the colour of the start point 19 | #' @param size_xend the size of the end point 20 | #' @param colour_xend the colour of the end point 21 | #' @param dot_guide if \code{TRUE}, a leading dotted line will be placed before the left-most dumbbell point 22 | #' @param dot_guide_size,dot_guide_colour singe-value aesthetics for \code{dot_guide} 23 | #' @param position Position adjustment, either as a string, or the result of a 24 | #' call to a position adjustment function. 25 | #' @inheritParams ggplot2::layer 26 | #' @export 27 | #' @examples 28 | #' library(ggplot2) 29 | #' 30 | #' df <- data.frame(trt=LETTERS[1:5], l=c(20, 40, 10, 30, 50), r=c(70, 50, 30, 60, 80)) 31 | #' 32 | #' ggplot(df, aes(y=trt, x=l, xend=r)) + 33 | #' geom_dumbbell(size=3, color="#e3e2e1", 34 | #' colour_x = "#5b8124", colour_xend = "#bad744", 35 | #' dot_guide=TRUE, dot_guide_size=0.25) + 36 | #' labs(x=NULL, y=NULL, title="ggplot2 geom_dumbbell with dot guide") + 37 | #' theme_minimal() + 38 | #' theme(panel.grid.major.x=element_line(size=0.05)) 39 | #' 40 | #' ## with vertical dodging 41 | #' df2 <- data.frame(trt = c(LETTERS[1:5], "D"), 42 | #' l = c(20, 40, 10, 30, 50, 40), 43 | #' r = c(70, 50, 30, 60, 80, 70)) 44 | #' 45 | #' ggplot(df2, aes(y=trt, x=l, xend=r)) + 46 | #' geom_dumbbell(size=3, color="#e3e2e1", 47 | #' colour_x = "#5b8124", colour_xend = "#bad744", 48 | #' dot_guide=TRUE, dot_guide_size=0.25, 49 | #' position=position_dodgev(height=0.4)) + 50 | #' labs(x=NULL, y=NULL, title="ggplot2 geom_dumbbell with dot guide") + 51 | #' theme_minimal() + 52 | #' theme(panel.grid.major.x=element_line(size=0.05)) 53 | geom_dumbbell <- function(mapping = NULL, data = NULL, ..., 54 | colour_x = NULL, size_x = NULL, 55 | colour_xend = NULL, size_xend = NULL, 56 | dot_guide = FALSE, dot_guide_size = NULL, 57 | dot_guide_colour = NULL, 58 | na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, 59 | position = "identity") { 60 | 61 | layer( 62 | data = data, 63 | mapping = mapping, 64 | stat = "identity", 65 | geom = GeomDumbbell, 66 | position = position, 67 | show.legend = show.legend, 68 | inherit.aes = inherit.aes, 69 | params = list( 70 | na.rm = na.rm, 71 | colour_x = colour_x, 72 | size_x = size_x, 73 | colour_xend = colour_xend, 74 | size_xend = size_xend, 75 | dot_guide = dot_guide, 76 | dot_guide_size = dot_guide_size, 77 | dot_guide_colour = dot_guide_colour, 78 | ... 79 | ) 80 | ) 81 | } 82 | 83 | #' @rdname ggalt-ggproto 84 | #' @format NULL 85 | #' @usage NULL 86 | #' @export 87 | GeomDumbbell <- ggproto("GeomDumbbell", Geom, 88 | required_aes = c("x", "xend", "y"), 89 | non_missing_aes = c("size", "shape", 90 | "colour_x", "size_x", 91 | "colour_xend", "size_xend", 92 | "dot_guide", "dot_guide_size", "dot_guide_colour"), 93 | default_aes = aes( 94 | shape = 19, colour = "black", size = 0.5, fill = NA, 95 | alpha = NA, stroke = 0.5 96 | ), 97 | 98 | setup_data = function(data, params) { 99 | transform(data, yend = y) 100 | }, 101 | 102 | draw_group = function(data, panel_scales, coord, 103 | colour_x = NULL, size_x = NULL, 104 | colour_xend = NULL, size_xend = NULL, 105 | dot_guide = NULL, dot_guide_size = NULL, 106 | dot_guide_colour = NULL) { 107 | 108 | points.x <- data 109 | points.x$colour <- colour_x %||% data$colour 110 | points.x$xend <- NULL 111 | points.x$size <- size_x %||% (data$size * 1.2) 112 | 113 | points.xend <- data 114 | points.xend$x <- points.xend$xend 115 | points.xend$xend <- NULL 116 | points.xend$colour <- colour_xend %||% data$colour 117 | points.xend$size <- size_xend %||% (data$size * 1.25) 118 | 119 | dot_df <- data 120 | dot_df$xend <- ifelse(data$xend < data$x, data$xend, data$x) 121 | dot_df$x <- -Inf 122 | dot_df$linetype <- "11" 123 | dot_df$size <- dot_guide_size %||% (data$size * 0.5) 124 | dot_df$colour <- dot_guide_colour %||% "#5b5b5b" 125 | 126 | if (is.null(dot_guide) | !dot_guide) { 127 | 128 | gList( 129 | ggplot2::GeomSegment$draw_panel(data, panel_scales, coord), 130 | ggplot2::GeomPoint$draw_panel(points.x, panel_scales, coord), 131 | ggplot2::GeomPoint$draw_panel(points.xend, panel_scales, coord) 132 | ) 133 | 134 | } else { 135 | 136 | gList( 137 | ggplot2::GeomSegment$draw_panel(dot_df, panel_scales, coord), 138 | ggplot2::GeomSegment$draw_panel(data, panel_scales, coord), 139 | ggplot2::GeomPoint$draw_panel(points.x, panel_scales, coord), 140 | ggplot2::GeomPoint$draw_panel(points.xend, panel_scales, coord) 141 | ) 142 | 143 | } 144 | 145 | }, 146 | 147 | draw_key = draw_key_point 148 | ) 149 | 150 | 151 | -------------------------------------------------------------------------------- /R/geom_encircle.r: -------------------------------------------------------------------------------- 1 | draw_key_hack <- function(data, params, size) { 2 | data$fill <- alpha(data$fill, data$alpha) 3 | data$alpha <- 1 4 | 5 | grobTree( 6 | if (!is.na(data$fill)) grid::rectGrob(gp = gpar(col = NA, fill = data$fill)), 7 | draw_key_path(data, params) 8 | ) 9 | } 10 | 11 | #' @rdname ggalt-ggproto 12 | #' @format NULL 13 | #' @usage NULL 14 | #' @export 15 | GeomEncircle <- ggproto("GeomEncircle", Geom, 16 | required_aes = c("x", "y"), 17 | default_aes = aes(colour = "black", 18 | fill = NA, ## ??? 19 | alpha = 1, 20 | linetype=1, 21 | size=1, 22 | s_shape=0.5, ## corresponds to default shape in xspline of -0.5 23 | s_open=FALSE, 24 | expand=0.05, 25 | spread=0.1), 26 | draw_key = draw_key_hack, ## ??? 27 | 28 | draw_group = function(data, panel_scales, coord) { 29 | ## browser() 30 | coords <- coord$transform(data, panel_scales) 31 | first_row <- coords[1, , drop = FALSE] 32 | rownames(first_row) <- NULL ## prevent warning later 33 | 34 | m <- lapply(coords[,c("x","y")],mean,na.rm=TRUE) 35 | ch <- grDevices::chull(coords[c("x","y")]) 36 | 37 | mkcoords <- function(x,y) { 38 | data.frame(x,y,first_row[!names(first_row) %in% c("x","y")]) 39 | } 40 | 41 | coords <- coords[ch,] 42 | ## FIXME: using grid:: a lot. importFrom instead? 43 | 44 | ## convert from lengths to physical units, for computing *directions* 45 | cc <- function(x,dir="x") 46 | grid::convertUnit(grid::unit(x,"native"),"mm",typeFrom="dimension", 47 | axisFrom=dir,valueOnly=TRUE) 48 | 49 | ## convert back to native (e.g. native + snpc offset) 50 | cc_inv <- function(x,dir="x") 51 | grid::convertUnit(x,"native",typeFrom="location", 52 | axisFrom=dir,valueOnly=TRUE) 53 | 54 | cc_comb <- function(x1,x2,dir="x") 55 | cc_inv(unit(x1,"native")+unit(x2,"snpc"),dir=dir) 56 | 57 | ## find normalized vector: d1 and d2 have $x, $y elements 58 | normFun <- function(d1,d2) { 59 | dx <- cc(d1$x-d2$x) 60 | dy <- cc(d1$y-d2$y) 61 | r <- sqrt(dx*dx+dy*dy) 62 | list(x=dx/r,y=dy/r) 63 | } 64 | 65 | if (nrow(coords)==1) { 66 | ## only one point: make a diamond by spreading points vertically 67 | ## and horizontally 68 | coords <- with(coords, 69 | mkcoords( 70 | c(x,x+spread,x,x-spread), 71 | c(y+spread,y,y-spread,y))) 72 | } else if (nrow(coords)==2) { 73 | ## only two points: make a diamond by spreading points perpendicularly 74 | rot <- matrix(c(0,1,-1,0),2) 75 | dd <- c(rot %*% unlist(normFun(coords[1,],coords[2,])))* 76 | coords$spread 77 | coords <- with(coords, { 78 | ## figure out rotated values, then convert *back* to native units 79 | ## already in scaled units, so ignore? 80 | x <- c(x[1], 81 | m$x+dd[1], ## cc_comb(m$x,dd[1]), 82 | x[2], 83 | m$x-dd[1]) ## cc_comb(m$x,-dd[1])) 84 | y <- c(y[1], 85 | m$y+dd[2], ## cc_comb(m$y,dd[2],"y"), 86 | y[2], 87 | m$y-dd[2]) ## cc_comb(m$y,-dd[2],"y")) 88 | mkcoords(x,y) 89 | }) 90 | } 91 | 92 | disp <- normFun(coords,m) 93 | 94 | ## browser() 95 | 96 | gp <- grid::get.gpar() 97 | pars1 <- c("colour","linetype","alpha","fill","size") 98 | pars2 <- c("col","lty","alpha","fill","lwd") 99 | gp[pars2] <- first_row[pars1] 100 | grid::xsplineGrob( 101 | with(coords,unit(x,"npc")+disp$x*unit(expand,"snpc")), 102 | with(coords,unit(y,"npc")+disp$y*unit(expand,"snpc")), 103 | ## coords$x, 104 | ## coords$y, 105 | shape = coords$s_shape-1, ## kluge! 106 | open = first_row$s_open, 107 | gp = gp) 108 | } 109 | ) 110 | 111 | if (FALSE) { 112 | library("grid") 113 | library("gridBase") 114 | coords <- data.frame(x=c(1,1),y=c(1,2)*100,spread=c(0.1,0.1)) 115 | plot(y~x,data=d,xlim=c(0,3),ylim=c(0,300)) 116 | vps <- baseViewports() 117 | pushViewport(vps$inner) 118 | pushViewport(vps$figure) 119 | pushViewport(vps$plot) 120 | ## check that we're in the right place 121 | m <- as.list(colMeans(coords)) 122 | grid.points(m$x,m$y,gp=gpar(col="red")) 123 | cc <- function(x,dir="x") 124 | grid::convertUnit(grid::unit(x,"native"),"mm",typeFrom="dimension", 125 | axisFrom=dir,valueOnly=TRUE) 126 | cc_inv <- function(x,dir="x") 127 | grid::convertUnit(x,"native",typeFrom="location", 128 | axisFrom=dir,valueOnly=TRUE) 129 | 130 | cc_comb <- function(x1,x2,dir="x") 131 | cc_inv(unit(x1,"native")+unit(x2,"snpc"),dir=dir) 132 | 133 | ## find normalized vector: d1 and d2 have $x, $y elements 134 | normFun <- function(d1,d2) { 135 | dx <- cc(d1$x-d2$x) 136 | dy <- cc(d1$y-d2$y) 137 | r <- sqrt(dx*dx+dy*dy) 138 | list(x=dx/r,y=dy/r) 139 | } 140 | 141 | dd <- c(rot %*% unlist(normFun(coords[1,],coords[2,])))* 142 | coords$spread 143 | z <- with(coords, { 144 | ## figure out rotated values, then convert *back* to native units 145 | x <- c(x[1], 146 | cc_comb(m$x,dd[1]), 147 | x[2], 148 | cc_comb(m$x,-dd[1])) 149 | y <- c(y[1], 150 | cc_comb(m$y,dd[2],"y"), 151 | y[2], 152 | cc_comb(m$y,-dd[2],"y")) 153 | list(x=x,y=y) 154 | }) 155 | with(z,grid.points(x,y,gp=gpar(col="blue"))) 156 | 157 | print(grid::convertWidth(unit(1,'npc'),'native')) 158 | print(grid::convertHeight(unit(1,'npc'),'native')) 159 | 160 | } 161 | 162 | #' Automatically enclose points in a polygon 163 | #' 164 | #' @details 165 | #' \if{html}{ 166 | #' A sample of the output from \code{geom_encircle()}: 167 | #' 168 | #' \figure{geomencircle01.png}{options: width="100\%" alt="Figure: geomencircle01.png"} 169 | #' } 170 | #' 171 | #' \if{latex}{ 172 | #' A sample of the output from \code{geom_encircle()}: 173 | #' 174 | #' \figure{geomencircle01.png}{options: width=10cm} 175 | #' } 176 | #' 177 | #' @param mapping mapping 178 | #' @param data data 179 | #' @param stat stat 180 | #' @param position position 181 | #' @param na.rm na.rm 182 | #' @param show.legend show.legend 183 | #' @param inherit.aes inherit.aes 184 | #' @param ... dots 185 | #' @return adds a circle around the specified points 186 | #' @author Ben Bolker 187 | #' @export 188 | #' @examples 189 | #' d <- data.frame(x=c(1,1,2),y=c(1,2,2)*100) 190 | #' 191 | #' gg <- ggplot(d,aes(x,y)) 192 | #' gg <- gg + scale_x_continuous(expand=c(0.5,1)) 193 | #' gg <- gg + scale_y_continuous(expand=c(0.5,1)) 194 | #' 195 | #' gg + geom_encircle(s_shape=1, expand=0) + geom_point() 196 | #' 197 | #' gg + geom_encircle(s_shape=1, expand=0.1, colour="red") + geom_point() 198 | #' 199 | #' gg + geom_encircle(s_shape=0.5, expand=0.1, colour="purple") + geom_point() 200 | #' 201 | #' gg + geom_encircle(data=subset(d, x==1), colour="blue", spread=0.02) + 202 | #' geom_point() 203 | #' 204 | #' gg +geom_encircle(data=subset(d, x==2), colour="cyan", spread=0.04) + 205 | #' geom_point() 206 | #' 207 | #' gg <- ggplot(mpg, aes(displ, hwy)) 208 | #' gg + geom_encircle(data=subset(mpg, hwy>40)) + geom_point() 209 | #' gg + geom_encircle(aes(group=manufacturer)) + geom_point() 210 | #' gg + geom_encircle(aes(group=manufacturer,fill=manufacturer),alpha=0.4)+ 211 | #' geom_point() 212 | #' gg + geom_encircle(aes(group=manufacturer,colour=manufacturer))+ 213 | #' geom_point() 214 | #' 215 | #' ss <- subset(mpg,hwy>31 & displ<2) 216 | #' 217 | #' gg + geom_encircle(data=ss, colour="blue", s_shape=0.9, expand=0.07) + 218 | #' geom_point() + geom_point(data=ss, colour="blue") 219 | geom_encircle <- function(mapping = NULL, data = NULL, stat = "identity", 220 | position = "identity", na.rm = FALSE, show.legend = NA, 221 | inherit.aes = TRUE, ...) { 222 | layer( 223 | geom = GeomEncircle, mapping = mapping, data = data, stat = stat, 224 | position = position, show.legend = show.legend, inherit.aes = inherit.aes, 225 | params = list(na.rm = na.rm, ...) 226 | ) 227 | } 228 | 229 | -------------------------------------------------------------------------------- /R/geom_horizon.r: -------------------------------------------------------------------------------- 1 | #' Plot a time series as a horizon plot 2 | #' 3 | #' A horizon plot breaks the Y dimension down using colours. This is useful 4 | #' when visualising y values spanning a vast range and / or trying to highlight 5 | #' outliers without losing context of the rest of the data.\cr \cr Horizon 6 | #' plots are best viewed in an apsect ratio of very low vertical length. 7 | #' 8 | #' @md 9 | #' @section Aesthetics: `x`, `y`, `fill`. `fill` defaults to `..band..` which is 10 | #' the band number the current data fill area belongs in. 11 | #' @section Other parameters: `bandwidth`, to dictate the span of a band. 12 | #' @export 13 | geom_horizon <- function(mapping = NULL, data = NULL, show.legend = TRUE, 14 | inherit.aes = TRUE, na.rm = TRUE, bandwidth = NULL, ...) { 15 | 16 | list( 17 | layer( 18 | data = data, 19 | mapping = mapping, 20 | stat = "horizon", 21 | geom = GeomHorizon, 22 | position = 'identity', 23 | show.legend = show.legend, 24 | inherit.aes = inherit.aes, 25 | params = list(bandwidth = bandwidth, na.rm = na.rm, ...) 26 | ) 27 | ) 28 | 29 | } 30 | 31 | #' @rdname geom_horizon 32 | #' @keywords internal 33 | #' @export 34 | GeomHorizon <- ggproto("GeomHorizon", GeomArea, 35 | required_aes = c("x", "y"), 36 | default_aes = plyr::defaults( 37 | aes(fill=NA, size = 0.15, linetype = 1, alpha = NA, colour = "gray20"), 38 | ggplot2::GeomArea$default_aes 39 | ), 40 | draw_key = ggplot2::draw_key_rect 41 | ) 42 | 43 | 44 | #' Transforms data for a horizon plot 45 | #' @rdname geom_horizon 46 | #' @export 47 | stat_horizon <- function(mapping = NULL, data = NULL, geom = "horizon", show.legend = TRUE, 48 | inherit.aes = TRUE, na.rm = TRUE, bandwidth = NULL, ...) { 49 | 50 | list( 51 | layer( 52 | stat = StatHorizon, 53 | data = data, 54 | mapping = mapping, 55 | geom = geom, 56 | position = 'identity', 57 | show.legend = show.legend, 58 | inherit.aes = inherit.aes, 59 | params = list(bandwidth = bandwidth, na.rm = na.rm, ...) 60 | ) 61 | ) 62 | 63 | } 64 | 65 | #' @rdname geom_horizon 66 | #' @keywords internal 67 | #' @export 68 | StatHorizon <- ggproto( 69 | "StatHorizon", 70 | Stat, 71 | required_aes = c("x", "y"), 72 | default_aes = aes(fill=..band..), 73 | setup_params = function(data, params) { 74 | 75 | # calculating a default bandwidth 76 | if (is.null(params$bandwidth)) { 77 | params$bandwidth <- diff(range(data$y)) / 4 78 | message(sprintf("bandwidth not specified. Using computed bandwidth %s", 79 | params$bandwidth)) 80 | } 81 | 82 | params$n_min_y <- min(data$y, na.rm = TRUE) 83 | 84 | params 85 | 86 | }, 87 | 88 | compute_group = function(data, scales, bandwidth, n_min_y) { 89 | 90 | # calculating the band in which the values fall 91 | data$fillb <- ((data$y - n_min_y) %/% bandwidth) + 1 92 | 93 | # calculating the banded y value 94 | orig_y <- data$y 95 | orig_fill_b <- data$fillb 96 | 97 | data$y <- data$y - (bandwidth * (data$fillb - 1)) - n_min_y 98 | 99 | fill_bands <- sort(unique(data$fillb)) 100 | 101 | # for each band, calculating value at a particular x 102 | banded_data <- lapply( 103 | 104 | fill_bands, 105 | 106 | function(i_fill_band) { 107 | 108 | df_banded_data <- data[data$fillb == i_fill_band,] 109 | 110 | df_banded_data_high <- data[data$fillb > i_fill_band,] 111 | 112 | if (nrow(df_banded_data_high) > 0) { 113 | df_banded_data_high$y <- bandwidth 114 | df_banded_data_high$fillb <- i_fill_band 115 | } 116 | 117 | df_banded_data_low <- data[data$fillb < i_fill_band,] 118 | 119 | if (nrow(df_banded_data_low) > 0) { 120 | df_banded_data_low$y <- 0 121 | df_banded_data_low$fillb <- i_fill_band 122 | } 123 | 124 | data <- rbind( 125 | rbind(df_banded_data, df_banded_data_low), 126 | df_banded_data_high 127 | ) 128 | 129 | data$fillb <- data$fillb * bandwidth 130 | 131 | data$band <- i_fill_band 132 | data$group <- i_fill_band 133 | 134 | data 135 | 136 | } 137 | 138 | ) 139 | 140 | data <- do.call(rbind, banded_data) 141 | 142 | data$band <- factor(data$band) 143 | 144 | data 145 | 146 | } 147 | 148 | ) 149 | -------------------------------------------------------------------------------- /R/geom_lollipop.r: -------------------------------------------------------------------------------- 1 | #' Lollipop charts 2 | #' 3 | #' The lollipop geom is used to create lollipop charts. 4 | #' 5 | #' Lollipop charts are the creation of Andy Cotgreave going back to 2011. They 6 | #' are a combination of a thin segment, starting at with a dot at the top and are a 7 | #' suitable alternative to or replacement for bar charts. 8 | #' 9 | #' Use the \code{horizontal} parameter to abate the need for \code{coord_flip()} 10 | #' (see the \code{Arguments} section for details). 11 | #' 12 | #' \if{html}{ 13 | #' A sample of the output from \code{geom_lollipop()}: 14 | #' 15 | #' \figure{geomlollipop01.png}{options: width="100\%" alt="Figure: geomlollipop01.png"} 16 | #' } 17 | #' 18 | #' \if{latex}{ 19 | #' A sample of the output from \code{geom_lollipop()}: 20 | #' 21 | #' \figure{geomlollipop01.png}{options: width=10cm} 22 | #' } 23 | #' 24 | #' @section Aesthetics: 25 | #' \Sexpr[results=rd,stage=build]{ggplot2:::rd_aesthetics("geom", "point")} 26 | #' @inheritParams ggplot2::layer 27 | #' @param na.rm If \code{FALSE} (the default), removes missing values with 28 | #' a warning. If \code{TRUE} silently removes missing values. 29 | #' @param ... other arguments passed on to \code{\link{layer}}. These are 30 | #' often aesthetics, used to set an aesthetic to a fixed value, like 31 | #' \code{color = "red"} or \code{size = 3}. They may also be parameters 32 | #' to the paired geom/stat. 33 | #' @param horizontal \code{horizontal} is \code{FALSE} (the default), the function 34 | #' will draw the lollipops up from the X axis (i.e. it will set \code{xend} 35 | #' to \code{x} & \code{yend} to \code{0}). If \code{TRUE}, it wiill set 36 | #' \code{yend} to \code{y} & \code{xend} to \code{0}). Make sure you map the 37 | #' \code{x} & \code{y} aesthetics accordingly. This parameter helps avoid 38 | #' the need for \code{coord_flip()}. 39 | #' @param point.size the size of the point 40 | #' @param point.colour the colour of the point 41 | #' @inheritParams ggplot2::layer 42 | #' @export 43 | #' @examples 44 | #' df <- data.frame(trt=LETTERS[1:10], 45 | #' value=seq(100, 10, by=-10)) 46 | #' 47 | #' ggplot(df, aes(trt, value)) + geom_lollipop() 48 | #' 49 | #' ggplot(df, aes(value, trt)) + geom_lollipop(horizontal=TRUE) 50 | geom_lollipop <- function(mapping = NULL, data = NULL, ..., 51 | horizontal = FALSE, 52 | point.colour = NULL, point.size = NULL, 53 | na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { 54 | 55 | layer( 56 | data = data, 57 | mapping = mapping, 58 | stat = "identity", 59 | geom = GeomLollipop, 60 | position = "identity", 61 | show.legend = show.legend, 62 | inherit.aes = inherit.aes, 63 | params = list( 64 | na.rm = na.rm, 65 | horizontal = horizontal, 66 | point.colour = point.colour, 67 | point.size = point.size, 68 | ... 69 | ) 70 | ) 71 | } 72 | 73 | #' @rdname ggalt-ggproto 74 | #' @format NULL 75 | #' @usage NULL 76 | #' @export 77 | GeomLollipop <- ggproto("GeomLollipop", Geom, 78 | required_aes = c("x", "y"), 79 | non_missing_aes = c("size", "shape", "point.colour", "point.size", "horizontal"), 80 | default_aes = aes( 81 | shape = 19, colour = "black", size = 0.5, fill = NA, 82 | alpha = NA, stroke = 0.5 83 | ), 84 | 85 | setup_data = function(data, params) { 86 | if (params$horizontal) { 87 | transform(data, yend = y, xend = 0) 88 | } else { 89 | transform(data, xend = x, yend = 0) 90 | } 91 | }, 92 | 93 | draw_group = function(data, panel_scales, coord, 94 | point.colour = NULL, point.size = NULL, 95 | horizontal = FALSE) { 96 | 97 | points <- data 98 | points$colour <- point.colour %||% data$colour 99 | points$size <- point.size %||% (data$size * 2.5) 100 | 101 | gList( 102 | ggplot2::GeomSegment$draw_panel(data, panel_scales, coord), 103 | ggplot2::GeomPoint$draw_panel(points, panel_scales, coord) 104 | ) 105 | 106 | }, 107 | 108 | draw_key = draw_key_point 109 | ) 110 | 111 | 112 | -------------------------------------------------------------------------------- /R/geom_spikelines.R: -------------------------------------------------------------------------------- 1 | #' @title Draw spikelines on a plot 2 | #' @description Segment reference lines that originate at an point 3 | #' @inheritParams ggplot2::geom_line 4 | #' @examples 5 | #' 6 | #' mtcars$name <- rownames(mtcars) 7 | #' 8 | #' p <- ggplot(data = mtcars, aes(x=mpg,y=disp)) + geom_point() 9 | #' 10 | #' p + geom_spikelines(data = mtcars[mtcars$carb==4,],linetype = 2) 11 | #' 12 | #' p + geom_spikelines(data = mtcars[mtcars$carb==4,],aes(colour = factor(gear)), linetype = 2) 13 | #' 14 | #' \dontrun{ 15 | #' require(ggrepel) 16 | #' p + geom_spikelines(data = mtcars[mtcars$carb==4,],aes(colour = factor(gear)), linetype = 2) + 17 | #' ggrepel::geom_label_repel(data = mtcars[mtcars$carb==4,],aes(label = name)) 18 | #' } 19 | #' 20 | #' @rdname geom_spikelines 21 | #' @author Jonathan Sidi 22 | #' @export 23 | 24 | geom_spikelines <- function(mapping = NULL, data = NULL, 25 | stat = "identity", position = "identity", 26 | ..., 27 | arrow = NULL, 28 | lineend = "butt", 29 | linejoin = "round", 30 | na.rm = FALSE, 31 | show.legend = NA, 32 | inherit.aes = TRUE) { 33 | layer( 34 | data = data, 35 | mapping = mapping, 36 | stat = stat, 37 | geom = GeomSpikelines, 38 | position = position, 39 | show.legend = show.legend, 40 | inherit.aes = inherit.aes, 41 | params = list( 42 | arrow = arrow, 43 | lineend = lineend, 44 | linejoin = linejoin, 45 | na.rm = na.rm, 46 | ... 47 | ) 48 | ) 49 | } 50 | 51 | #' @rdname ggalt-ggproto 52 | #' @format NULL 53 | #' @usage NULL 54 | #' @export 55 | GeomSpikelines <- ggproto("GeomSpikelines", Geom, 56 | required_aes = c("x", "y"), 57 | non_missing_aes = c("linetype", "size", "shape"), 58 | default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA), 59 | 60 | draw_panel = function(data, panel_params, coord, arrow = NULL, 61 | lineend = "butt", linejoin = "round", na.rm = FALSE) { 62 | 63 | data1 <- data 64 | data2 <- data 65 | 66 | data1$xend <- data$x 67 | data1$yend <- data$y 68 | data1$y <- 0 69 | 70 | 71 | data2$xend <- data$x 72 | data2$yend <- data$y 73 | data2$x <- 0 74 | 75 | data <- rbind(data1,data2) 76 | 77 | data <- remove_missing(data, na.rm = na.rm, 78 | c("x", "y", "linetype", "size", "shape"), 79 | name = "geom_spikelines") 80 | if (empty(data)) return(zeroGrob()) 81 | 82 | if (coord$is_linear()) { 83 | coord <- coord$transform(data, panel_params) 84 | 85 | ret <- grid::segmentsGrob(coord$x, coord$y, coord$xend, coord$yend, 86 | default.units = "native", 87 | gp = grid::gpar( 88 | col = alpha(coord$colour, coord$alpha), 89 | fill = alpha(coord$colour, coord$alpha), 90 | lwd = coord$size * .pt, 91 | lty = coord$linetype, 92 | lineend = lineend, 93 | linejoin = linejoin 94 | ), 95 | arrow = arrow 96 | ) 97 | 98 | return(ret) 99 | } 100 | 101 | data$group <- 1:nrow(data) 102 | starts <- subset(data, select = c(-xend, -yend)) 103 | ends <- plyr::rename(subset(data, select = c(-x, -y)), c("xend" = "x", "yend" = "y"), 104 | warn_missing = FALSE) 105 | 106 | pieces <- rbind(starts, ends) 107 | pieces <- pieces[order(pieces$group),] 108 | 109 | GeomPath$draw_panel(pieces, panel_params, coord, arrow = arrow, 110 | lineend = lineend) 111 | }, 112 | 113 | draw_key = draw_key_path 114 | ) 115 | 116 | empty <- function (df) 117 | { 118 | is.null(df) || nrow(df) == 0 || ncol(df) == 0 119 | } 120 | -------------------------------------------------------------------------------- /R/geom_table.r: -------------------------------------------------------------------------------- 1 | # #' @rdname ggalt-ggproto 2 | # #' @format NULL 3 | # #' @usage NULL 4 | # #' @export 5 | # GeomTable <- ggproto( 6 | # "GeomTable", 7 | # Geom, 8 | # required_aes = c("x", "y", "table"), 9 | # default_aes = aes( 10 | # widthx = 10, 11 | # widthy = 10, 12 | # rownames = NA 13 | # ), 14 | # draw_key = draw_key_blank, 15 | # 16 | # draw_panel = function(data, panel_scales, coord) { 17 | # if (nrow(data) != 1) { 18 | # stop( 19 | # sprintf( 20 | # "only one table per panel allowed, got %s (%s)", 21 | # nrow(data), 22 | # as.character(data) 23 | # ), 24 | # call. = FALSE 25 | # ) 26 | # } 27 | # wy = data$widthy / 2 28 | # wx = data$widthx / 2 29 | # 30 | # corners <- 31 | # data.frame(x = c(data$x - wx, data$x + wx), 32 | # y = c(data$y - wy, data$y + wy)) 33 | # d <- coord$transform(corners, panel_scales) 34 | # 35 | # # gross hack, but I've found no other way to get a table/matrix/dataframe to this point :-( 36 | # table = utils::read.csv(text = data$table, header = TRUE) 37 | # if (!is.na(data$rownames)) { 38 | # rownames(table) <- 39 | # unlist(strsplit(data$rownames, "|", fixed = TRUE)) 40 | # } 41 | # 42 | # x_rng <- range(d$x, na.rm = TRUE) 43 | # y_rng <- range(d$y, na.rm = TRUE) 44 | # 45 | # vp <- 46 | # viewport( 47 | # x = mean(x_rng), 48 | # y = mean(y_rng), 49 | # width = diff(x_rng), 50 | # height = diff(y_rng), 51 | # just = c("center", "center") 52 | # ) 53 | # 54 | # grob <- 55 | # tableGrob(table, theme = ttheme_minimal()) 56 | # # add a line across the header 57 | # grob <- gtable_add_grob( 58 | # grob, 59 | # grobs = segmentsGrob(y1 = unit(0, "npc"), 60 | # gp = gpar(lwd = 2.0)), 61 | # t = 1, 62 | # b = 1, 63 | # l = 1, 64 | # r = ncol(d) + 1 65 | # ) 66 | # editGrob(grob, vp = vp, name = paste(grob$name, facet_id())) 67 | # } 68 | # ) 69 | # 70 | # facet_id <- local({ 71 | # i <- 1 72 | # function() { 73 | # i <<- i + 1 74 | # i 75 | # } 76 | # }) 77 | # 78 | # #' Add a table to a ggplot2 plot 79 | # #' 80 | # #' @export 81 | # #' @author Jan Schulz 82 | # geom_table <- function(mapping = NULL, data = NULL, stat = "identity", 83 | # position = "identity", na.rm = FALSE, 84 | # show.legend = NA, inherit.aes = TRUE, ...) { 85 | # layer( 86 | # geom = GeomTable, 87 | # mapping = mapping, 88 | # data = data, 89 | # stat = stat, 90 | # position = position, 91 | # show.legend = show.legend, 92 | # inherit.aes = inherit.aes, 93 | # params = list(na.rm = na.rm, ...) 94 | # ) 95 | # } 96 | # 97 | -------------------------------------------------------------------------------- /R/geom_twoway_bar.r: -------------------------------------------------------------------------------- 1 | # #' Two-way bar chart 2 | # #' 3 | # #' @inheritParams ggplot2::geom_bar 4 | # #' @export 5 | # geom_twoway_bar <- function(mapping = NULL, data = NULL, 6 | # stat = "identity", 7 | # width = NULL, 8 | # ..., 9 | # na.rm = FALSE, 10 | # show.legend = NA, 11 | # inherit.aes = TRUE) { 12 | # 13 | # layer( 14 | # data = data, 15 | # mapping = mapping, 16 | # stat = stat, 17 | # geom = GeomTwowayBar, 18 | # position = "stack", 19 | # show.legend = show.legend, 20 | # inherit.aes = inherit.aes, 21 | # params = list( 22 | # width = width, 23 | # na.rm = na.rm, 24 | # ... 25 | # ) 26 | # ) 27 | # } 28 | # 29 | # #' @rdname ggalt-ggproto 30 | # #' @format NULL 31 | # #' @usage NULL 32 | # #' @export 33 | # GeomTwowayBar <- ggproto("GeomTwowayBar", GeomRect, 34 | # required_aes = c("x", "y"), 35 | # 36 | # do_setup_data = function(data, params) { 37 | # data$width <- data$width %||% 38 | # params$width %||% (resolution(data$x, FALSE) * 0.9) 39 | # 40 | # d_plus <- subset(data, y>=0, drop=FALSE) 41 | # d_minus <- subset(data, y<0, drop=FALSE) 42 | # 43 | # d_plus <- transform(d_plus, 44 | # ymin = pmin(y, 0), ymax = pmax(y, 0), 45 | # xmin = x - width / 2, xmax = x + width / 2, width = NULL, 46 | # is_plus = TRUE 47 | # ) 48 | # 49 | # d_minus <- transform(d_minus, 50 | # ymin = pmin(y, 0), ymax = pmax(y, 0), 51 | # xmin = x - width / 2, xmax = x + width / 2, width = NULL, 52 | # y = abs(y), 53 | # is_plus = FALSE 54 | # ) 55 | # 56 | # cat("setup_data() after _________\n") 57 | # print(rbind(d_plus, d_minus)) 58 | # 59 | # rbind(d_plus, d_minus) 60 | # 61 | # }, 62 | # 63 | # draw_panel = function(self, data, panel_scales, coord, width=NULL) { 64 | # 65 | # cat("draw_panel() _________\n") 66 | # print(data) 67 | # # 68 | # # d_plus <- subset(data, is_plus) 69 | # # d_minus <- subset(data, !is_plus) 70 | # # d_minus$y <- -d_minus$y 71 | # 72 | # gList( 73 | # ggplot2::ggproto_parent(GeomBar, self)$draw_panel(data, panel_scales, coord) 74 | # ) 75 | # } 76 | # ) 77 | # 78 | -------------------------------------------------------------------------------- /R/geom_ubar.r: -------------------------------------------------------------------------------- 1 | #' Uniform "bar" charts 2 | #' 3 | #' I've been using `geom_segment` more to make "bar" charts, setting 4 | #' `xend` to whatever `x` is and `yend` to `0`. The bar widths remain 5 | #' constant without any tricks and you have granular control over the 6 | #' segment width. I decided it was time to make a `geom`. 7 | #' 8 | #' @md 9 | #' @section Aesthetics: 10 | #' `geom_ubar`` understands the following aesthetics (required aesthetics are in bold): 11 | #' 12 | #' - **`x`** 13 | #' - **`y`** 14 | #' - `alpha` 15 | #' - `colour` 16 | #' - `group` 17 | #' - `linetype` 18 | #' - `size` 19 | #' 20 | #' @inheritParams ggplot2::layer 21 | #' @param na.rm If `FALSE` (the default), removes missing values with 22 | #' a warning. If `TRUE` silently removes missing values. 23 | #' @param ... other arguments passed on to `layer`. These are 24 | #' often aesthetics, used to set an aesthetic to a fixed value, like 25 | #' `color = "red"` or `size = 3`. They may also be parameters 26 | #' to the paired geom/stat. 27 | #' @inheritParams ggplot2::layer 28 | #' @export 29 | #' @examples 30 | #' library(ggplot2) 31 | #' 32 | #' data(economics) 33 | #' ggplot(economics, aes(date, uempmed)) + 34 | #' geom_ubar() 35 | geom_ubar <- function(mapping = NULL, data = NULL, stat = "identity", 36 | position = "identity", ..., 37 | na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { 38 | 39 | layer( 40 | data = data, 41 | mapping = mapping, 42 | stat = "identity", 43 | geom = GeomUbar, 44 | position = "identity", 45 | show.legend = show.legend, 46 | inherit.aes = inherit.aes, 47 | params = list( 48 | na.rm = na.rm, 49 | ... 50 | ) 51 | ) 52 | } 53 | 54 | #' @rdname ggalt-ggproto 55 | #' @format NULL 56 | #' @usage NULL 57 | #' @export 58 | GeomUbar <- ggproto("GeomUbar", Geom, 59 | required_aes = c("x", "y"), 60 | non_missing_aes = c("size"), 61 | default_aes = aes( 62 | size = 0.25, colour = "black", alpha = NA 63 | ), 64 | 65 | setup_data = function(data, params) { 66 | transform(data, xend = x, yend = 0) 67 | }, 68 | 69 | draw_group = function(data, panel_scales, coord) { 70 | 71 | ggplot2::GeomSegment$draw_panel(data, panel_scales, coord) 72 | 73 | } 74 | 75 | ) 76 | 77 | 78 | -------------------------------------------------------------------------------- /R/geom_xspline.r: -------------------------------------------------------------------------------- 1 | #' Connect control points/observations with an X-spline 2 | #' 3 | #' Draw an X-spline, a curve drawn relative to control points/observations. 4 | #' Patterned after \code{geom_line} in that it orders the points by \code{x} 5 | #' first before computing the splines. 6 | #' 7 | #' \if{html}{ 8 | #' A sample of the output from \code{geom_xspline()}: 9 | #' 10 | #' \figure{geomxspline01.png}{options: width="100\%" alt="Figure: geomxspline01.png"} 11 | #' } 12 | #' 13 | #' \if{latex}{ 14 | #' A sample of the output from \code{geom_xspline()}: 15 | #' 16 | #' \figure{geomxspline01.png}{options: width=10cm} 17 | #' } 18 | #' 19 | #' @section Aesthetics: 20 | #' \code{geom_xspline} understands the following aesthetics (required aesthetics 21 | #' are in bold): 22 | #' \itemize{ 23 | #' \item \strong{\code{x}} 24 | #' \item \strong{\code{y}} 25 | #' \item \code{alpha} 26 | #' \item \code{color} 27 | #' \item \code{linetype} 28 | #' \item \code{size} 29 | #' } 30 | #' 31 | #' @seealso 32 | #' \code{\link[ggplot2]{geom_line}}: Connect observations (x order); 33 | #' \code{\link[ggplot2]{geom_path}}: Connect observations; 34 | #' \code{\link[ggplot2]{geom_polygon}}: Filled paths (polygons); 35 | #' \code{\link[ggplot2]{geom_segment}}: Line segments; 36 | #' \code{\link[graphics]{xspline}}; 37 | #' \code{\link[grid]{grid.xspline}} 38 | #' 39 | #' @details 40 | #' An X-spline is a line drawn relative to control points. For each control 41 | #' point, the line may pass through (interpolate) the control point or it may 42 | #' only approach (approximate) the control point; the behaviour is determined 43 | #' by a shape parameter for each control point. 44 | #' 45 | #' If the shape parameter is greater than zero, the spline approximates the 46 | #' control points (and is very similar to a cubic B-spline when the shape is 47 | #' 1). If the shape parameter is less than zero, the spline interpolates the 48 | #' control points (and is very similar to a Catmull-Rom spline when the shape 49 | #' is -1). If the shape parameter is 0, the spline forms a sharp corner at that 50 | #' control point. 51 | #' 52 | #' For open X-splines, the start and end control points must have a shape of 53 | #' 0 (and non-zero values are silently converted to zero). 54 | #' 55 | #' For open X-splines, by default the start and end control points are 56 | #' replicated before the curve is drawn. A curve is drawn between (interpolating 57 | #' or approximating) the second and third of each set of four control points, 58 | #' so this default behaviour ensures that the resulting curve starts at the 59 | #' first control point you have specified and ends at the last control point. 60 | #' The default behaviour can be turned off via the repEnds argument. 61 | #' 62 | #' @inheritParams ggplot2::geom_line 63 | #' @param geom,stat Use to override the default connection between 64 | #' \code{geom_xspline} and \code{stat_xspline}. 65 | #' @param spline_shape A numeric vector of values between -1 and 1, which 66 | #' control the shape of the spline relative to the control points. 67 | #' @param open A logical value indicating whether the spline is an open or a 68 | #' closed shape. 69 | #' @param rep_ends For open X-splines, a logical value indicating whether the 70 | #' first and last control points should be replicated for drawing the 71 | #' curve. Ignored for closed X-splines. 72 | #' @references Blanc, C. and Schlick, C. (1995), "X-splines : A Spline Model 73 | #' Designed for the End User", in \emph{Proceedings of SIGGRAPH 95}, 74 | #' pp. 377-386. \url{http://dept-info.labri.fr/~schlick/DOC/sig1.html} 75 | #' @export 76 | #' @family xspline implementations 77 | #' @examples 78 | #' set.seed(1492) 79 | #' dat <- data.frame(x=c(1:10, 1:10, 1:10), 80 | #' y=c(sample(15:30, 10), 2*sample(15:30, 10), 81 | #' 3*sample(15:30, 10)), 82 | #' group=factor(c(rep(1, 10), rep(2, 10), rep(3, 10))) 83 | #' ) 84 | #' 85 | #' ggplot(dat, aes(x, y, group=group, color=group)) + 86 | #' geom_point() + 87 | #' geom_line() 88 | #' 89 | #' ggplot(dat, aes(x, y, group=group, color=factor(group))) + 90 | #' geom_point() + 91 | #' geom_line() + 92 | #' geom_smooth(se=FALSE, linetype="dashed", size=0.5) 93 | #' 94 | #' ggplot(dat, aes(x, y, group=group, color=factor(group))) + 95 | #' geom_point(color="black") + 96 | #' geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 97 | #' geom_xspline(size=0.5) 98 | #' 99 | #' ggplot(dat, aes(x, y, group=group, color=factor(group))) + 100 | #' geom_point(color="black") + 101 | #' geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 102 | #' geom_xspline(spline_shape=-0.4, size=0.5) 103 | #' 104 | #' ggplot(dat, aes(x, y, group=group, color=factor(group))) + 105 | #' geom_point(color="black") + 106 | #' geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 107 | #' geom_xspline(spline_shape=0.4, size=0.5) 108 | #' 109 | #' ggplot(dat, aes(x, y, group=group, color=factor(group))) + 110 | #' geom_point(color="black") + 111 | #' geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 112 | #' geom_xspline(spline_shape=1, size=0.5) 113 | #' 114 | #' ggplot(dat, aes(x, y, group=group, color=factor(group))) + 115 | #' geom_point(color="black") + 116 | #' geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 117 | #' geom_xspline(spline_shape=0, size=0.5) 118 | #' 119 | #' ggplot(dat, aes(x, y, group=group, color=factor(group))) + 120 | #' geom_point(color="black") + 121 | #' geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 122 | #' geom_xspline(spline_shape=-1, size=0.5) 123 | geom_xspline <- function(mapping = NULL, data = NULL, stat = "xspline", 124 | position = "identity", na.rm = TRUE, show.legend = NA, 125 | inherit.aes = TRUE, 126 | spline_shape=-0.25, open=TRUE, rep_ends=TRUE, ...) { 127 | layer( 128 | geom = GeomXspline, 129 | mapping = mapping, 130 | data = data, 131 | stat = stat, 132 | position = position, 133 | show.legend = show.legend, 134 | inherit.aes = inherit.aes, 135 | params = list( 136 | spline_shape = spline_shape, 137 | open = open, 138 | na.rm = na.rm, 139 | rep_ends = rep_ends, 140 | ... 141 | ) 142 | ) 143 | } 144 | 145 | #' Geom Proto 146 | #' @rdname ggalt-ggproto 147 | #' @format NULL 148 | #' @usage NULL 149 | #' @keywords internal 150 | #' @export 151 | GeomXspline <- ggproto("GeomXspline", GeomLine, 152 | required_aes = c("x", "y"), 153 | default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA) 154 | ) 155 | 156 | #' @export 157 | #' @rdname geom_xspline 158 | #' @section Computed variables: 159 | #' \itemize{ 160 | #' \item{x} 161 | #' \item{y} 162 | #' } 163 | stat_xspline <- function(mapping = NULL, data = NULL, geom = "line", 164 | position = "identity", na.rm = TRUE, show.legend = NA, inherit.aes = TRUE, 165 | spline_shape=-0.25, open=TRUE, rep_ends=TRUE, ...) { 166 | layer( 167 | stat = StatXspline, 168 | data = data, 169 | mapping = mapping, 170 | geom = geom, 171 | position = position, 172 | show.legend = show.legend, 173 | inherit.aes = inherit.aes, 174 | params = list(spline_shape=spline_shape, 175 | open=open, 176 | na.rm = na.rm, 177 | rep_ends=rep_ends, 178 | ... 179 | ) 180 | ) 181 | } 182 | 183 | #' @rdname ggalt-ggproto 184 | #' @format NULL 185 | #' @usage NULL 186 | #' @export 187 | StatXspline <- ggproto("StatXspline", Stat, 188 | 189 | required_aes = c("x", "y"), 190 | 191 | compute_group = function(self, data, scales, params, 192 | spline_shape=-0.25, open=TRUE, rep_ends=TRUE) { 193 | 194 | tf <- tempfile(fileext=".png") 195 | png(tf) 196 | plot.new() 197 | tmp <- xspline(data$x, data$y, spline_shape, open, rep_ends, draw=FALSE, NA, NA) 198 | invisible(dev.off()) 199 | unlink(tf) 200 | 201 | data.frame(x=tmp$x, y=tmp$y) 202 | } 203 | 204 | ) 205 | -------------------------------------------------------------------------------- /R/geom_xspline2.r: -------------------------------------------------------------------------------- 1 | #' @rdname ggalt-ggproto 2 | #' @format NULL 3 | #' @usage NULL 4 | #' @export 5 | GeomXSpline2 <- ggproto("GeomXSpline", Geom, 6 | required_aes = c("x", "y"), 7 | default_aes = aes(colour = "black", s_shape=1, s_open=FALSE), 8 | draw_key = draw_key_point, 9 | 10 | draw_panel = function(data, panel_scales, coord) { 11 | coords <- coord$transform(data, panel_scales) 12 | grid::xsplineGrob( 13 | coords$x, coords$y, 14 | shape = coords$s_shape-1, ## kluge! 15 | open = coords$s_open[1], 16 | gp = grid::gpar(col = coords$colour) 17 | ) 18 | } 19 | ) 20 | 21 | #' Alternative implemenation for connecting control points/observations 22 | #' with an X-spline 23 | #' 24 | #' @inheritParams geom_xspline 25 | #' @return creates a spline curve 26 | #' @author Ben Bolker 27 | #' @family xspline implementations 28 | geom_xspline2 <- function(mapping = NULL, data = NULL, stat = "identity", 29 | position = "identity", na.rm = FALSE, show.legend = NA, 30 | inherit.aes = TRUE, ...) { 31 | layer( 32 | geom = GeomXSpline2, mapping = mapping, data = data, stat = stat, 33 | position = position, show.legend = show.legend, inherit.aes = inherit.aes, 34 | params = list(na.rm = na.rm, ...) 35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /R/ggalt-package.r: -------------------------------------------------------------------------------- 1 | #' Extra Geoms, Stats, Coords, Scales & Fonts for 'ggplot2' 2 | #' 3 | #' A package containing additional geoms, coords, stats, scales & fonts 4 | #' for ggplot2 2.0+ 5 | #' 6 | #' @name ggalt 7 | #' @docType package 8 | #' @author Bob Rudis (@@hrbrmstr) 9 | #' @import maps ggplot2 graphics grDevices KernSmooth proj4 ash MASS 10 | #' @importFrom dplyr filter 11 | #' @importFrom scales rescale expand_range comma 12 | #' @importFrom grid grobName grobTree unit.c grobHeight grobWidth viewport 13 | #' grid.draw grobX grobY gTree gList textGrob gpar pointsGrob 14 | #' segmentsGrob polygonGrob 15 | #' @importFrom gtable gtable_col gtable_height gtable_width gtable_row gtable_col 16 | #' @importFrom RColorBrewer brewer.pal 17 | #' @importFrom extrafont loadfonts fonts ttf_import 18 | #' @import datasets 19 | #' @import utils 20 | #' @importFrom tibble as_tibble 21 | NULL 22 | -------------------------------------------------------------------------------- /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/guide_axis.r: -------------------------------------------------------------------------------- 1 | # Grob for axes 2 | # 3 | # @param position of ticks 4 | # @param labels at ticks 5 | # @param position of axis (top, bottom, left or right) 6 | # @param range of data values 7 | guide_axis <- function(at, labels, position = "right", theme) { 8 | if (length(at) == 0) 9 | return(zeroGrob()) 10 | 11 | at <- unit(at, "native") 12 | position <- match.arg(position, c("top", "bottom", "right", "left")) 13 | 14 | zero <- unit(0, "npc") 15 | one <- unit(1, "npc") 16 | 17 | label_render <- switch(position, 18 | top = , bottom = "axis.text.x", 19 | left = , right = "axis.text.y" 20 | ) 21 | 22 | label_x <- switch(position, 23 | top = , 24 | bottom = at, 25 | right = theme$axis.ticks.length, 26 | left = one - theme$axis.ticks.length 27 | ) 28 | label_y <- switch(position, 29 | top = theme$axis.ticks.length, 30 | bottom = one - theme$axis.ticks.length, 31 | right = , 32 | left = at 33 | ) 34 | 35 | if (is.list(labels)) { 36 | if (any(sapply(labels, is.language))) { 37 | labels <- do.call(expression, labels) 38 | } else { 39 | labels <- unlist(labels) 40 | } 41 | } 42 | 43 | labels <- switch(position, 44 | top = , 45 | bottom = element_render(theme, label_render, labels, x = label_x, expand_y = TRUE), 46 | right = , 47 | left = element_render(theme, label_render, labels, y = label_y, expand_x = TRUE)) 48 | 49 | line <- switch(position, 50 | top = element_render(theme, "axis.line.x", c(0, 1), c(0, 0), id.lengths = 2), 51 | bottom = element_render(theme, "axis.line.x", c(0, 1), c(1, 1), id.lengths = 2), 52 | right = element_render(theme, "axis.line.y", c(0, 0), c(0, 1), id.lengths = 2), 53 | left = element_render(theme, "axis.line.y", c(1, 1), c(0, 1), id.lengths = 2) 54 | ) 55 | 56 | nticks <- length(at) 57 | 58 | ticks <- switch(position, 59 | top = element_render(theme, "axis.ticks.x", 60 | x = rep(at, each = 2), 61 | y = rep(unit.c(zero, theme$axis.ticks.length), nticks), 62 | id.lengths = rep(2, nticks)), 63 | bottom = element_render(theme, "axis.ticks.x", 64 | x = rep(at, each = 2), 65 | y = rep(unit.c(one - theme$axis.ticks.length, one), nticks), 66 | id.lengths = rep(2, nticks)), 67 | right = element_render(theme, "axis.ticks.y", 68 | x = rep(unit.c(zero, theme$axis.ticks.length), nticks), 69 | y = rep(at, each = 2), 70 | id.lengths = rep(2, nticks)), 71 | left = element_render(theme, "axis.ticks.y", 72 | x = rep(unit.c(one - theme$axis.ticks.length, one), nticks), 73 | y = rep(at, each = 2), 74 | id.lengths = rep(2, nticks)) 75 | ) 76 | 77 | # Create the gtable for the ticks + labels 78 | gt <- switch(position, 79 | top = gtable_col("axis", 80 | grobs = list(labels, ticks), 81 | width = one, 82 | heights = unit.c(grobHeight(labels), theme$axis.ticks.length) 83 | ), 84 | bottom = gtable_col("axis", 85 | grobs = list(ticks, labels), 86 | width = one, 87 | heights = unit.c(theme$axis.ticks.length, grobHeight(labels)) 88 | ), 89 | right = gtable_row("axis", 90 | grobs = list(ticks, labels), 91 | widths = unit.c(theme$axis.ticks.length, grobWidth(labels)), 92 | height = one 93 | ), 94 | left = gtable_row("axis", 95 | grobs = list(labels, ticks), 96 | widths = unit.c(grobWidth(labels), theme$axis.ticks.length), 97 | height = one 98 | ) 99 | ) 100 | 101 | # Viewport for justifying the axis grob 102 | justvp <- switch(position, 103 | top = viewport(y = 0, just = "bottom", height = gtable_height(gt)), 104 | bottom = viewport(y = 1, just = "top", height = gtable_height(gt)), 105 | right = viewport(x = 0, just = "left", width = gtable_width(gt)), 106 | left = viewport(x = 1, just = "right", width = gtable_width(gt)) 107 | ) 108 | 109 | absoluteGrob( 110 | gList(line, gt), 111 | width = gtable_width(gt), 112 | height = gtable_height(gt), 113 | vp = justvp 114 | ) 115 | } 116 | -------------------------------------------------------------------------------- /R/position-dodgev.R: -------------------------------------------------------------------------------- 1 | #' @title Vertically dodge position 2 | #' @param height numeric, height of vertical dodge, Default: NULL 3 | #' @examples 4 | #' 5 | #' if(interactive()){ 6 | #' 7 | #' dat <- data.frame( 8 | #' trt = c(LETTERS[1:5], "D"), 9 | #' l = c(20, 40, 10, 30, 50, 40), 10 | #' r = c(70, 50, 30, 60, 80, 70) 11 | #' ) 12 | #' 13 | #' ggplot(dat, aes(y=trt, x=l, xend=r)) + 14 | #' geom_dumbbell(size=3, color="#e3e2e1", 15 | #' colour_x = "#5b8124", colour_xend = "#bad744", 16 | #' dot_guide=TRUE, dot_guide_size=0.25, 17 | #' position=position_dodgev(height=0.8)) + 18 | #' labs(x=NULL, y=NULL, title="ggplot2 geom_dumbbell with dot guide") + 19 | #' theme_minimal() + 20 | #' theme(panel.grid.major.x=element_line(size=0.05)) 21 | #' 22 | #' } 23 | #' 24 | #' @rdname position-dodgev 25 | #' @author @@ggstance authors 26 | #' @note position-dodgev(): unmodified from lionel-/ggstance/R/position-dodgev.R 73f521384ae8ea277db5f7d5a2854004aa18f947 27 | #' @export 28 | position_dodgev <- function(height = NULL) { 29 | ggplot2::ggproto(NULL, PositionDodgev, height = height) 30 | } 31 | 32 | #' @rdname position-dodgev 33 | #' @format NULL 34 | #' @usage NULL 35 | #' @export 36 | PositionDodgev <- ggplot2::ggproto("PositionDodgev", ggplot2::Position, 37 | required_aes = "y", 38 | height = NULL, 39 | setup_params = function(self, data) { 40 | if (is.null(data$ymin) && is.null(data$ymax) && is.null(self$height)) { 41 | warning("Height not defined. Set with `position_dodgev(height = ?)`", 42 | call. = FALSE) 43 | } 44 | list(height = self$height) 45 | }, 46 | 47 | compute_panel = function(data, params, scales) { 48 | collidev(data, params$height, "position_dodgev", pos_dodgev, check.height = FALSE) 49 | } 50 | ) 51 | 52 | pos_dodgev <- function(df, height) { 53 | n <- length(unique(df$group)) 54 | if (n == 1) return(df) 55 | 56 | if (!all(c("ymin", "ymax") %in% names(df))) { 57 | df$ymin <- df$y 58 | df$ymax <- df$y 59 | } 60 | 61 | d_height <- max(df$ymax - df$ymin) 62 | 63 | # df <- data.frame(n = c(2:5, 10, 26), div = c(4, 3, 2.666666, 2.5, 2.2, 2.1)) 64 | # ggplot(df, aes(n, div)) + geom_point() 65 | 66 | # Have a new group index from 1 to number of groups. 67 | # This might be needed if the group numbers in this set don't include all of 1:n 68 | groupidx <- match(df$group, sort(unique(df$group))) 69 | 70 | # Find the center for each group, then use that to calculate ymin and lmax 71 | df$y <- df$y + height * ((groupidx - 0.5) / n - .5) 72 | df$ymin <- df$y - d_height / n / 2 73 | df$ymax <- df$y + d_height / n / 2 74 | 75 | df 76 | } 77 | 78 | collidev <- function(data, height = NULL, name, strategy, ..., check.height = TRUE, reverse = FALSE) { 79 | # Determine height 80 | if (!is.null(height)) { 81 | # Width set manually 82 | if (!(all(c("ymin", "ymax") %in% names(data)))) { 83 | data$ymin <- data$y - height / 2 84 | data$ymax <- data$y + height / 2 85 | } 86 | } else { 87 | if (!(all(c("ymin", "ymax") %in% names(data)))) { 88 | data$ymin <- data$y 89 | data$ymax <- data$y 90 | } 91 | 92 | # Width determined from data, must be floating point constant 93 | heights <- unique(data$ymax - data$ymin) 94 | heights <- heights[!is.na(heights)] 95 | 96 | # # Suppress warning message since it's not reliable 97 | # if (!zero_range(range(heights))) { 98 | # warning(name, " requires constant height: output may be incorrect", 99 | # call. = FALSE) 100 | # } 101 | height <- heights[1] 102 | } 103 | 104 | # Reorder by x position, then on group. The default stacking order reverses 105 | # the group in order to match the legend order. 106 | if (reverse) { 107 | data <- data[order(data$ymin, data$group), ] 108 | } else { 109 | data <- data[order(data$ymin, -data$group), ] 110 | } 111 | 112 | 113 | # Check for overlap 114 | intervals <- as.numeric(t(unique(data[c("ymin", "ymax")]))) 115 | intervals <- intervals[!is.na(intervals)] 116 | 117 | if (length(unique(intervals)) > 1 & any(diff(scale(intervals)) < -1e-6)) { 118 | warning(name, " requires non-overlapping y intervals", call. = FALSE) 119 | # This is where the algorithm from [L. Wilkinson. Dot plots. 120 | # The American Statistician, 1999.] should be used 121 | } 122 | 123 | data$group <- seq_len(nrow(data)) ## reset grouping 124 | 125 | if (!is.null(data$xmax)) { 126 | plyr::ddply(data, "ymin", strategy, ..., height = height) 127 | } else if (!is.null(data$x)) { 128 | data$xmax <- data$x 129 | data <- plyr::ddply(data, "ymin", strategy, ..., height = height) 130 | data$x <- data$xmax 131 | data$yend <- data$y ## ALLOW FOR A YEND COLUMN 132 | data 133 | } else { 134 | stop("Neither x nor xmax defined") 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /R/stat-stepribbon.r: -------------------------------------------------------------------------------- 1 | #' Step ribbon statistic 2 | #' 3 | #' Provides stairstep values for ribbon plots 4 | #' 5 | #' @md 6 | #' @inheritParams ggplot2::geom_ribbon 7 | #' @param geom which geom to use; defaults to "`ribbon`" 8 | #' @param direction `hv` for horizontal-veritcal steps, `vh` for 9 | #' vertical-horizontal steps 10 | #' @references [https://groups.google.com/forum/?fromgroups=#!topic/ggplot2/9cFWHaH1CPs]() 11 | #' @export 12 | #' @examples 13 | #' x <- 1:10 14 | #' df <- data.frame(x=x, y=x+10, ymin=x+7, ymax=x+12) 15 | #' 16 | #' gg <- ggplot(df, aes(x, y)) 17 | #' gg <- gg + geom_ribbon(aes(ymin=ymin, ymax=ymax), 18 | #' stat="stepribbon", fill="#b2b2b2") 19 | #' gg <- gg + geom_step(color="#2b2b2b") 20 | #' gg 21 | #' 22 | #' gg <- ggplot(df, aes(x, y)) 23 | #' gg <- gg + geom_ribbon(aes(ymin=ymin, ymax=ymax), 24 | #' stat="stepribbon", fill="#b2b2b2", 25 | #' direction="hv") 26 | #' gg <- gg + geom_step(color="#2b2b2b") 27 | #' gg 28 | stat_stepribbon <- function(mapping=NULL, data=NULL, geom="ribbon", 29 | position="identity", 30 | na.rm=FALSE, show.legend=NA, inherit.aes=TRUE, 31 | direction="hv", ...) { 32 | 33 | ggplot2::layer( 34 | data = data, 35 | mapping = mapping, 36 | stat = StatStepribbon, 37 | geom = geom, 38 | position = position, 39 | show.legend = show.legend, 40 | inherit.aes = inherit.aes, 41 | params = list( 42 | na.rm = na.rm, 43 | direction = direction, 44 | ... 45 | ) 46 | ) 47 | } 48 | 49 | #' @rdname ggalt-ggproto 50 | #' @format NULL 51 | #' @usage NULL 52 | #' @references \url{https://groups.google.com/forum/?fromgroups=#!topic/ggplot2/9cFWHaH1CPs} 53 | #' @export 54 | StatStepribbon <- 55 | ggproto( 56 | "StatStepRibbon", Stat, 57 | 58 | required_aes = c("x", "ymin", "ymax"), 59 | 60 | compute_group = function(data, scales, direction="hv", 61 | yvars=c("ymin", "ymax"), ...) { 62 | stairstepn(data=data, direction=direction, yvars=yvars) 63 | } 64 | 65 | ) 66 | 67 | stairstepn <- function(data, direction="hv", yvars="y") { 68 | 69 | direction <- match.arg(direction, c("hv", "vh")) 70 | 71 | data <- as.data.frame(data)[order(data$x),] 72 | 73 | n <- nrow(data) 74 | 75 | if (direction == "vh") { 76 | xs <- rep(1:n, each=2)[-2*n] 77 | ys <- c(1, rep( 2:n, each=2)) 78 | } else { 79 | ys <- rep(1:n, each=2)[-2*n] 80 | xs <- c(1, rep(2:n, each=2)) 81 | } 82 | 83 | data.frame( 84 | x=data$x[xs], 85 | data[ys, yvars, drop=FALSE], 86 | data[xs, setdiff(names(data), c("x", yvars)), drop=FALSE] 87 | ) 88 | 89 | } 90 | -------------------------------------------------------------------------------- /R/stateface.r: -------------------------------------------------------------------------------- 1 | state_trans <- c(AL='B', AK='A', AZ='D', AR='C', CA='E', CO='F', CT='G', 2 | DE='H', DC='y', FL='I', GA='J', HI='K', ID='M', IL='N', 3 | IN='O', IA='L', KS='P', KY='Q', LA='R', ME='U', MD='T', 4 | MA='S', MI='V', MN='W', MS='Y', MO='X', MT='Z', NE='c', 5 | NV='g', NH='d', NJ='e', NM='f', NY='h', NC='a', ND='b', 6 | OH='i', OK='j', OR='k', PA='l', RI='m', SC='n', SD='o', 7 | TN='p', TX='q', UT='r', VT='t', VA='s', WA='u', WV='w', 8 | WI='v', WY='x', US='z') 9 | 10 | state_tbl <- setNames(toupper(state.abb), tolower(state.name)) 11 | 12 | #' Show location of StateFace font 13 | #' 14 | #' Displays the path to the StateFace font. For the font to work 15 | #' in the on-screen plot device for ggplot2, you need to install 16 | #' the font on your system 17 | #' 18 | #' @family StateFace operations 19 | #' @export 20 | show_stateface <- function() { 21 | 22 | path <- normalizePath(file.path(system.file("fonts/", package="ggalt"))) 23 | print(path) 24 | 25 | if (!interactive()) return() 26 | 27 | if (.Platform$OS.type == "windows") { 28 | shell(sprintf("explorer %s", path), intern=TRUE) 29 | } else if(.Platform$OS.type == "unix") { 30 | if (Sys.info()["sysname"] == "Darwin") { 31 | system2("open", path) 32 | } 33 | } 34 | 35 | } 36 | 37 | #' Load stateface font 38 | #' 39 | #' Makes the ProPublica StateFace font available to PDF, PostScript, 40 | #' et. al. devices. 41 | #' 42 | #' @family StateFace operations 43 | #' @export 44 | load_stateface <- function() { 45 | if (interactive()) message("Loading stateface device fonts...") 46 | if (!any(grepl("StateFace", extrafont::fonts()))) { 47 | tmp <- capture.output(suppressWarnings(extrafont::ttf_import( 48 | system.file("fonts/", package="ggalt"), 49 | prompt=FALSE, pattern="*.ttf", recursive=FALSE))) 50 | } 51 | tmp <- utils::capture.output(suppressWarnings(extrafont::loadfonts(quiet=TRUE))) 52 | } 53 | 54 | #' Use ProPublica's StateFace font in ggplot2 plots 55 | #' 56 | #' The \code{label} parameter can be either a 2-letter state abbreviation 57 | #' or a full state name. \code{geom_stateface()} will take care of the 58 | #' translation to StateFace font glyph characters. 59 | #' 60 | #' The package will also take care of loading the StateFace font for 61 | #' PDF and other devices, but to use it with the on-screen ggplot2 62 | #' device, you'll need to install the font on your system. 63 | #' 64 | #' \code{ggalt} ships with a copy of the StateFace TTF font. You can 65 | #' run \code{show_stateface()} to get the filesystem location and then 66 | #' load the font manually from there. 67 | #' 68 | #' \if{html}{ 69 | #' A sample of the output from \code{geom_stateface()}: 70 | #' 71 | #' \figure{geomstateface01.png}{options: width="100\%" alt="Figure: geomstateface01.png"} 72 | #' } 73 | #' 74 | #' \if{latex}{ 75 | #' A sample of the output from \code{geom_stateface()}: 76 | #' 77 | #' \figure{geomstateface01.png}{options: width=10cm} 78 | #' } 79 | #' 80 | #' @param nudge_x,nudge_y Horizontal and vertical adjustment to nudge l 81 | #' abels by. Useful for offsetting text from points, particularly 82 | #' on discrete scales. 83 | #' @inheritParams ggplot2::geom_text 84 | #' @family StateFace operations 85 | #' @export 86 | #' @examples \dontrun{ 87 | #' library(ggplot2) 88 | #' library(ggalt) 89 | #' 90 | #' # Run show_stateface() to see the location of the TTF StateFace font 91 | #' # You need to install it for it to work 92 | #' 93 | #' set.seed(1492) 94 | #' dat <- data.frame(state=state.abb, 95 | #' x=sample(100, 50), 96 | #' y=sample(100, 50), 97 | #' col=sample(c("#b2182b", "#2166ac"), 50, replace=TRUE), 98 | #' sz=sample(6:15, 50, replace=TRUE), 99 | #' stringsAsFactors=FALSE) 100 | #' gg <- ggplot(dat, aes(x=x, y=y)) 101 | #' gg <- gg + geom_stateface(aes(label=state, color=col, size=sz)) 102 | #' gg <- gg + scale_color_identity() 103 | #' gg <- gg + scale_size_identity() 104 | #' gg 105 | #' } 106 | geom_stateface <- function(mapping = NULL, data = NULL, stat = "identity", 107 | position = "identity", ..., parse = FALSE, 108 | nudge_x = 0, nudge_y = 0, check_overlap = FALSE, 109 | na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { 110 | 111 | if (!missing(nudge_x) || !missing(nudge_y)) { 112 | if (!missing(position)) { 113 | stop("Specify either `position` or `nudge_x`/`nudge_y`", call. = FALSE) 114 | } 115 | 116 | position <- position_nudge(nudge_x, nudge_y) 117 | } 118 | 119 | layer( 120 | data = data, 121 | mapping = mapping, 122 | stat = stat, 123 | geom = GeomStateface, 124 | position = position, 125 | show.legend = show.legend, 126 | inherit.aes = inherit.aes, 127 | params = list( 128 | parse = parse, 129 | check_overlap = check_overlap, 130 | na.rm = na.rm, 131 | ... 132 | ) 133 | ) 134 | 135 | } 136 | 137 | #' @rdname ggalt-ggproto 138 | #' @format NULL 139 | #' @usage NULL 140 | #' @export 141 | GeomStateface <- ggproto("GeomStateface", Geom, 142 | required_aes = c("x", "y", "label"), 143 | 144 | default_aes = aes( 145 | colour = "black", size = 3.88, angle = 0, hjust = 0.5, 146 | vjust = 0.5, alpha = NA, family = "", fontface = 1, lineheight = 1.2 147 | ), 148 | 149 | draw_panel = function(data, panel_scales, coord, parse = FALSE, 150 | na.rm = FALSE, check_overlap = FALSE) { 151 | 152 | load_stateface 153 | 154 | lab <- data$label 155 | 156 | if (max(sapply(lab, nchar)) == 2) { 157 | lab <- unname(state_trans[toupper(lab)]) 158 | } else { 159 | lab <- unname(state_trans[state_tbl[tolower(lab)]]) 160 | } 161 | 162 | data <- coord$transform(data, panel_scales) 163 | if (is.character(data$vjust)) { 164 | data$vjust <- compute_just(data$vjust, data$y) 165 | } 166 | if (is.character(data$hjust)) { 167 | data$hjust <- compute_just(data$hjust, data$x) 168 | } 169 | 170 | textGrob( 171 | lab, 172 | data$x, data$y, default.units = "native", 173 | hjust = data$hjust, vjust = data$vjust, 174 | rot = data$angle, 175 | gp = gpar( 176 | col = alpha(data$colour, data$alpha), 177 | fontsize = data$size * .pt, 178 | fontfamily = "StateFace", 179 | fontface = data$fontface, 180 | lineheight = data$lineheight 181 | ), 182 | check.overlap = check_overlap 183 | ) 184 | }, 185 | 186 | draw_key = draw_key_text 187 | 188 | ) 189 | 190 | compute_just <- function(just, x) { 191 | inward <- just == "inward" 192 | just[inward] <- c("left", "middle", "right")[just_dir(x[inward])] 193 | outward <- just == "outward" 194 | just[outward] <- c("right", "middle", "left")[just_dir(x[outward])] 195 | 196 | unname(c(left = 0, center = 0.5, right = 1, 197 | bottom = 0, middle = 0.5, top = 1)[just]) 198 | } 199 | 200 | just_dir <- function(x, tol = 0.001) { 201 | out <- rep(2L, length(x)) 202 | out[x < 0.5 - tol] <- 1L 203 | out[x > 0.5 + tol] <- 3L 204 | out 205 | } 206 | -------------------------------------------------------------------------------- /R/utils.r: -------------------------------------------------------------------------------- 1 | "%||%" <- function(a, b) { 2 | if (!is.null(a)) a else b 3 | } 4 | 5 | "%|W|%" <- function(a, b) { 6 | if (!is.waive(a)) a else b 7 | } 8 | 9 | is.waive <- function(x) inherits(x, "waiver") 10 | 11 | # Compute central angle between two points. 12 | # Multiple by radius of sphere to get great circle distance 13 | # @arguments longitude 14 | # @arguments latitude 15 | dist_central_angle <- function(lon, lat) { 16 | # Convert to radians 17 | lat <- lat * pi / 180 18 | lon <- lon * pi / 180 19 | 20 | hav <- function(x) sin(x / 2) ^ 2 21 | ahav <- function(x) 2 * asin(x) 22 | 23 | n <- length(lat) 24 | ahav(sqrt(hav(diff(lat)) + cos(lat[-n]) * cos(lat[-1]) * hav(diff(lon)))) 25 | } 26 | 27 | 28 | expand_default <- function(scale, discrete = c(0, 0.6), continuous = c(0.05, 0)) { 29 | scale$expand %|W|% if (scale$is_discrete()) discrete else continuous 30 | } 31 | 32 | 33 | # Col union 34 | # 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. 35 | # 36 | # @param data frame a 37 | # @param data frame b 38 | # @keyword internal 39 | cunion <- function(a, b) { 40 | if (length(a) == 0) return(b) 41 | if (length(b) == 0) return(a) 42 | 43 | cbind(a, b[setdiff(names(b), names(a))]) 44 | } 45 | 46 | # Given a theme object and element name, return a grob for the element 47 | element_render <- function(theme, element, ..., name = NULL) { 48 | 49 | # Get the element from the theme, calculating inheritance 50 | el <- calc_element(element, theme) 51 | if (is.null(el)) { 52 | message("Theme element ", element, " missing") 53 | return(zeroGrob()) 54 | } 55 | 56 | ggname(paste(element, name, sep = "."), element_grob(el, ...)) 57 | } 58 | 59 | 60 | # Name ggplot grid object 61 | # Convenience function to name grid objects 62 | # 63 | # @keyword internal 64 | ggname <- function(prefix, grob) { 65 | grob$name <- grobName(grob, prefix) 66 | grob 67 | } 68 | 69 | # Convert a snake_case string to camelCase 70 | camelize <- function(x, first = FALSE) { 71 | x <- gsub("_(.)", "\\U\\1", x, perl = TRUE) 72 | if (first) x <- firstUpper(x) 73 | x 74 | } 75 | 76 | snakeize <- function(x) { 77 | x <- gsub("([A-Za-z])([A-Z])([a-z])", "\\1_\\2\\3", x) 78 | x <- gsub(".", "_", x, fixed = TRUE) 79 | x <- gsub("([a-z])([A-Z])", "\\1_\\2", x) 80 | tolower(x) 81 | } 82 | 83 | firstUpper <- function(s) { 84 | paste(toupper(substring(s, 1,1)), substring(s, 2), sep = "") 85 | } 86 | 87 | snake_class <- function(x) { 88 | snakeize(class(x)[1]) 89 | } 90 | 91 | 92 | # Look for object first in parent environment and if not found, then in 93 | # ggplot2 namespace environment. This makes it possible to override default 94 | # scales by setting them in the parent environment. 95 | find_global <- function(name, env, mode = "any") { 96 | if (exists(name, envir = env, mode = mode)) { 97 | return(get(name, envir = env, mode = mode)) 98 | } 99 | 100 | nsenv <- asNamespace("ggalt") 101 | if (exists(name, envir = nsenv, mode = mode)) { 102 | return(get(name, envir = nsenv, mode = mode)) 103 | } 104 | 105 | NULL 106 | } 107 | 108 | find_subclass <- function (super, class, env) { 109 | name <- paste0(super, camelize(class, first = TRUE)) 110 | obj <- find_global(name, env = env) 111 | if (is.null(name)) { 112 | stop("No ", tolower(super), " called ", name, ".", call. = FALSE) 113 | } 114 | else if (!inherits(obj, super)) { 115 | stop("Found object is not a ", tolower(super), ".", call. = FALSE) 116 | } 117 | obj 118 | } 119 | 120 | alt_aesthetics <- function(type, name) { 121 | obj <- switch(type, 122 | geom = find_subclass("Geom", name, globalenv()), 123 | stat = find_subclass("Stat", name, globalenv()) 124 | ) 125 | aes <- alt_aesthetics_item(obj) 126 | 127 | paste("\\code{", type, "_", name, "} ", 128 | "understands the following aesthetics (required aesthetics are in bold):\n\n", 129 | "\\itemize{\n", 130 | paste(" \\item \\code{", aes, "}", collapse = "\n", sep = ""), 131 | "\n}\n", sep = "") 132 | } 133 | 134 | alt_aesthetics_item <- function(x) { 135 | req <- x$required_aes 136 | all <- union(req, sort(x$aesthetics())) 137 | 138 | ifelse(all %in% req, 139 | paste0("\\strong{", all, "}"), 140 | all 141 | ) 142 | } 143 | -------------------------------------------------------------------------------- /R/zzz.r: -------------------------------------------------------------------------------- 1 | .onAttach <- function(...) { 2 | 3 | if (!interactive()) return() 4 | 5 | # packageStartupMessage(paste0("ggalt is under *active* development. ", 6 | # "See https://github.com/hrbrmstr/ggalt for changes")) 7 | 8 | } 9 | 10 | -------------------------------------------------------------------------------- /README_figs/README-annoticks-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-annoticks-1.png -------------------------------------------------------------------------------- /README_figs/README-annoticks-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-annoticks-2.png -------------------------------------------------------------------------------- /README_figs/README-annoticks-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-annoticks-3.png -------------------------------------------------------------------------------- /README_figs/README-bkde2d-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-bkde2d-1.png -------------------------------------------------------------------------------- /README_figs/README-bkde2d-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-bkde2d-2.png -------------------------------------------------------------------------------- /README_figs/README-bkde_ash-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-bkde_ash-1.png -------------------------------------------------------------------------------- /README_figs/README-bkde_ash-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-bkde_ash-2.png -------------------------------------------------------------------------------- /README_figs/README-bkde_ash-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-bkde_ash-3.png -------------------------------------------------------------------------------- /README_figs/README-bkde_ash-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-bkde_ash-4.png -------------------------------------------------------------------------------- /README_figs/README-bkde_ash-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-bkde_ash-5.png -------------------------------------------------------------------------------- /README_figs/README-bkde_ash-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-bkde_ash-6.png -------------------------------------------------------------------------------- /README_figs/README-bkde_ash-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-bkde_ash-7.png -------------------------------------------------------------------------------- /README_figs/README-bkde_ash-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-bkde_ash-8.png -------------------------------------------------------------------------------- /README_figs/README-coord_proj-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-coord_proj-1.png -------------------------------------------------------------------------------- /README_figs/README-dumbbell-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-dumbbell-1.png -------------------------------------------------------------------------------- /README_figs/README-dumbbell2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-dumbbell2-1.png -------------------------------------------------------------------------------- /README_figs/README-encircle-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-encircle-1.png -------------------------------------------------------------------------------- /README_figs/README-encircle-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-encircle-2.png -------------------------------------------------------------------------------- /README_figs/README-encircle-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-encircle-3.png -------------------------------------------------------------------------------- /README_figs/README-encircle-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-encircle-4.png -------------------------------------------------------------------------------- /README_figs/README-encircle-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-encircle-5.png -------------------------------------------------------------------------------- /README_figs/README-encircle-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-encircle-6.png -------------------------------------------------------------------------------- /README_figs/README-encircle-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-encircle-7.png -------------------------------------------------------------------------------- /README_figs/README-horizon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-horizon-1.png -------------------------------------------------------------------------------- /README_figs/README-lollipop-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-lollipop-1.png -------------------------------------------------------------------------------- /README_figs/README-spikelines-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-spikelines-1.png -------------------------------------------------------------------------------- /README_figs/README-splines-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-splines-1.png -------------------------------------------------------------------------------- /README_figs/README-splines-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-splines-2.png -------------------------------------------------------------------------------- /README_figs/README-splines-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-splines-3.png -------------------------------------------------------------------------------- /README_figs/README-splines-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-splines-4.png -------------------------------------------------------------------------------- /README_figs/README-splines-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-splines-5.png -------------------------------------------------------------------------------- /README_figs/README-splines-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-splines-6.png -------------------------------------------------------------------------------- /README_figs/README-splines-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-splines-7.png -------------------------------------------------------------------------------- /README_figs/README-splines-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-splines-8.png -------------------------------------------------------------------------------- /README_figs/README-stateface-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-stateface-1.png -------------------------------------------------------------------------------- /README_figs/README-stepribbon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-stepribbon-1.png -------------------------------------------------------------------------------- /README_figs/README-stepribbon-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/README_figs/README-stepribbon-2.png -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE the "init" and "install" sections below 2 | 3 | # Download script file from GitHub 4 | init: 5 | ps: | 6 | $ErrorActionPreference = "Stop" 7 | Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" 8 | Import-Module '..\appveyor-tool.ps1' 9 | 10 | install: 11 | ps: Bootstrap 12 | 13 | cache: 14 | - C:\RLibrary 15 | 16 | # Adapt as necessary starting from here 17 | 18 | build_script: 19 | - travis-tool.sh install_deps 20 | 21 | test_script: 22 | - travis-tool.sh run_tests 23 | 24 | on_failure: 25 | - 7z a failure.zip *.Rcheck\* 26 | - appveyor PushArtifact failure.zip 27 | 28 | artifacts: 29 | - path: '*.Rcheck\**\*.log' 30 | name: Logs 31 | 32 | - path: '*.Rcheck\**\*.out' 33 | name: Logs 34 | 35 | - path: '*.Rcheck\**\*.fail' 36 | name: Logs 37 | 38 | - path: '*.Rcheck\**\*.Rout' 39 | name: Logs 40 | 41 | - path: '\*_*.tar.gz' 42 | name: Bits 43 | 44 | - path: '\*_*.zip' 45 | name: Bits 46 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | * local OS X install, R 3.3.2 3 | * ubuntu 14.04 (on travis-ci), old, current, devel 4 | * win-builder (devel and release) 5 | 6 | ## R CMD check results 7 | 8 | 0 errors | 0 warnings | 1 note 9 | 10 | ## Reverse dependencies 11 | 12 | GSODR & spbabel have been rev-dep checked: 13 | 14 | - Checked GSODR : 0 errors | 0 warnings | 0 notes 15 | - Checked spbabel: 0 errors | 0 warnings | 0 notes 16 | 17 | --- 18 | 19 | * Modified DESCRIPTION errors per CRAN team feedback 20 | * E-mail change (old one is nigh dead and I need to update my other pkgs) 21 | * Fixes errors in the CRAN checks after the ggplot2 2.2.1 release 22 | * Adds substantial new functionality (many new geoms and stats) 23 | * Includes a new basic vignette 24 | -------------------------------------------------------------------------------- /ggalt.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 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 | PackageBuildArgs: --resave-data 22 | PackageCheckArgs: --as-cran 23 | PackageRoxygenize: rd,collate,namespace 24 | -------------------------------------------------------------------------------- /inst/fonts/stateface-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/inst/fonts/stateface-regular-webfont.ttf -------------------------------------------------------------------------------- /man/absoluteGrob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/grob_absolute.r 3 | \name{absoluteGrob} 4 | \alias{absoluteGrob} 5 | \title{Absolute grob} 6 | \usage{ 7 | absoluteGrob( 8 | grob, 9 | width = NULL, 10 | height = NULL, 11 | xmin = NULL, 12 | ymin = NULL, 13 | vp = NULL 14 | ) 15 | } 16 | \description{ 17 | This grob has fixed dimensions and position. 18 | } 19 | \details{ 20 | It's still experimental 21 | } 22 | \keyword{internal} 23 | -------------------------------------------------------------------------------- /man/annotate_textp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/annotate_textp.r 3 | \name{annotate_textp} 4 | \alias{annotate_textp} 5 | \title{Text annotations in plot coordinate system} 6 | \usage{ 7 | annotate_textp( 8 | label, 9 | x, 10 | y, 11 | facets = NULL, 12 | hjust = 0, 13 | vjust = 0, 14 | color = "black", 15 | alpha = NA, 16 | family = theme_get()$text$family, 17 | size = theme_get()$text$size, 18 | fontface = 1, 19 | lineheight = 1, 20 | box_just = ifelse(c(x, y) < 0.5, 0, 1), 21 | margin = unit(size/2, "pt") 22 | ) 23 | } 24 | \arguments{ 25 | \item{label}{text annotation to be placed on the plot} 26 | 27 | \item{x, y}{positions of the individual annotations, in plot coordinates 28 | (0..1) instead of data coordinates!} 29 | 30 | \item{facets}{facet positions of the individual annotations} 31 | 32 | \item{hjust, vjust}{horizontal and vertical justification of the text relative 33 | to the bounding box} 34 | 35 | \item{color, }{alpha, family, size, fontface, lineheight font properties} 36 | 37 | \item{alpha, family, size, fontface, lineheight}{standard aesthetic customizations} 38 | 39 | \item{box_just}{placement of the bounding box for the text relative to x,y 40 | coordinates. Per default, the box is placed to the center of the plot. Be 41 | aware that parts of the box which are outside of the visible region of the 42 | plot will not be shown.} 43 | 44 | \item{margin}{margins of the bounding box} 45 | } 46 | \description{ 47 | Annotates the plot with text. Compared to \code{annotate("text",...)}, the 48 | placement of the annotations is specified in plot coordinates (from 0 to 1) 49 | instead of data coordinates. 50 | } 51 | \examples{ 52 | p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() 53 | p <- p + geom_smooth(method = "lm", se = FALSE) 54 | p + annotate_textp(x = 0.9, y = 0.35, label="A relative linear\nrelationship", hjust=1, color="red") 55 | } 56 | -------------------------------------------------------------------------------- /man/annotation_ticks.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/annotation_ticks.r 3 | \name{annotation_ticks} 4 | \alias{annotation_ticks} 5 | \title{Annotation: tick marks} 6 | \usage{ 7 | annotation_ticks( 8 | sides = "b", 9 | scale = "identity", 10 | scaled = TRUE, 11 | short = unit(0.1, "cm"), 12 | mid = unit(0.2, "cm"), 13 | long = unit(0.3, "cm"), 14 | colour = "black", 15 | size = 0.5, 16 | linetype = 1, 17 | alpha = 1, 18 | color = NULL, 19 | ticks_per_base = NULL, 20 | ... 21 | ) 22 | } 23 | \arguments{ 24 | \item{sides}{a string that controls which sides of the plot the log ticks appear on. 25 | It can be set to a string containing any of \code{"trbl"}, for top, right, 26 | bottom, and left.} 27 | 28 | \item{scale}{character, vector of type of scale attributed to each corresponding side, Default: 'identity'} 29 | 30 | \item{scaled}{is the data already log-scaled? This should be \code{TRUE} 31 | (default) when the data is already transformed with \code{log10()} or when 32 | using \code{scale_y_log10()}. It should be \code{FALSE} when using 33 | \code{coord_trans(y = "log10")}.} 34 | 35 | \item{short}{a \code{\link[grid:unit]{grid::unit()}} object specifying the length of the 36 | short tick marks} 37 | 38 | \item{mid}{a \code{\link[grid:unit]{grid::unit()}} object specifying the length of the 39 | middle tick marks. In base 10, these are the "5" ticks.} 40 | 41 | \item{long}{a \code{\link[grid:unit]{grid::unit()}} object specifying the length of the 42 | long tick marks. In base 10, these are the "1" (or "10") ticks.} 43 | 44 | \item{colour}{Colour of the tick marks.} 45 | 46 | \item{size}{Thickness of tick marks, in mm.} 47 | 48 | \item{linetype}{Linetype of tick marks (\code{solid}, \code{dashed}, etc.)} 49 | 50 | \item{alpha}{The transparency of the tick marks.} 51 | 52 | \item{color}{An alias for \code{colour}.} 53 | 54 | \item{ticks_per_base}{integer, number of minor ticks between each pair of major ticks, Default: NULL} 55 | 56 | \item{...}{Other parameters passed on to the layer} 57 | } 58 | \description{ 59 | This annotation adds tick marks to an axis 60 | } 61 | \details{ 62 | If scale is of length one it will be replicated to the number of sides given, but if the 63 | length of scale is larger than one it must match the number of sides given. 64 | If ticks_per_base is set to NULL the function infers the number of ticks per base to be 65 | the base of the scale - 1, for example log scale is base exp(1) and 66 | log10 and identity are base 10. If ticks_per_base is given it follows the same logic as scale. 67 | } 68 | \examples{ 69 | 70 | p <- ggplot(msleep, aes(bodywt, brainwt)) + geom_point() 71 | 72 | # Default behavior 73 | 74 | # add identity scale minor ticks on y axis 75 | p + annotation_ticks(sides = 'l') 76 | 77 | # add identity scale minor ticks on x,y axis 78 | p + annotation_ticks(sides = 'lb') 79 | 80 | # Control number of minor ticks of each side independently 81 | 82 | # add identity scale minor ticks on x,y axis 83 | p + annotation_ticks(sides = 'lb', ticks_per_base = c(10,5)) 84 | 85 | # log10 scale 86 | p1 <- p + scale_x_log10() 87 | 88 | # add minor ticks on log10 scale 89 | p1 + annotation_ticks(sides = 'b', scale = 'log10') 90 | 91 | # add minor ticks on both scales 92 | p1 + annotation_ticks(sides = 'lb', scale = c('identity','log10')) 93 | 94 | # add minor ticks on both scales, but force x axis to be identity 95 | p1 + annotation_ticks(sides = 'lb', scale = 'identity') 96 | 97 | # log scale 98 | p2 <- p + scale_x_continuous(trans = 'log') 99 | 100 | # add minor ticks on log scale 101 | p2 + annotation_ticks(sides = 'b', scale = 'log') 102 | 103 | # add minor ticks on both scales 104 | p2 + annotation_ticks(sides = 'lb', scale = c('identity','log')) 105 | 106 | # add minor ticks on both scales, but force x axis to be identity 107 | p2 + annotation_ticks(sides = 'lb', scale = 'identity') 108 | 109 | } 110 | \author{ 111 | Jonathan Sidi 112 | } 113 | -------------------------------------------------------------------------------- /man/byte_format.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/formatters.r 3 | \name{byte_format} 4 | \alias{byte_format} 5 | \alias{Kb} 6 | \alias{Mb} 7 | \alias{Gb} 8 | \alias{bytes} 9 | \title{Bytes formatter: convert to byte measurement and display symbol.} 10 | \usage{ 11 | byte_format(symbol = "auto", units = "binary", only_highest = TRUE) 12 | 13 | Kb(x) 14 | 15 | Mb(x) 16 | 17 | Gb(x) 18 | 19 | bytes(x, symbol = "auto", units = c("binary", "si"), only_highest = FALSE) 20 | } 21 | \arguments{ 22 | \item{symbol}{byte symbol to use. If "\code{auto}" the symbol used will be 23 | determined by the maximum value of \code{x}. Valid symbols are 24 | "\code{b}", "\code{K}", "\code{Mb}", "\code{Gb}", "\code{Tb}", "\code{Pb}", 25 | "\code{Eb}", "\code{Zb}", and "\code{Yb}", along with their upper case 26 | equivalents and "\code{iB}" equivalents.} 27 | 28 | \item{units}{which unit base to use, "\code{binary}" (1024 base) or 29 | "\code{si}" (1000 base) for ISI units.} 30 | 31 | \item{only_highest}{Whether to use the unit of the highest number or 32 | each number uses its own unit.} 33 | 34 | \item{x}{a numeric vector to format} 35 | } 36 | \value{ 37 | a function with three parameters, \code{x}, a numeric vector that 38 | returns a character vector, \code{symbol} a single or a vector of byte 39 | symbol(s) (e.g. "\code{Kb}") desired and the measurement \code{units} 40 | (traditional \code{binary} or \code{si} for ISI metric units). 41 | } 42 | \description{ 43 | Bytes formatter: convert to byte measurement and display symbol. 44 | } 45 | \examples{ 46 | byte_format()(sample(3000000000, 10)) 47 | bytes(sample(3000000000, 10)) 48 | Kb(sample(3000000000, 10)) 49 | Mb(sample(3000000000, 10)) 50 | Gb(sample(3000000000, 10)) 51 | } 52 | \references{ 53 | Units of Information (Wikipedia) : 54 | \url{http://en.wikipedia.org/wiki/Units_of_information} 55 | } 56 | -------------------------------------------------------------------------------- /man/coord_proj.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/coord_proj.r 3 | \name{coord_proj} 4 | \alias{coord_proj} 5 | \title{Similar to \code{coord_map} but uses the PROJ.4 library/package for projection 6 | transformation} 7 | \usage{ 8 | coord_proj( 9 | proj = NULL, 10 | inverse = FALSE, 11 | degrees = TRUE, 12 | ellps.default = "sphere", 13 | xlim = NULL, 14 | ylim = NULL 15 | ) 16 | } 17 | \arguments{ 18 | \item{proj}{projection definition. If left \code{NULL} will default to 19 | a Robinson projection} 20 | 21 | \item{inverse}{if \code{TRUE} inverse projection is performed (from a 22 | cartographic projection into lat/long), otherwise projects from 23 | lat/long into a cartographic projection.} 24 | 25 | \item{degrees}{if \code{TRUE} then the lat/long data is assumed to be in 26 | degrees, otherwise in radians} 27 | 28 | \item{ellps.default}{default ellipsoid that will be added if no datum or 29 | ellipsoid parameter is specified in proj. Older versions of PROJ.4 30 | didn't require a datum (and used sphere by default), but 4.5.0 and 31 | higher always require a datum or an ellipsoid. Set to \code{NA} if no 32 | datum should be added to proj (e.g. if you specify an ellipsoid 33 | directly).} 34 | 35 | \item{xlim}{manually specify x limits (in degrees of longitude)} 36 | 37 | \item{ylim}{manually specify y limits (in degrees of latitude)} 38 | } 39 | \description{ 40 | The representation of a portion of the earth, which is approximately 41 | spherical, onto a flat 2D plane requires a projection. This is what 42 | \code{coord_proj} does, using the \code{proj4::project()} function from 43 | the \code{proj4} package. 44 | } 45 | \details{ 46 | \if{html}{ 47 | A sample of the output from \code{coord_proj()} using the Winkel-Tripel projection: 48 | 49 | \figure{coordproj01.png}{options: width="100\%" alt="Figure: coordproj01.png"} 50 | } 51 | 52 | \if{latex}{ 53 | A sample of the output from \code{coord_proj()} using the Winkel-Tripel projection: 54 | `` 55 | \figure{coordproj01.png}{options: width=10cm} 56 | } 57 | } 58 | \note{ 59 | It is recommended that you use \code{geom_cartogram} with this coordinate system 60 | 61 | When \code{inverse} is \code{FALSE} \code{coord_proj} makes a fairly 62 | large assumption that the coordinates being transformed are within 63 | -180:180 (longitude) and -90:90 (latitude). As such, it truncates 64 | all longitude & latitude input to fit within these ranges. More updates 65 | to this new \code{coord_} are planned. 66 | } 67 | \examples{ 68 | \dontrun{ 69 | # World in Winkel-Tripel 70 | 71 | # U.S.A. Albers-style 72 | usa <- world[world$region == "USA",] 73 | usa <- usa[!(usa$subregion \%in\% c("Alaska", "Hawaii")),] 74 | 75 | gg <- ggplot() 76 | gg <- gg + geom_cartogram(data=usa, map=usa, 77 | aes(x=long, y=lat, map_id=region)) 78 | gg <- gg + coord_proj( 79 | paste0("+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=37.5 +lon_0=-96", 80 | " +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs")) 81 | gg 82 | 83 | # Showcase Greenland (properly) 84 | greenland <- world[world$region == "Greenland",] 85 | 86 | gg <- ggplot() 87 | gg <- gg + geom_cartogram(data=greenland, map=greenland, 88 | aes(x=long, y=lat, map_id=region)) 89 | gg <- gg + coord_proj( 90 | paste0("+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0", 91 | " +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")) 92 | gg 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /man/figures/coordproj01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/man/figures/coordproj01.png -------------------------------------------------------------------------------- /man/figures/geombkde01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/man/figures/geombkde01.png -------------------------------------------------------------------------------- /man/figures/geombkde2d01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/man/figures/geombkde2d01.png -------------------------------------------------------------------------------- /man/figures/geomencircle01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/man/figures/geomencircle01.png -------------------------------------------------------------------------------- /man/figures/geomlollipop01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/man/figures/geomlollipop01.png -------------------------------------------------------------------------------- /man/figures/geomstateface01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/man/figures/geomstateface01.png -------------------------------------------------------------------------------- /man/figures/geomxspline01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/man/figures/geomxspline01.png -------------------------------------------------------------------------------- /man/figures/statash01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/man/figures/statash01.png -------------------------------------------------------------------------------- /man/fortify.table.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fortify.r 3 | \name{fortify.table} 4 | \alias{fortify.table} 5 | \title{Fortify contingency tables} 6 | \usage{ 7 | \method{fortify}{table}(model, data, ...) 8 | } 9 | \arguments{ 10 | \item{model}{the contingency table} 11 | 12 | \item{data}{data (unused)} 13 | 14 | \item{...}{(unused)} 15 | } 16 | \description{ 17 | Fortify contingency tables 18 | } 19 | -------------------------------------------------------------------------------- /man/geom_bkde.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_bkde.r 3 | \name{geom_bkde} 4 | \alias{geom_bkde} 5 | \alias{stat_bkde} 6 | \title{Display a smooth density estimate.} 7 | \usage{ 8 | geom_bkde( 9 | mapping = NULL, 10 | data = NULL, 11 | stat = "bkde", 12 | position = "identity", 13 | bandwidth = NULL, 14 | range.x = NULL, 15 | na.rm = FALSE, 16 | show.legend = NA, 17 | inherit.aes = TRUE, 18 | ... 19 | ) 20 | 21 | stat_bkde( 22 | mapping = NULL, 23 | data = NULL, 24 | geom = "area", 25 | position = "stack", 26 | kernel = "normal", 27 | canonical = FALSE, 28 | bandwidth = NULL, 29 | gridsize = 410, 30 | range.x = NULL, 31 | truncate = TRUE, 32 | na.rm = FALSE, 33 | show.legend = NA, 34 | inherit.aes = TRUE, 35 | ... 36 | ) 37 | } 38 | \arguments{ 39 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 40 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 41 | at the top level of the plot. You must supply \code{mapping} if there is no plot 42 | mapping.} 43 | 44 | \item{data}{The data to be displayed in this layer. There are three 45 | options: 46 | 47 | If \code{NULL}, the default, the data is inherited from the plot 48 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 49 | 50 | A \code{data.frame}, or other object, will override the plot 51 | data. All objects will be fortified to produce a data frame. See 52 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 53 | 54 | A \code{function} will be called with a single argument, 55 | the plot data. The return value must be a \code{data.frame}, and 56 | will be used as the layer data. A \code{function} can be created 57 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 58 | 59 | \item{position}{Position adjustment, either as a string naming the adjustment 60 | (e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a 61 | position adjustment function. Use the latter if you need to change the 62 | settings of the adjustment.} 63 | 64 | \item{bandwidth}{the kernel bandwidth smoothing parameter. see 65 | \code{\link[KernSmooth]{bkde}} for details. If \code{NULL}, 66 | it will be computed for you but will most likely not yield optimal 67 | results.} 68 | 69 | \item{range.x}{vector containing the minimum and maximum values of x at which 70 | to compute the estimate. see \code{\link[KernSmooth]{bkde}} for details} 71 | 72 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with 73 | a warning. If \code{TRUE}, missing values are silently removed.} 74 | 75 | \item{show.legend}{logical. Should this layer be included in the legends? 76 | \code{NA}, the default, includes if any aesthetics are mapped. 77 | \code{FALSE} never includes, and \code{TRUE} always includes. 78 | It can also be a named logical vector to finely select the aesthetics to 79 | display.} 80 | 81 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 82 | rather than combining with them. This is most useful for helper functions 83 | that define both data and aesthetics and shouldn't inherit behaviour from 84 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 85 | 86 | \item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{layer()}}. These are 87 | often aesthetics, used to set an aesthetic to a fixed value, like 88 | \code{colour = "red"} or \code{size = 3}. They may also be parameters 89 | to the paired geom/stat.} 90 | 91 | \item{geom, stat}{Use to override the default connection between 92 | \code{geom_bkde} and \code{stat_bkde}.} 93 | 94 | \item{kernel}{character string which determines the smoothing kernel. see 95 | \code{\link[KernSmooth]{bkde}} for details} 96 | 97 | \item{canonical}{logical flag: if TRUE, canonically scaled kernels are used. 98 | see \code{\link[KernSmooth]{bkde}} for details} 99 | 100 | \item{gridsize}{the number of equally spaced points at which to estimate the 101 | density. see \code{\link[KernSmooth]{bkde}} for details.} 102 | 103 | \item{truncate}{logical flag: if TRUE, data with x values outside the range 104 | specified by range.x are ignored. see \code{\link[KernSmooth]{bkde}} 105 | for details} 106 | } 107 | \description{ 108 | A kernel density estimate, useful for displaying the distribution of 109 | variables with underlying smoothness. 110 | } 111 | \details{ 112 | \if{html}{ 113 | A sample of the output from \code{geom_bkde()}: 114 | 115 | \figure{geombkde01.png}{options: width="100\%" alt="Figure: geombkde01.png"} 116 | } 117 | 118 | \if{latex}{ 119 | A sample of the output from \code{geom_bkde()}: 120 | 121 | \figure{geombkde01.png}{options: width=10cm} 122 | } 123 | } 124 | \section{Aesthetics}{ 125 | 126 | \code{geom_bkde} understands the following aesthetics (required aesthetics 127 | are in bold): 128 | \itemize{ 129 | \item \strong{\code{x}} 130 | \item \strong{\code{y}} 131 | \item \code{alpha} 132 | \item \code{color} 133 | \item \code{fill} 134 | \item \code{linetype} 135 | \item \code{size} 136 | } 137 | } 138 | 139 | \section{Computed variables}{ 140 | 141 | \describe{ 142 | \item{density}{density estimate} 143 | \item{count}{density * number of points - useful for stacked density 144 | plots} 145 | \item{scaled}{density estimate, scaled to maximum of 1} 146 | } 147 | } 148 | 149 | \examples{ 150 | data(geyser, package="MASS") 151 | 152 | ggplot(geyser, aes(x=duration)) + 153 | stat_bkde(alpha=1/2) 154 | 155 | ggplot(geyser, aes(x=duration)) + 156 | geom_bkde(alpha=1/2) 157 | 158 | ggplot(geyser, aes(x=duration)) + 159 | stat_bkde(bandwidth=0.25) 160 | 161 | ggplot(geyser, aes(x=duration)) + 162 | geom_bkde(bandwidth=0.25) 163 | } 164 | \seealso{ 165 | See \code{\link{geom_histogram}}, \code{\link{geom_freqpoly}} for 166 | other methods of displaying continuous distribution. 167 | See \code{\link{geom_violin}} for a compact density display. 168 | } 169 | -------------------------------------------------------------------------------- /man/geom_bkde2d.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_bkde2d.r 3 | \name{geom_bkde2d} 4 | \alias{geom_bkde2d} 5 | \alias{stat_bkde2d} 6 | \title{Contours from a 2d density estimate.} 7 | \usage{ 8 | geom_bkde2d( 9 | mapping = NULL, 10 | data = NULL, 11 | stat = "bkde2d", 12 | position = "identity", 13 | bandwidth = NULL, 14 | range.x = NULL, 15 | lineend = "butt", 16 | contour = TRUE, 17 | linejoin = "round", 18 | linemitre = 1, 19 | na.rm = FALSE, 20 | show.legend = NA, 21 | inherit.aes = TRUE, 22 | ... 23 | ) 24 | 25 | stat_bkde2d( 26 | mapping = NULL, 27 | data = NULL, 28 | geom = "density2d", 29 | position = "identity", 30 | contour = TRUE, 31 | bandwidth = NULL, 32 | grid_size = c(51, 51), 33 | range.x = NULL, 34 | truncate = TRUE, 35 | na.rm = FALSE, 36 | show.legend = NA, 37 | inherit.aes = TRUE, 38 | ... 39 | ) 40 | } 41 | \arguments{ 42 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 43 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 44 | at the top level of the plot. You must supply \code{mapping} if there is no plot 45 | mapping.} 46 | 47 | \item{data}{The data to be displayed in this layer. There are three 48 | options: 49 | 50 | If \code{NULL}, the default, the data is inherited from the plot 51 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 52 | 53 | A \code{data.frame}, or other object, will override the plot 54 | data. All objects will be fortified to produce a data frame. See 55 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 56 | 57 | A \code{function} will be called with a single argument, 58 | the plot data. The return value must be a \code{data.frame}, and 59 | will be used as the layer data. A \code{function} can be created 60 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 61 | 62 | \item{stat}{The statistical transformation to use on the data for this 63 | layer, either as a \code{ggproto} \code{Geom} subclass or as a string naming the 64 | stat stripped of the \code{stat_} prefix (e.g. \code{"count"} rather than 65 | \code{"stat_count"})} 66 | 67 | \item{position}{Position adjustment, either as a string naming the adjustment 68 | (e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a 69 | position adjustment function. Use the latter if you need to change the 70 | settings of the adjustment.} 71 | 72 | \item{bandwidth}{the kernel bandwidth smoothing parameter. see 73 | \code{\link[KernSmooth]{bkde2D}} for details. If \code{NULL}, 74 | it will be computed for you but will most likely not yield optimal 75 | results. see \code{\link[KernSmooth]{bkde2D}} for details} 76 | 77 | \item{range.x}{a list containing two vectors, where each vector contains the 78 | minimum and maximum values of x at which to compute the estimate for 79 | each direction. see \code{\link[KernSmooth]{bkde2D}} for details} 80 | 81 | \item{lineend}{Line end style (round, butt, square).} 82 | 83 | \item{contour}{If \code{TRUE}, contour the results of the 2d density 84 | estimation} 85 | 86 | \item{linejoin}{Line join style (round, mitre, bevel).} 87 | 88 | \item{linemitre}{Line mitre limit (number greater than 1).} 89 | 90 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with 91 | a warning. If \code{TRUE}, missing values are silently removed.} 92 | 93 | \item{show.legend}{logical. Should this layer be included in the legends? 94 | \code{NA}, the default, includes if any aesthetics are mapped. 95 | \code{FALSE} never includes, and \code{TRUE} always includes. 96 | It can also be a named logical vector to finely select the aesthetics to 97 | display.} 98 | 99 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 100 | rather than combining with them. This is most useful for helper functions 101 | that define both data and aesthetics and shouldn't inherit behaviour from 102 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 103 | 104 | \item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{layer()}}. These are 105 | often aesthetics, used to set an aesthetic to a fixed value, like 106 | \code{colour = "red"} or \code{size = 3}. They may also be parameters 107 | to the paired geom/stat.} 108 | 109 | \item{geom}{default geom to use with this stat} 110 | 111 | \item{grid_size}{vector containing the number of equally spaced points in each 112 | direction over which the density is to be estimated. see 113 | \code{\link[KernSmooth]{bkde2D}} for details} 114 | 115 | \item{truncate}{logical flag: if TRUE, data with x values outside the range 116 | specified by range.x are ignored. see \code{\link[KernSmooth]{bkde2D}} 117 | for details} 118 | } 119 | \description{ 120 | Perform a 2D kernel density estimation using \code{bkde2D} and display the 121 | results with contours. This can be useful for dealing with overplotting 122 | } 123 | \details{ 124 | \if{html}{ 125 | A sample of the output from \code{geom_bkde2d()}: 126 | 127 | \figure{geombkde2d01.png}{options: width="100\%" alt="Figure: geombkde2d01.png"} 128 | } 129 | 130 | \if{latex}{ 131 | A sample of the output from \code{geom_bkde2d()}: 132 | 133 | \figure{geombkde2d01.png}{options: width=10cm} 134 | } 135 | } 136 | \section{Computed variables}{ 137 | 138 | Same as \code{\link{stat_contour}} 139 | } 140 | 141 | \examples{ 142 | m <- ggplot(faithful, aes(x = eruptions, y = waiting)) + 143 | geom_point() + 144 | xlim(0.5, 6) + 145 | ylim(40, 110) 146 | 147 | m + geom_bkde2d(bandwidth=c(0.5, 4)) 148 | 149 | m + stat_bkde2d(bandwidth=c(0.5, 4), aes(fill = ..level..), geom = "polygon") 150 | 151 | # If you map an aesthetic to a categorical variable, you will get a 152 | # set of contours for each value of that variable 153 | set.seed(4393) 154 | dsmall <- diamonds[sample(nrow(diamonds), 1000), ] 155 | d <- ggplot(dsmall, aes(x, y)) + 156 | geom_bkde2d(bandwidth=c(0.5, 0.5), aes(colour = cut)) 157 | d 158 | 159 | # If we turn contouring off, we can use use geoms like tiles: 160 | d + stat_bkde2d(bandwidth=c(0.5, 0.5), geom = "raster", 161 | aes(fill = ..density..), contour = FALSE) 162 | 163 | # Or points: 164 | d + stat_bkde2d(bandwidth=c(0.5, 0.5), geom = "point", 165 | aes(size = ..density..), contour = FALSE) 166 | } 167 | \seealso{ 168 | \code{\link{geom_contour}} for contour drawing geom, 169 | \code{\link{stat_sum}} for another way of dealing with overplotting 170 | } 171 | -------------------------------------------------------------------------------- /man/geom_cartogram.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_cartogram.r 3 | \name{geom_cartogram} 4 | \alias{geom_cartogram} 5 | \title{Map polygons layer enabling the display of show statistical information} 6 | \usage{ 7 | geom_cartogram( 8 | mapping = NULL, 9 | data = NULL, 10 | stat = "identity", 11 | ..., 12 | map, 13 | na.rm = FALSE, 14 | show.legend = NA, 15 | inherit.aes = TRUE 16 | ) 17 | } 18 | \arguments{ 19 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 20 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 21 | at the top level of the plot. You must supply \code{mapping} if there is no plot 22 | mapping.} 23 | 24 | \item{data}{The data to be displayed in this layer. There are three 25 | options: 26 | 27 | If \code{NULL}, the default, the data is inherited from the plot 28 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 29 | 30 | A \code{data.frame}, or other object, will override the plot 31 | data. All objects will be fortified to produce a data frame. See 32 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 33 | 34 | A \code{function} will be called with a single argument, 35 | the plot data. The return value must be a \code{data.frame}, and 36 | will be used as the layer data. A \code{function} can be created 37 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 38 | 39 | \item{stat}{The statistical transformation to use on the data for this 40 | layer, either as a \code{ggproto} \code{Geom} subclass or as a string naming the 41 | stat stripped of the \code{stat_} prefix (e.g. \code{"count"} rather than 42 | \code{"stat_count"})} 43 | 44 | \item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{layer()}}. These are 45 | often aesthetics, used to set an aesthetic to a fixed value, like 46 | \code{colour = "red"} or \code{size = 3}. They may also be parameters 47 | to the paired geom/stat.} 48 | 49 | \item{map}{Data frame that contains the map coordinates. This will 50 | typically be created using \code{\link{fortify}} on a spatial object. 51 | It must contain columns \code{x}, \code{long} or \code{longitude}, 52 | \code{y}, \code{lat} or \code{latitude} and \code{region} or \code{id}.} 53 | 54 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with 55 | a warning. If \code{TRUE}, missing values are silently removed.} 56 | 57 | \item{show.legend}{logical. Should this layer be included in the legends? 58 | \code{NA}, the default, includes if any aesthetics are mapped. 59 | \code{FALSE} never includes, and \code{TRUE} always includes. 60 | It can also be a named logical vector to finely select the aesthetics to 61 | display.} 62 | 63 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 64 | rather than combining with them. This is most useful for helper functions 65 | that define both data and aesthetics and shouldn't inherit behaviour from 66 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 67 | } 68 | \description{ 69 | This replicates the old behaviour of \code{geom_map()}, enabling specifying of 70 | \code{x} and \code{y} aesthetics. 71 | } 72 | \section{Aesthetics}{ 73 | 74 | \code{geom_cartogram} understands the following aesthetics (required aesthetics are in bold): 75 | \itemize{ 76 | \item \code{map_id} 77 | \item \code{alpha} 78 | \item \code{colour} 79 | \item \code{fill} 80 | \item \code{group} 81 | \item \code{linetype} 82 | \item \code{size} 83 | \item \code{x} 84 | \item \code{y} 85 | } 86 | } 87 | 88 | \examples{ 89 | \dontrun{ 90 | # When using geom_polygon, you will typically need two data frames: 91 | # one contains the coordinates of each polygon (positions), and the 92 | # other the values associated with each polygon (values). An id 93 | # variable links the two together 94 | 95 | ids <- factor(c("1.1", "2.1", "1.2", "2.2", "1.3", "2.3")) 96 | 97 | values <- data.frame( 98 | id = ids, 99 | value = c(3, 3.1, 3.1, 3.2, 3.15, 3.5) 100 | ) 101 | 102 | positions <- data.frame( 103 | id = rep(ids, each = 4), 104 | x = c(2, 1, 1.1, 2.2, 1, 0, 0.3, 1.1, 2.2, 1.1, 1.2, 2.5, 1.1, 0.3, 105 | 0.5, 1.2, 2.5, 1.2, 1.3, 2.7, 1.2, 0.5, 0.6, 1.3), 106 | y = c(-0.5, 0, 1, 0.5, 0, 0.5, 1.5, 1, 0.5, 1, 2.1, 1.7, 1, 1.5, 107 | 2.2, 2.1, 1.7, 2.1, 3.2, 2.8, 2.1, 2.2, 3.3, 3.2) 108 | ) 109 | 110 | ggplot() + 111 | geom_cartogram(aes(x, y, map_id = id), map = positions, data=positions) 112 | 113 | ggplot() + 114 | geom_cartogram(aes(x, y, map_id = id), map = positions, data=positions) + 115 | geom_cartogram(data=values, map=positions, aes(fill = value, map_id=id)) 116 | 117 | ggplot() + 118 | geom_cartogram(aes(x, y, map_id = id), map = positions, data=positions) + 119 | geom_cartogram(data=values, map=positions, aes(fill = value, map_id=id)) + 120 | ylim(0, 3) 121 | 122 | # Better example 123 | crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests) 124 | crimesm <- reshape2::melt(crimes, id = 1) 125 | 126 | if (require(maps)) { 127 | 128 | states_map <- map_data("state") 129 | 130 | ggplot() + 131 | geom_cartogram(aes(long, lat, map_id = region), map = states_map, data=states_map) + 132 | geom_cartogram(aes(fill = Murder, map_id = state), map=states_map, data=crimes) 133 | 134 | last_plot() + coord_map("polyconic") 135 | 136 | ggplot() + 137 | geom_cartogram(aes(long, lat, map_id=region), map = states_map, data=states_map) + 138 | geom_cartogram(aes(fill = value, map_id=state), map = states_map, data=crimesm) + 139 | coord_map("polyconic") + 140 | facet_wrap( ~ variable) 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /man/geom_dumbbell.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_dumbbell.R 3 | \name{geom_dumbbell} 4 | \alias{geom_dumbbell} 5 | \title{Dumbbell charts} 6 | \usage{ 7 | geom_dumbbell( 8 | mapping = NULL, 9 | data = NULL, 10 | ..., 11 | colour_x = NULL, 12 | size_x = NULL, 13 | colour_xend = NULL, 14 | size_xend = NULL, 15 | dot_guide = FALSE, 16 | dot_guide_size = NULL, 17 | dot_guide_colour = NULL, 18 | na.rm = FALSE, 19 | show.legend = NA, 20 | inherit.aes = TRUE, 21 | position = "identity" 22 | ) 23 | } 24 | \arguments{ 25 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 26 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 27 | at the top level of the plot. You must supply \code{mapping} if there is no plot 28 | mapping.} 29 | 30 | \item{data}{The data to be displayed in this layer. There are three 31 | options: 32 | 33 | If \code{NULL}, the default, the data is inherited from the plot 34 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 35 | 36 | A \code{data.frame}, or other object, will override the plot 37 | data. All objects will be fortified to produce a data frame. See 38 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 39 | 40 | A \code{function} will be called with a single argument, 41 | the plot data. The return value must be a \code{data.frame}, and 42 | will be used as the layer data. A \code{function} can be created 43 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 44 | 45 | \item{...}{other arguments passed on to \code{\link{layer}}. These are 46 | often aesthetics, used to set an aesthetic to a fixed value, like 47 | \code{color = "red"} or \code{size = 3}. They may also be parameters 48 | to the paired geom/stat.} 49 | 50 | \item{colour_x}{the colour of the start point} 51 | 52 | \item{size_x}{the size of the start point} 53 | 54 | \item{colour_xend}{the colour of the end point} 55 | 56 | \item{size_xend}{the size of the end point} 57 | 58 | \item{dot_guide}{if \code{TRUE}, a leading dotted line will be placed before the left-most dumbbell point} 59 | 60 | \item{dot_guide_size, dot_guide_colour}{singe-value aesthetics for \code{dot_guide}} 61 | 62 | \item{na.rm}{If \code{FALSE} (the default), removes missing values with 63 | a warning. If \code{TRUE} silently removes missing values.} 64 | 65 | \item{show.legend}{logical. Should this layer be included in the legends? 66 | \code{NA}, the default, includes if any aesthetics are mapped. 67 | \code{FALSE} never includes, and \code{TRUE} always includes. 68 | It can also be a named logical vector to finely select the aesthetics to 69 | display.} 70 | 71 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 72 | rather than combining with them. This is most useful for helper functions 73 | that define both data and aesthetics and shouldn't inherit behaviour from 74 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 75 | 76 | \item{position}{Position adjustment, either as a string, or the result of a 77 | call to a position adjustment function.} 78 | } 79 | \description{ 80 | The dumbbell geom is used to create dumbbell charts. 81 | } 82 | \details{ 83 | Dumbbell dot plots — dot plots with two or more series of data — are an 84 | alternative to the clustered bar chart or slope graph. 85 | } 86 | \section{Aesthetics}{ 87 | 88 | \Sexpr[results=rd,stage=build]{ggplot2:::rd_aesthetics("geom", "segment")} 89 | } 90 | 91 | \examples{ 92 | library(ggplot2) 93 | 94 | df <- data.frame(trt=LETTERS[1:5], l=c(20, 40, 10, 30, 50), r=c(70, 50, 30, 60, 80)) 95 | 96 | ggplot(df, aes(y=trt, x=l, xend=r)) + 97 | geom_dumbbell(size=3, color="#e3e2e1", 98 | colour_x = "#5b8124", colour_xend = "#bad744", 99 | dot_guide=TRUE, dot_guide_size=0.25) + 100 | labs(x=NULL, y=NULL, title="ggplot2 geom_dumbbell with dot guide") + 101 | theme_minimal() + 102 | theme(panel.grid.major.x=element_line(size=0.05)) 103 | 104 | ## with vertical dodging 105 | df2 <- data.frame(trt = c(LETTERS[1:5], "D"), 106 | l = c(20, 40, 10, 30, 50, 40), 107 | r = c(70, 50, 30, 60, 80, 70)) 108 | 109 | ggplot(df2, aes(y=trt, x=l, xend=r)) + 110 | geom_dumbbell(size=3, color="#e3e2e1", 111 | colour_x = "#5b8124", colour_xend = "#bad744", 112 | dot_guide=TRUE, dot_guide_size=0.25, 113 | position=position_dodgev(height=0.4)) + 114 | labs(x=NULL, y=NULL, title="ggplot2 geom_dumbbell with dot guide") + 115 | theme_minimal() + 116 | theme(panel.grid.major.x=element_line(size=0.05)) 117 | } 118 | -------------------------------------------------------------------------------- /man/geom_encircle.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_encircle.r 3 | \name{geom_encircle} 4 | \alias{geom_encircle} 5 | \title{Automatically enclose points in a polygon} 6 | \usage{ 7 | geom_encircle( 8 | mapping = NULL, 9 | data = NULL, 10 | stat = "identity", 11 | position = "identity", 12 | na.rm = FALSE, 13 | show.legend = NA, 14 | inherit.aes = TRUE, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{mapping}{mapping} 20 | 21 | \item{data}{data} 22 | 23 | \item{stat}{stat} 24 | 25 | \item{position}{position} 26 | 27 | \item{na.rm}{na.rm} 28 | 29 | \item{show.legend}{show.legend} 30 | 31 | \item{inherit.aes}{inherit.aes} 32 | 33 | \item{...}{dots} 34 | } 35 | \value{ 36 | adds a circle around the specified points 37 | } 38 | \description{ 39 | Automatically enclose points in a polygon 40 | } 41 | \details{ 42 | \if{html}{ 43 | A sample of the output from \code{geom_encircle()}: 44 | 45 | \figure{geomencircle01.png}{options: width="100\%" alt="Figure: geomencircle01.png"} 46 | } 47 | 48 | \if{latex}{ 49 | A sample of the output from \code{geom_encircle()}: 50 | 51 | \figure{geomencircle01.png}{options: width=10cm} 52 | } 53 | } 54 | \examples{ 55 | d <- data.frame(x=c(1,1,2),y=c(1,2,2)*100) 56 | 57 | gg <- ggplot(d,aes(x,y)) 58 | gg <- gg + scale_x_continuous(expand=c(0.5,1)) 59 | gg <- gg + scale_y_continuous(expand=c(0.5,1)) 60 | 61 | gg + geom_encircle(s_shape=1, expand=0) + geom_point() 62 | 63 | gg + geom_encircle(s_shape=1, expand=0.1, colour="red") + geom_point() 64 | 65 | gg + geom_encircle(s_shape=0.5, expand=0.1, colour="purple") + geom_point() 66 | 67 | gg + geom_encircle(data=subset(d, x==1), colour="blue", spread=0.02) + 68 | geom_point() 69 | 70 | gg +geom_encircle(data=subset(d, x==2), colour="cyan", spread=0.04) + 71 | geom_point() 72 | 73 | gg <- ggplot(mpg, aes(displ, hwy)) 74 | gg + geom_encircle(data=subset(mpg, hwy>40)) + geom_point() 75 | gg + geom_encircle(aes(group=manufacturer)) + geom_point() 76 | gg + geom_encircle(aes(group=manufacturer,fill=manufacturer),alpha=0.4)+ 77 | geom_point() 78 | gg + geom_encircle(aes(group=manufacturer,colour=manufacturer))+ 79 | geom_point() 80 | 81 | ss <- subset(mpg,hwy>31 & displ<2) 82 | 83 | gg + geom_encircle(data=ss, colour="blue", s_shape=0.9, expand=0.07) + 84 | geom_point() + geom_point(data=ss, colour="blue") 85 | } 86 | \author{ 87 | Ben Bolker 88 | } 89 | -------------------------------------------------------------------------------- /man/geom_horizon.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_horizon.r 3 | \docType{data} 4 | \name{geom_horizon} 5 | \alias{geom_horizon} 6 | \alias{GeomHorizon} 7 | \alias{stat_horizon} 8 | \alias{StatHorizon} 9 | \title{Plot a time series as a horizon plot} 10 | \format{ 11 | An object of class \code{GeomHorizon} (inherits from \code{GeomArea}, \code{GeomRibbon}, \code{Geom}, \code{ggproto}, \code{gg}) of length 4. 12 | 13 | An object of class \code{StatHorizon} (inherits from \code{Stat}, \code{ggproto}, \code{gg}) of length 5. 14 | } 15 | \usage{ 16 | geom_horizon( 17 | mapping = NULL, 18 | data = NULL, 19 | show.legend = TRUE, 20 | inherit.aes = TRUE, 21 | na.rm = TRUE, 22 | bandwidth = NULL, 23 | ... 24 | ) 25 | 26 | GeomHorizon 27 | 28 | stat_horizon( 29 | mapping = NULL, 30 | data = NULL, 31 | geom = "horizon", 32 | show.legend = TRUE, 33 | inherit.aes = TRUE, 34 | na.rm = TRUE, 35 | bandwidth = NULL, 36 | ... 37 | ) 38 | 39 | StatHorizon 40 | } 41 | \description{ 42 | A horizon plot breaks the Y dimension down using colours. This is useful 43 | when visualising y values spanning a vast range and / or trying to highlight 44 | outliers without losing context of the rest of the data.\cr \cr Horizon 45 | plots are best viewed in an apsect ratio of very low vertical length. 46 | } 47 | \section{Aesthetics}{ 48 | \code{x}, \code{y}, \code{fill}. \code{fill} defaults to \code{..band..} which is 49 | the band number the current data fill area belongs in. 50 | } 51 | 52 | \section{Other parameters}{ 53 | \code{bandwidth}, to dictate the span of a band. 54 | } 55 | 56 | \keyword{internal} 57 | -------------------------------------------------------------------------------- /man/geom_lollipop.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_lollipop.r 3 | \name{geom_lollipop} 4 | \alias{geom_lollipop} 5 | \title{Lollipop charts} 6 | \usage{ 7 | geom_lollipop( 8 | mapping = NULL, 9 | data = NULL, 10 | ..., 11 | horizontal = FALSE, 12 | point.colour = NULL, 13 | point.size = NULL, 14 | na.rm = FALSE, 15 | show.legend = NA, 16 | inherit.aes = TRUE 17 | ) 18 | } 19 | \arguments{ 20 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 21 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 22 | at the top level of the plot. You must supply \code{mapping} if there is no plot 23 | mapping.} 24 | 25 | \item{data}{The data to be displayed in this layer. There are three 26 | options: 27 | 28 | If \code{NULL}, the default, the data is inherited from the plot 29 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 30 | 31 | A \code{data.frame}, or other object, will override the plot 32 | data. All objects will be fortified to produce a data frame. See 33 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 34 | 35 | A \code{function} will be called with a single argument, 36 | the plot data. The return value must be a \code{data.frame}, and 37 | will be used as the layer data. A \code{function} can be created 38 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 39 | 40 | \item{...}{other arguments passed on to \code{\link{layer}}. These are 41 | often aesthetics, used to set an aesthetic to a fixed value, like 42 | \code{color = "red"} or \code{size = 3}. They may also be parameters 43 | to the paired geom/stat.} 44 | 45 | \item{horizontal}{\code{horizontal} is \code{FALSE} (the default), the function 46 | will draw the lollipops up from the X axis (i.e. it will set \code{xend} 47 | to \code{x} & \code{yend} to \code{0}). If \code{TRUE}, it wiill set 48 | \code{yend} to \code{y} & \code{xend} to \code{0}). Make sure you map the 49 | \code{x} & \code{y} aesthetics accordingly. This parameter helps avoid 50 | the need for \code{coord_flip()}.} 51 | 52 | \item{point.colour}{the colour of the point} 53 | 54 | \item{point.size}{the size of the point} 55 | 56 | \item{na.rm}{If \code{FALSE} (the default), removes missing values with 57 | a warning. If \code{TRUE} silently removes missing values.} 58 | 59 | \item{show.legend}{logical. Should this layer be included in the legends? 60 | \code{NA}, the default, includes if any aesthetics are mapped. 61 | \code{FALSE} never includes, and \code{TRUE} always includes. 62 | It can also be a named logical vector to finely select the aesthetics to 63 | display.} 64 | 65 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 66 | rather than combining with them. This is most useful for helper functions 67 | that define both data and aesthetics and shouldn't inherit behaviour from 68 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 69 | } 70 | \description{ 71 | The lollipop geom is used to create lollipop charts. 72 | } 73 | \details{ 74 | Lollipop charts are the creation of Andy Cotgreave going back to 2011. They 75 | are a combination of a thin segment, starting at with a dot at the top and are a 76 | suitable alternative to or replacement for bar charts. 77 | 78 | Use the \code{horizontal} parameter to abate the need for \code{coord_flip()} 79 | (see the \code{Arguments} section for details). 80 | 81 | \if{html}{ 82 | A sample of the output from \code{geom_lollipop()}: 83 | 84 | \figure{geomlollipop01.png}{options: width="100\%" alt="Figure: geomlollipop01.png"} 85 | } 86 | 87 | \if{latex}{ 88 | A sample of the output from \code{geom_lollipop()}: 89 | 90 | \figure{geomlollipop01.png}{options: width=10cm} 91 | } 92 | } 93 | \section{Aesthetics}{ 94 | 95 | \Sexpr[results=rd,stage=build]{ggplot2:::rd_aesthetics("geom", "point")} 96 | } 97 | 98 | \examples{ 99 | df <- data.frame(trt=LETTERS[1:10], 100 | value=seq(100, 10, by=-10)) 101 | 102 | ggplot(df, aes(trt, value)) + geom_lollipop() 103 | 104 | ggplot(df, aes(value, trt)) + geom_lollipop(horizontal=TRUE) 105 | } 106 | -------------------------------------------------------------------------------- /man/geom_spikelines.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_spikelines.R 3 | \name{geom_spikelines} 4 | \alias{geom_spikelines} 5 | \title{Draw spikelines on a plot} 6 | \usage{ 7 | geom_spikelines( 8 | mapping = NULL, 9 | data = NULL, 10 | stat = "identity", 11 | position = "identity", 12 | ..., 13 | arrow = NULL, 14 | lineend = "butt", 15 | linejoin = "round", 16 | na.rm = FALSE, 17 | show.legend = NA, 18 | inherit.aes = TRUE 19 | ) 20 | } 21 | \arguments{ 22 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 23 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 24 | at the top level of the plot. You must supply \code{mapping} if there is no plot 25 | mapping.} 26 | 27 | \item{data}{The data to be displayed in this layer. There are three 28 | options: 29 | 30 | If \code{NULL}, the default, the data is inherited from the plot 31 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 32 | 33 | A \code{data.frame}, or other object, will override the plot 34 | data. All objects will be fortified to produce a data frame. See 35 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 36 | 37 | A \code{function} will be called with a single argument, 38 | the plot data. The return value must be a \code{data.frame}, and 39 | will be used as the layer data. A \code{function} can be created 40 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 41 | 42 | \item{stat}{The statistical transformation to use on the data for this 43 | layer, either as a \code{ggproto} \code{Geom} subclass or as a string naming the 44 | stat stripped of the \code{stat_} prefix (e.g. \code{"count"} rather than 45 | \code{"stat_count"})} 46 | 47 | \item{position}{Position adjustment, either as a string naming the adjustment 48 | (e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a 49 | position adjustment function. Use the latter if you need to change the 50 | settings of the adjustment.} 51 | 52 | \item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{layer()}}. These are 53 | often aesthetics, used to set an aesthetic to a fixed value, like 54 | \code{colour = "red"} or \code{size = 3}. They may also be parameters 55 | to the paired geom/stat.} 56 | 57 | \item{arrow}{Arrow specification, as created by \code{\link[grid:arrow]{grid::arrow()}}.} 58 | 59 | \item{lineend}{Line end style (round, butt, square).} 60 | 61 | \item{linejoin}{Line join style (round, mitre, bevel).} 62 | 63 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with 64 | a warning. If \code{TRUE}, missing values are silently removed.} 65 | 66 | \item{show.legend}{logical. Should this layer be included in the legends? 67 | \code{NA}, the default, includes if any aesthetics are mapped. 68 | \code{FALSE} never includes, and \code{TRUE} always includes. 69 | It can also be a named logical vector to finely select the aesthetics to 70 | display.} 71 | 72 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 73 | rather than combining with them. This is most useful for helper functions 74 | that define both data and aesthetics and shouldn't inherit behaviour from 75 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 76 | } 77 | \description{ 78 | Segment reference lines that originate at an point 79 | } 80 | \examples{ 81 | 82 | mtcars$name <- rownames(mtcars) 83 | 84 | p <- ggplot(data = mtcars, aes(x=mpg,y=disp)) + geom_point() 85 | 86 | p + geom_spikelines(data = mtcars[mtcars$carb==4,],linetype = 2) 87 | 88 | p + geom_spikelines(data = mtcars[mtcars$carb==4,],aes(colour = factor(gear)), linetype = 2) 89 | 90 | \dontrun{ 91 | require(ggrepel) 92 | p + geom_spikelines(data = mtcars[mtcars$carb==4,],aes(colour = factor(gear)), linetype = 2) + 93 | ggrepel::geom_label_repel(data = mtcars[mtcars$carb==4,],aes(label = name)) 94 | } 95 | 96 | } 97 | \author{ 98 | Jonathan Sidi 99 | } 100 | -------------------------------------------------------------------------------- /man/geom_stateface.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stateface.r 3 | \name{geom_stateface} 4 | \alias{geom_stateface} 5 | \title{Use ProPublica's StateFace font in ggplot2 plots} 6 | \usage{ 7 | geom_stateface( 8 | mapping = NULL, 9 | data = NULL, 10 | stat = "identity", 11 | position = "identity", 12 | ..., 13 | parse = FALSE, 14 | nudge_x = 0, 15 | nudge_y = 0, 16 | check_overlap = FALSE, 17 | na.rm = FALSE, 18 | show.legend = NA, 19 | inherit.aes = TRUE 20 | ) 21 | } 22 | \arguments{ 23 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 24 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 25 | at the top level of the plot. You must supply \code{mapping} if there is no plot 26 | mapping.} 27 | 28 | \item{data}{The data to be displayed in this layer. There are three 29 | options: 30 | 31 | If \code{NULL}, the default, the data is inherited from the plot 32 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 33 | 34 | A \code{data.frame}, or other object, will override the plot 35 | data. All objects will be fortified to produce a data frame. See 36 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 37 | 38 | A \code{function} will be called with a single argument, 39 | the plot data. The return value must be a \code{data.frame}, and 40 | will be used as the layer data. A \code{function} can be created 41 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 42 | 43 | \item{stat}{The statistical transformation to use on the data for this 44 | layer, either as a \code{ggproto} \code{Geom} subclass or as a string naming the 45 | stat stripped of the \code{stat_} prefix (e.g. \code{"count"} rather than 46 | \code{"stat_count"})} 47 | 48 | \item{position}{Position adjustment, either as a string, or the result of 49 | a call to a position adjustment function. Cannot be jointy specified with 50 | \code{nudge_x} or \code{nudge_y}.} 51 | 52 | \item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{layer()}}. These are 53 | often aesthetics, used to set an aesthetic to a fixed value, like 54 | \code{colour = "red"} or \code{size = 3}. They may also be parameters 55 | to the paired geom/stat.} 56 | 57 | \item{parse}{If \code{TRUE}, the labels will be parsed into expressions and 58 | displayed as described in \code{?plotmath}.} 59 | 60 | \item{nudge_x, nudge_y}{Horizontal and vertical adjustment to nudge l 61 | abels by. Useful for offsetting text from points, particularly 62 | on discrete scales.} 63 | 64 | \item{check_overlap}{If \code{TRUE}, text that overlaps previous text in the 65 | same layer will not be plotted. \code{check_overlap} happens at draw time and in 66 | the order of the data. Therefore data should be arranged by the label 67 | column before calling \code{geom_text()}. Note that this argument is not 68 | supported by \code{geom_label()}.} 69 | 70 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with 71 | a warning. If \code{TRUE}, missing values are silently removed.} 72 | 73 | \item{show.legend}{logical. Should this layer be included in the legends? 74 | \code{NA}, the default, includes if any aesthetics are mapped. 75 | \code{FALSE} never includes, and \code{TRUE} always includes. 76 | It can also be a named logical vector to finely select the aesthetics to 77 | display.} 78 | 79 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 80 | rather than combining with them. This is most useful for helper functions 81 | that define both data and aesthetics and shouldn't inherit behaviour from 82 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 83 | } 84 | \description{ 85 | The \code{label} parameter can be either a 2-letter state abbreviation 86 | or a full state name. \code{geom_stateface()} will take care of the 87 | translation to StateFace font glyph characters. 88 | } 89 | \details{ 90 | The package will also take care of loading the StateFace font for 91 | PDF and other devices, but to use it with the on-screen ggplot2 92 | device, you'll need to install the font on your system. 93 | 94 | \code{ggalt} ships with a copy of the StateFace TTF font. You can 95 | run \code{show_stateface()} to get the filesystem location and then 96 | load the font manually from there. 97 | 98 | \if{html}{ 99 | A sample of the output from \code{geom_stateface()}: 100 | 101 | \figure{geomstateface01.png}{options: width="100\%" alt="Figure: geomstateface01.png"} 102 | } 103 | 104 | \if{latex}{ 105 | A sample of the output from \code{geom_stateface()}: 106 | 107 | \figure{geomstateface01.png}{options: width=10cm} 108 | } 109 | } 110 | \examples{ 111 | \dontrun{ 112 | library(ggplot2) 113 | library(ggalt) 114 | 115 | # Run show_stateface() to see the location of the TTF StateFace font 116 | # You need to install it for it to work 117 | 118 | set.seed(1492) 119 | dat <- data.frame(state=state.abb, 120 | x=sample(100, 50), 121 | y=sample(100, 50), 122 | col=sample(c("#b2182b", "#2166ac"), 50, replace=TRUE), 123 | sz=sample(6:15, 50, replace=TRUE), 124 | stringsAsFactors=FALSE) 125 | gg <- ggplot(dat, aes(x=x, y=y)) 126 | gg <- gg + geom_stateface(aes(label=state, color=col, size=sz)) 127 | gg <- gg + scale_color_identity() 128 | gg <- gg + scale_size_identity() 129 | gg 130 | } 131 | } 132 | \seealso{ 133 | Other StateFace operations: 134 | \code{\link{load_stateface}()}, 135 | \code{\link{show_stateface}()} 136 | } 137 | \concept{StateFace operations} 138 | -------------------------------------------------------------------------------- /man/geom_ubar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_ubar.r 3 | \name{geom_ubar} 4 | \alias{geom_ubar} 5 | \title{Uniform "bar" charts} 6 | \usage{ 7 | geom_ubar( 8 | mapping = NULL, 9 | data = NULL, 10 | stat = "identity", 11 | position = "identity", 12 | ..., 13 | na.rm = FALSE, 14 | show.legend = NA, 15 | inherit.aes = TRUE 16 | ) 17 | } 18 | \arguments{ 19 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 20 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 21 | at the top level of the plot. You must supply \code{mapping} if there is no plot 22 | mapping.} 23 | 24 | \item{data}{The data to be displayed in this layer. There are three 25 | options: 26 | 27 | If \code{NULL}, the default, the data is inherited from the plot 28 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 29 | 30 | A \code{data.frame}, or other object, will override the plot 31 | data. All objects will be fortified to produce a data frame. See 32 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 33 | 34 | A \code{function} will be called with a single argument, 35 | the plot data. The return value must be a \code{data.frame}, and 36 | will be used as the layer data. A \code{function} can be created 37 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 38 | 39 | \item{stat}{The statistical transformation to use on the data for this 40 | layer, either as a \code{ggproto} \code{Geom} subclass or as a string naming the 41 | stat stripped of the \code{stat_} prefix (e.g. \code{"count"} rather than 42 | \code{"stat_count"})} 43 | 44 | \item{position}{Position adjustment, either as a string naming the adjustment 45 | (e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a 46 | position adjustment function. Use the latter if you need to change the 47 | settings of the adjustment.} 48 | 49 | \item{...}{other arguments passed on to \code{layer}. These are 50 | often aesthetics, used to set an aesthetic to a fixed value, like 51 | \code{color = "red"} or \code{size = 3}. They may also be parameters 52 | to the paired geom/stat.} 53 | 54 | \item{na.rm}{If \code{FALSE} (the default), removes missing values with 55 | a warning. If \code{TRUE} silently removes missing values.} 56 | 57 | \item{show.legend}{logical. Should this layer be included in the legends? 58 | \code{NA}, the default, includes if any aesthetics are mapped. 59 | \code{FALSE} never includes, and \code{TRUE} always includes. 60 | It can also be a named logical vector to finely select the aesthetics to 61 | display.} 62 | 63 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 64 | rather than combining with them. This is most useful for helper functions 65 | that define both data and aesthetics and shouldn't inherit behaviour from 66 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 67 | } 68 | \description{ 69 | I've been using \code{geom_segment} more to make "bar" charts, setting 70 | \code{xend} to whatever \code{x} is and \code{yend} to \code{0}. The bar widths remain 71 | constant without any tricks and you have granular control over the 72 | segment width. I decided it was time to make a \code{geom}. 73 | } 74 | \section{Aesthetics}{ 75 | 76 | `geom_ubar`` understands the following aesthetics (required aesthetics are in bold): 77 | \itemize{ 78 | \item \strong{\code{x}} 79 | \item \strong{\code{y}} 80 | \item \code{alpha} 81 | \item \code{colour} 82 | \item \code{group} 83 | \item \code{linetype} 84 | \item \code{size} 85 | } 86 | } 87 | 88 | \examples{ 89 | library(ggplot2) 90 | 91 | data(economics) 92 | ggplot(economics, aes(date, uempmed)) + 93 | geom_ubar() 94 | } 95 | -------------------------------------------------------------------------------- /man/geom_xspline.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_xspline.r 3 | \name{geom_xspline} 4 | \alias{geom_xspline} 5 | \alias{stat_xspline} 6 | \title{Connect control points/observations with an X-spline} 7 | \usage{ 8 | geom_xspline( 9 | mapping = NULL, 10 | data = NULL, 11 | stat = "xspline", 12 | position = "identity", 13 | na.rm = TRUE, 14 | show.legend = NA, 15 | inherit.aes = TRUE, 16 | spline_shape = -0.25, 17 | open = TRUE, 18 | rep_ends = TRUE, 19 | ... 20 | ) 21 | 22 | stat_xspline( 23 | mapping = NULL, 24 | data = NULL, 25 | geom = "line", 26 | position = "identity", 27 | na.rm = TRUE, 28 | show.legend = NA, 29 | inherit.aes = TRUE, 30 | spline_shape = -0.25, 31 | open = TRUE, 32 | rep_ends = TRUE, 33 | ... 34 | ) 35 | } 36 | \arguments{ 37 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 38 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 39 | at the top level of the plot. You must supply \code{mapping} if there is no plot 40 | mapping.} 41 | 42 | \item{data}{The data to be displayed in this layer. There are three 43 | options: 44 | 45 | If \code{NULL}, the default, the data is inherited from the plot 46 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 47 | 48 | A \code{data.frame}, or other object, will override the plot 49 | data. All objects will be fortified to produce a data frame. See 50 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 51 | 52 | A \code{function} will be called with a single argument, 53 | the plot data. The return value must be a \code{data.frame}, and 54 | will be used as the layer data. A \code{function} can be created 55 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 56 | 57 | \item{position}{Position adjustment, either as a string naming the adjustment 58 | (e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a 59 | position adjustment function. Use the latter if you need to change the 60 | settings of the adjustment.} 61 | 62 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with 63 | a warning. If \code{TRUE}, missing values are silently removed.} 64 | 65 | \item{show.legend}{logical. Should this layer be included in the legends? 66 | \code{NA}, the default, includes if any aesthetics are mapped. 67 | \code{FALSE} never includes, and \code{TRUE} always includes. 68 | It can also be a named logical vector to finely select the aesthetics to 69 | display.} 70 | 71 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 72 | rather than combining with them. This is most useful for helper functions 73 | that define both data and aesthetics and shouldn't inherit behaviour from 74 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 75 | 76 | \item{spline_shape}{A numeric vector of values between -1 and 1, which 77 | control the shape of the spline relative to the control points.} 78 | 79 | \item{open}{A logical value indicating whether the spline is an open or a 80 | closed shape.} 81 | 82 | \item{rep_ends}{For open X-splines, a logical value indicating whether the 83 | first and last control points should be replicated for drawing the 84 | curve. Ignored for closed X-splines.} 85 | 86 | \item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{layer()}}. These are 87 | often aesthetics, used to set an aesthetic to a fixed value, like 88 | \code{colour = "red"} or \code{size = 3}. They may also be parameters 89 | to the paired geom/stat.} 90 | 91 | \item{geom, stat}{Use to override the default connection between 92 | \code{geom_xspline} and \code{stat_xspline}.} 93 | } 94 | \description{ 95 | Draw an X-spline, a curve drawn relative to control points/observations. 96 | Patterned after \code{geom_line} in that it orders the points by \code{x} 97 | first before computing the splines. 98 | } 99 | \details{ 100 | \if{html}{ 101 | A sample of the output from \code{geom_xspline()}: 102 | 103 | \figure{geomxspline01.png}{options: width="100\%" alt="Figure: geomxspline01.png"} 104 | } 105 | 106 | \if{latex}{ 107 | A sample of the output from \code{geom_xspline()}: 108 | 109 | \figure{geomxspline01.png}{options: width=10cm} 110 | } 111 | 112 | 113 | An X-spline is a line drawn relative to control points. For each control 114 | point, the line may pass through (interpolate) the control point or it may 115 | only approach (approximate) the control point; the behaviour is determined 116 | by a shape parameter for each control point. 117 | 118 | If the shape parameter is greater than zero, the spline approximates the 119 | control points (and is very similar to a cubic B-spline when the shape is 120 | 1). If the shape parameter is less than zero, the spline interpolates the 121 | control points (and is very similar to a Catmull-Rom spline when the shape 122 | is -1). If the shape parameter is 0, the spline forms a sharp corner at that 123 | control point. 124 | 125 | For open X-splines, the start and end control points must have a shape of 126 | 0 (and non-zero values are silently converted to zero). 127 | 128 | For open X-splines, by default the start and end control points are 129 | replicated before the curve is drawn. A curve is drawn between (interpolating 130 | or approximating) the second and third of each set of four control points, 131 | so this default behaviour ensures that the resulting curve starts at the 132 | first control point you have specified and ends at the last control point. 133 | The default behaviour can be turned off via the repEnds argument. 134 | } 135 | \section{Aesthetics}{ 136 | 137 | \code{geom_xspline} understands the following aesthetics (required aesthetics 138 | are in bold): 139 | \itemize{ 140 | \item \strong{\code{x}} 141 | \item \strong{\code{y}} 142 | \item \code{alpha} 143 | \item \code{color} 144 | \item \code{linetype} 145 | \item \code{size} 146 | } 147 | } 148 | 149 | \section{Computed variables}{ 150 | 151 | \itemize{ 152 | \item{x} 153 | \item{y} 154 | } 155 | } 156 | 157 | \examples{ 158 | set.seed(1492) 159 | dat <- data.frame(x=c(1:10, 1:10, 1:10), 160 | y=c(sample(15:30, 10), 2*sample(15:30, 10), 161 | 3*sample(15:30, 10)), 162 | group=factor(c(rep(1, 10), rep(2, 10), rep(3, 10))) 163 | ) 164 | 165 | ggplot(dat, aes(x, y, group=group, color=group)) + 166 | geom_point() + 167 | geom_line() 168 | 169 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 170 | geom_point() + 171 | geom_line() + 172 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) 173 | 174 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 175 | geom_point(color="black") + 176 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 177 | geom_xspline(size=0.5) 178 | 179 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 180 | geom_point(color="black") + 181 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 182 | geom_xspline(spline_shape=-0.4, size=0.5) 183 | 184 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 185 | geom_point(color="black") + 186 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 187 | geom_xspline(spline_shape=0.4, size=0.5) 188 | 189 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 190 | geom_point(color="black") + 191 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 192 | geom_xspline(spline_shape=1, size=0.5) 193 | 194 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 195 | geom_point(color="black") + 196 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 197 | geom_xspline(spline_shape=0, size=0.5) 198 | 199 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 200 | geom_point(color="black") + 201 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 202 | geom_xspline(spline_shape=-1, size=0.5) 203 | } 204 | \references{ 205 | Blanc, C. and Schlick, C. (1995), "X-splines : A Spline Model 206 | Designed for the End User", in \emph{Proceedings of SIGGRAPH 95}, 207 | pp. 377-386. \url{http://dept-info.labri.fr/~schlick/DOC/sig1.html} 208 | } 209 | \seealso{ 210 | \code{\link[ggplot2]{geom_line}}: Connect observations (x order); 211 | \code{\link[ggplot2]{geom_path}}: Connect observations; 212 | \code{\link[ggplot2]{geom_polygon}}: Filled paths (polygons); 213 | \code{\link[ggplot2]{geom_segment}}: Line segments; 214 | \code{\link[graphics]{xspline}}; 215 | \code{\link[grid]{grid.xspline}} 216 | 217 | Other xspline implementations: 218 | \code{\link{geom_xspline2}()} 219 | } 220 | \concept{xspline implementations} 221 | -------------------------------------------------------------------------------- /man/geom_xspline2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_xspline2.r 3 | \name{geom_xspline2} 4 | \alias{geom_xspline2} 5 | \title{Alternative implemenation for connecting control points/observations 6 | with an X-spline} 7 | \usage{ 8 | geom_xspline2( 9 | mapping = NULL, 10 | data = NULL, 11 | stat = "identity", 12 | position = "identity", 13 | na.rm = FALSE, 14 | show.legend = NA, 15 | inherit.aes = TRUE, 16 | ... 17 | ) 18 | } 19 | \arguments{ 20 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 21 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 22 | at the top level of the plot. You must supply \code{mapping} if there is no plot 23 | mapping.} 24 | 25 | \item{data}{The data to be displayed in this layer. There are three 26 | options: 27 | 28 | If \code{NULL}, the default, the data is inherited from the plot 29 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 30 | 31 | A \code{data.frame}, or other object, will override the plot 32 | data. All objects will be fortified to produce a data frame. See 33 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 34 | 35 | A \code{function} will be called with a single argument, 36 | the plot data. The return value must be a \code{data.frame}, and 37 | will be used as the layer data. A \code{function} can be created 38 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 39 | 40 | \item{position}{Position adjustment, either as a string naming the adjustment 41 | (e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a 42 | position adjustment function. Use the latter if you need to change the 43 | settings of the adjustment.} 44 | 45 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with 46 | a warning. If \code{TRUE}, missing values are silently removed.} 47 | 48 | \item{show.legend}{logical. Should this layer be included in the legends? 49 | \code{NA}, the default, includes if any aesthetics are mapped. 50 | \code{FALSE} never includes, and \code{TRUE} always includes. 51 | It can also be a named logical vector to finely select the aesthetics to 52 | display.} 53 | 54 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 55 | rather than combining with them. This is most useful for helper functions 56 | that define both data and aesthetics and shouldn't inherit behaviour from 57 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 58 | 59 | \item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{layer()}}. These are 60 | often aesthetics, used to set an aesthetic to a fixed value, like 61 | \code{colour = "red"} or \code{size = 3}. They may also be parameters 62 | to the paired geom/stat.} 63 | } 64 | \value{ 65 | creates a spline curve 66 | } 67 | \description{ 68 | Alternative implemenation for connecting control points/observations 69 | with an X-spline 70 | } 71 | \seealso{ 72 | Other xspline implementations: 73 | \code{\link{geom_xspline}()} 74 | } 75 | \author{ 76 | Ben Bolker 77 | } 78 | \concept{xspline implementations} 79 | -------------------------------------------------------------------------------- /man/ggalt-ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/coord_proj.r, R/geom_ash.r, R/geom_bkde.r, 3 | % R/geom_bkde2d.r, R/geom_spikelines.R, R/geom_dumbbell.R, R/geom_encircle.r, 4 | % R/geom_lollipop.r, R/geom_xspline.r, R/geom_xspline2.r, R/geom_ubar.r, 5 | % R/stat-stepribbon.r, R/stateface.r 6 | \docType{data} 7 | \name{CoordProj} 8 | \alias{CoordProj} 9 | \alias{StatAsh} 10 | \alias{GeomBkde} 11 | \alias{StatBkde} 12 | \alias{GeomBkde2d} 13 | \alias{StatBkde2d} 14 | \alias{GeomSpikelines} 15 | \alias{GeomDumbbell} 16 | \alias{GeomEncircle} 17 | \alias{GeomLollipop} 18 | \alias{GeomXspline} 19 | \alias{StatXspline} 20 | \alias{GeomXSpline2} 21 | \alias{GeomUbar} 22 | \alias{StatStepribbon} 23 | \alias{GeomStateface} 24 | \title{Geom Proto} 25 | \description{ 26 | Geom Proto 27 | 28 | Geom Proto 29 | 30 | Geom Proto 31 | 32 | Geom Proto 33 | 34 | Geom Proto 35 | } 36 | \references{ 37 | \url{https://groups.google.com/forum/?fromgroups=#!topic/ggplot2/9cFWHaH1CPs} 38 | } 39 | \keyword{datasets} 40 | \keyword{internal} 41 | -------------------------------------------------------------------------------- /man/ggalt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggalt-package.r 3 | \docType{package} 4 | \name{ggalt} 5 | \alias{ggalt} 6 | \title{Extra Geoms, Stats, Coords, Scales & Fonts for 'ggplot2'} 7 | \description{ 8 | A package containing additional geoms, coords, stats, scales & fonts 9 | for ggplot2 2.0+ 10 | } 11 | \author{ 12 | Bob Rudis (@hrbrmstr) 13 | } 14 | -------------------------------------------------------------------------------- /man/ggplot2-ggproto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/annotation_ticks.r, R/geom_cartogram.r 3 | \docType{data} 4 | \name{GeomTicks} 5 | \alias{GeomTicks} 6 | \alias{GeomCartogram} 7 | \title{Base ggproto classes for ggplot2} 8 | \description{ 9 | If you are creating a new geom, stat, position, or scale in another package, 10 | you'll need to extend from ggplot2::Geom, ggplot2::Stat, ggplot2::Position, or ggplot2::Scale. 11 | } 12 | \seealso{ 13 | \code{\link[ggplot2]{ggplot2-ggproto}} 14 | } 15 | \keyword{datasets} 16 | -------------------------------------------------------------------------------- /man/load_stateface.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stateface.r 3 | \name{load_stateface} 4 | \alias{load_stateface} 5 | \title{Load stateface font} 6 | \usage{ 7 | load_stateface() 8 | } 9 | \description{ 10 | Makes the ProPublica StateFace font available to PDF, PostScript, 11 | et. al. devices. 12 | } 13 | \seealso{ 14 | Other StateFace operations: 15 | \code{\link{geom_stateface}()}, 16 | \code{\link{show_stateface}()} 17 | } 18 | \concept{StateFace operations} 19 | -------------------------------------------------------------------------------- /man/macros/aesthetics.Rd: -------------------------------------------------------------------------------- 1 | \newcommand{\aesthetics}{\Sexpr[results=rd,stage=build]{ggalt:::alt_aesthetics("#1", "#2")}} 2 | -------------------------------------------------------------------------------- /man/plotly_helpers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom2plotly.r 3 | \name{plotly_helpers} 4 | \alias{plotly_helpers} 5 | \alias{to_basic.GeomXspline} 6 | \alias{to_basic.GeomBkde2d} 7 | \alias{to_basic.GeomStateface} 8 | \title{Plotly helpers} 9 | \usage{ 10 | to_basic.GeomXspline(data, prestats_data, layout, params, p, ...) 11 | 12 | to_basic.GeomBkde2d(data, prestats_data, layout, params, p, ...) 13 | 14 | to_basic.GeomStateface(data, prestats_data, layout, params, p, ...) 15 | } 16 | \arguments{ 17 | \item{data, prestats_data, layout, params, p, ...}{plotly interface parameters} 18 | } 19 | \description{ 20 | Helper functions to make it easier to automatically create plotly charts 21 | } 22 | \keyword{internal} 23 | -------------------------------------------------------------------------------- /man/position-dodgev.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/position-dodgev.R 3 | \docType{data} 4 | \name{position_dodgev} 5 | \alias{position_dodgev} 6 | \alias{PositionDodgev} 7 | \title{Vertically dodge position} 8 | \usage{ 9 | position_dodgev(height = NULL) 10 | } 11 | \arguments{ 12 | \item{height}{numeric, height of vertical dodge, Default: NULL} 13 | } 14 | \description{ 15 | Vertically dodge position 16 | } 17 | \note{ 18 | position-dodgev(): unmodified from lionel-/ggstance/R/position-dodgev.R 73f521384ae8ea277db5f7d5a2854004aa18f947 19 | } 20 | \examples{ 21 | 22 | if(interactive()){ 23 | 24 | dat <- data.frame( 25 | trt = c(LETTERS[1:5], "D"), 26 | l = c(20, 40, 10, 30, 50, 40), 27 | r = c(70, 50, 30, 60, 80, 70) 28 | ) 29 | 30 | ggplot(dat, aes(y=trt, x=l, xend=r)) + 31 | geom_dumbbell(size=3, color="#e3e2e1", 32 | colour_x = "#5b8124", colour_xend = "#bad744", 33 | dot_guide=TRUE, dot_guide_size=0.25, 34 | position=position_dodgev(height=0.8)) + 35 | labs(x=NULL, y=NULL, title="ggplot2 geom_dumbbell with dot guide") + 36 | theme_minimal() + 37 | theme(panel.grid.major.x=element_line(size=0.05)) 38 | 39 | } 40 | 41 | } 42 | \author{ 43 | @ggstance authors 44 | } 45 | \keyword{datasets} 46 | -------------------------------------------------------------------------------- /man/show_stateface.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stateface.r 3 | \name{show_stateface} 4 | \alias{show_stateface} 5 | \title{Show location of StateFace font} 6 | \usage{ 7 | show_stateface() 8 | } 9 | \description{ 10 | Displays the path to the StateFace font. For the font to work 11 | in the on-screen plot device for ggplot2, you need to install 12 | the font on your system 13 | } 14 | \seealso{ 15 | Other StateFace operations: 16 | \code{\link{geom_stateface}()}, 17 | \code{\link{load_stateface}()} 18 | } 19 | \concept{StateFace operations} 20 | -------------------------------------------------------------------------------- /man/stat_ash.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geom_ash.r 3 | \name{stat_ash} 4 | \alias{stat_ash} 5 | \title{Compute and display a univariate averaged shifted histogram (polynomial kernel)} 6 | \usage{ 7 | stat_ash( 8 | mapping = NULL, 9 | data = NULL, 10 | geom = "area", 11 | position = "stack", 12 | ab = NULL, 13 | nbin = 50, 14 | m = 5, 15 | kopt = c(2, 2), 16 | na.rm = FALSE, 17 | show.legend = NA, 18 | inherit.aes = TRUE, 19 | ... 20 | ) 21 | } 22 | \arguments{ 23 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 24 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 25 | at the top level of the plot. You must supply \code{mapping} if there is no plot 26 | mapping.} 27 | 28 | \item{data}{The data to be displayed in this layer. There are three 29 | options: 30 | 31 | If \code{NULL}, the default, the data is inherited from the plot 32 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 33 | 34 | A \code{data.frame}, or other object, will override the plot 35 | data. All objects will be fortified to produce a data frame. See 36 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 37 | 38 | A \code{function} will be called with a single argument, 39 | the plot data. The return value must be a \code{data.frame}, and 40 | will be used as the layer data. A \code{function} can be created 41 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 42 | 43 | \item{geom}{Use to override the default Geom} 44 | 45 | \item{position}{Position adjustment, either as a string naming the adjustment 46 | (e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a 47 | position adjustment function. Use the latter if you need to change the 48 | settings of the adjustment.} 49 | 50 | \item{ab}{half-open interval for bins \emph{[a,b)}. If no value is specified, 51 | the range of x is stretched by \code{5\%} at each end and used the 52 | interval.} 53 | 54 | \item{nbin}{number of bins desired. Default \code{50}.} 55 | 56 | \item{m}{integer smoothing parameter; Default \code{5}.} 57 | 58 | \item{kopt}{vector of length 2 specifying the kernel, which is proportional 59 | to \emph{( 1 - abs(i/m)^kopt(1) )i^kopt(2)}; (2,2)=biweight (default); 60 | (0,0)=uniform; (1,0)=triangle; (2,1)=Epanechnikov; (2,3)=triweight.} 61 | 62 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with 63 | a warning. If \code{TRUE}, missing values are silently removed.} 64 | 65 | \item{show.legend}{logical. Should this layer be included in the legends? 66 | \code{NA}, the default, includes if any aesthetics are mapped. 67 | \code{FALSE} never includes, and \code{TRUE} always includes. 68 | It can also be a named logical vector to finely select the aesthetics to 69 | display.} 70 | 71 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 72 | rather than combining with them. This is most useful for helper functions 73 | that define both data and aesthetics and shouldn't inherit behaviour from 74 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 75 | 76 | \item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{layer()}}. These are 77 | often aesthetics, used to set an aesthetic to a fixed value, like 78 | \code{colour = "red"} or \code{size = 3}. They may also be parameters 79 | to the paired geom/stat.} 80 | } 81 | \description{ 82 | See \code{\link[ash]{bin1}} & \code{\link[ash]{ash1}} for more information. 83 | } 84 | \details{ 85 | \if{html}{ 86 | A sample of the output from \code{stat_ash()}: 87 | 88 | \figure{statash01.png}{options: width="100\%" alt="Figure: statash01.png"} 89 | } 90 | 91 | \if{latex}{ 92 | A sample of the output from \code{stat_ash()}: 93 | 94 | \figure{statash01.png}{options: width=10cm} 95 | } 96 | } 97 | \section{Aesthetics}{ 98 | 99 | \code{geom_ash} understands the following aesthetics (required aesthetics 100 | are in bold): 101 | \itemize{ 102 | \item \strong{\code{x}} 103 | \item \code{alpha} 104 | \item \code{color} 105 | \item \code{fill} 106 | \item \code{linetype} 107 | \item \code{size} 108 | } 109 | } 110 | 111 | \section{Computed variables}{ 112 | 113 | \describe{ 114 | \item{\code{density}}{ash density estimate} 115 | } 116 | } 117 | 118 | \examples{ 119 | # compare 120 | library(gridExtra) 121 | set.seed(1492) 122 | dat <- data.frame(x=rnorm(100)) 123 | grid.arrange(ggplot(dat, aes(x)) + stat_ash(), 124 | ggplot(dat, aes(x)) + stat_bkde(), 125 | ggplot(dat, aes(x)) + stat_density(), 126 | nrow=3) 127 | 128 | cols <- RColorBrewer::brewer.pal(3, "Dark2") 129 | ggplot(dat, aes(x)) + 130 | stat_ash(alpha=1/2, fill=cols[3]) + 131 | stat_bkde(alpha=1/2, fill=cols[2]) + 132 | stat_density(alpha=1/2, fill=cols[1]) + 133 | geom_rug() + 134 | labs(x=NULL, y="density/estimate") + 135 | scale_x_continuous(expand=c(0,0)) + 136 | theme_bw() + 137 | theme(panel.grid=element_blank()) + 138 | theme(panel.border=element_blank()) 139 | } 140 | \references{ 141 | David Scott (1992), \emph{"Multivariate Density Estimation,"} 142 | John Wiley, (chapter 5 in particular).\cr 143 | \cr 144 | B. W. Silverman (1986), \emph{"Density Estimation for Statistics 145 | and Data Analysis,"} Chapman & Hall. 146 | } 147 | -------------------------------------------------------------------------------- /man/stat_stepribbon.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stat-stepribbon.r 3 | \name{stat_stepribbon} 4 | \alias{stat_stepribbon} 5 | \title{Step ribbon statistic} 6 | \usage{ 7 | stat_stepribbon( 8 | mapping = NULL, 9 | data = NULL, 10 | geom = "ribbon", 11 | position = "identity", 12 | na.rm = FALSE, 13 | show.legend = NA, 14 | inherit.aes = TRUE, 15 | direction = "hv", 16 | ... 17 | ) 18 | } 19 | \arguments{ 20 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and 21 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping 22 | at the top level of the plot. You must supply \code{mapping} if there is no plot 23 | mapping.} 24 | 25 | \item{data}{The data to be displayed in this layer. There are three 26 | options: 27 | 28 | If \code{NULL}, the default, the data is inherited from the plot 29 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}. 30 | 31 | A \code{data.frame}, or other object, will override the plot 32 | data. All objects will be fortified to produce a data frame. See 33 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created. 34 | 35 | A \code{function} will be called with a single argument, 36 | the plot data. The return value must be a \code{data.frame}, and 37 | will be used as the layer data. A \code{function} can be created 38 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).} 39 | 40 | \item{geom}{which geom to use; defaults to "\code{ribbon}"} 41 | 42 | \item{position}{Position adjustment, either as a string naming the adjustment 43 | (e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a 44 | position adjustment function. Use the latter if you need to change the 45 | settings of the adjustment.} 46 | 47 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with 48 | a warning. If \code{TRUE}, missing values are silently removed.} 49 | 50 | \item{show.legend}{logical. Should this layer be included in the legends? 51 | \code{NA}, the default, includes if any aesthetics are mapped. 52 | \code{FALSE} never includes, and \code{TRUE} always includes. 53 | It can also be a named logical vector to finely select the aesthetics to 54 | display.} 55 | 56 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, 57 | rather than combining with them. This is most useful for helper functions 58 | that define both data and aesthetics and shouldn't inherit behaviour from 59 | the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} 60 | 61 | \item{direction}{\code{hv} for horizontal-veritcal steps, \code{vh} for 62 | vertical-horizontal steps} 63 | 64 | \item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{layer()}}. These are 65 | often aesthetics, used to set an aesthetic to a fixed value, like 66 | \code{colour = "red"} or \code{size = 3}. They may also be parameters 67 | to the paired geom/stat.} 68 | } 69 | \description{ 70 | Provides stairstep values for ribbon plots 71 | } 72 | \examples{ 73 | x <- 1:10 74 | df <- data.frame(x=x, y=x+10, ymin=x+7, ymax=x+12) 75 | 76 | gg <- ggplot(df, aes(x, y)) 77 | gg <- gg + geom_ribbon(aes(ymin=ymin, ymax=ymax), 78 | stat="stepribbon", fill="#b2b2b2") 79 | gg <- gg + geom_step(color="#2b2b2b") 80 | gg 81 | 82 | gg <- ggplot(df, aes(x, y)) 83 | gg <- gg + geom_ribbon(aes(ymin=ymin, ymax=ymax), 84 | stat="stepribbon", fill="#b2b2b2", 85 | direction="hv") 86 | gg <- gg + geom_step(color="#2b2b2b") 87 | gg 88 | } 89 | \references{ 90 | \url{https://groups.google.com/forum/?fromgroups=#!topic/ggplot2/9cFWHaH1CPs} 91 | } 92 | -------------------------------------------------------------------------------- /revdep/checks.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrbrmstr/ggalt/8941f8c9b13ac38ca0cf6500951017c35241de28/revdep/checks.rds -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(ggalt) 3 | 4 | test_check("ggalt") 5 | -------------------------------------------------------------------------------- /tests/testthat/test-ggalt.R: -------------------------------------------------------------------------------- 1 | context("basic functionality") 2 | test_that("we can do something", { 3 | 4 | #expect_that(some_function(), is_a("data.frame")) 5 | 6 | }) 7 | -------------------------------------------------------------------------------- /vignettes/ggalt_examples.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ggalt examples" 3 | author: "Bob Rudis" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{ggalt examples} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | ```{r include=FALSE} 12 | knitr::opts_chunk$set(collapse=TRUE, comment="##", fig.retina=1, fig.height=6, fig.width=8) 13 | ``` 14 | ```{r} 15 | library(ggplot2) 16 | library(gridExtra) 17 | library(ggalt) 18 | library(scales) 19 | 20 | # current verison 21 | packageVersion("ggalt") 22 | 23 | set.seed(1492) 24 | dat <- data.frame(x=c(1:10, 1:10, 1:10), 25 | y=c(sample(15:30, 10), 2*sample(15:30, 10), 3*sample(15:30, 10)), 26 | group=factor(c(rep(1, 10), rep(2, 10), rep(3, 10))) 27 | ) 28 | ``` 29 | 30 | ### Splines! 31 | 32 | ```{r splines} 33 | ggplot(dat, aes(x, y, group=group, color=group)) + 34 | geom_point() + 35 | geom_line() 36 | 37 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 38 | geom_point() + 39 | geom_line() + 40 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) 41 | 42 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 43 | geom_point(color="black") + 44 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 45 | geom_xspline(size=0.5) 46 | 47 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 48 | geom_point(color="black") + 49 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 50 | geom_xspline(spline_shape=-0.4, size=0.5) 51 | 52 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 53 | geom_point(color="black") + 54 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 55 | geom_xspline(spline_shape=0.4, size=0.5) 56 | 57 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 58 | geom_point(color="black") + 59 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 60 | geom_xspline(spline_shape=1, size=0.5) 61 | 62 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 63 | geom_point(color="black") + 64 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 65 | geom_xspline(spline_shape=0, size=0.5) 66 | 67 | ggplot(dat, aes(x, y, group=group, color=factor(group))) + 68 | geom_point(color="black") + 69 | geom_smooth(se=FALSE, linetype="dashed", size=0.5) + 70 | geom_xspline(spline_shape=-1, size=0.5) 71 | ``` 72 | 73 | #### Alternate (better) density plots 74 | 75 | ```{r bkde_ash} 76 | # bkde 77 | 78 | data(geyser, package="MASS") 79 | 80 | ggplot(geyser, aes(x=duration)) + 81 | stat_bkde(alpha=1/2) 82 | 83 | ggplot(geyser, aes(x=duration)) + 84 | geom_bkde(alpha=1/2) 85 | 86 | ggplot(geyser, aes(x=duration)) + 87 | stat_bkde(bandwidth=0.25) 88 | 89 | ggplot(geyser, aes(x=duration)) + 90 | geom_bkde(bandwidth=0.25) 91 | 92 | set.seed(1492) 93 | dat <- data.frame(cond = factor(rep(c("A","B"), each=200)), 94 | rating = c(rnorm(200),rnorm(200, mean=.8))) 95 | 96 | ggplot(dat, aes(x=rating, color=cond)) + geom_bkde(fill="#00000000") 97 | 98 | ggplot(dat, aes(x=rating, fill=cond)) + geom_bkde(alpha=0.3) 99 | 100 | # ash 101 | 102 | set.seed(1492) 103 | dat <- data.frame(x=rnorm(100)) 104 | grid.arrange(ggplot(dat, aes(x)) + stat_ash(), 105 | ggplot(dat, aes(x)) + stat_bkde(), 106 | ggplot(dat, aes(x)) + stat_density(), 107 | nrow=3) 108 | 109 | cols <- RColorBrewer::brewer.pal(3, "Dark2") 110 | ggplot(dat, aes(x)) + 111 | stat_ash(alpha=1/3, fill=cols[3]) + 112 | stat_bkde(alpha=1/3, fill=cols[2]) + 113 | stat_density(alpha=1/3, fill=cols[1]) + 114 | geom_rug() + 115 | labs(x=NULL, y="density/estimate") + 116 | scale_x_continuous(expand=c(0,0)) + 117 | theme_bw() + 118 | theme(panel.grid=element_blank()) + 119 | theme(panel.border=element_blank()) 120 | ``` 121 | 122 | ### Alternate 2D density plots 123 | 124 | ```{r bkde2d} 125 | m <- ggplot(faithful, aes(x = eruptions, y = waiting)) + 126 | geom_point() + 127 | xlim(0.5, 6) + 128 | ylim(40, 110) 129 | 130 | m + geom_bkde2d(bandwidth=c(0.5, 4)) 131 | 132 | m + stat_bkde2d(bandwidth=c(0.5, 4), aes(fill = ..level..), geom = "polygon") 133 | 134 | ``` 135 | 136 | ### ProPublica StateFace 137 | 138 | ```{r stateface} 139 | # Run show_stateface() to see the location of the TTF StateFace font 140 | # You need to install it for it to work 141 | 142 | set.seed(1492) 143 | dat <- data.frame(state=state.abb, 144 | x=sample(100, 50), 145 | y=sample(100, 50), 146 | col=sample(c("#b2182b", "#2166ac"), 50, replace=TRUE), 147 | sz=sample(6:15, 50, replace=TRUE), 148 | stringsAsFactors=FALSE) 149 | gg <- ggplot(dat, aes(x=x, y=y)) 150 | gg <- gg + geom_stateface(aes(label=state, color=col, size=sz)) 151 | gg <- gg + scale_color_identity() 152 | gg <- gg + scale_size_identity() 153 | gg 154 | ``` 155 | 156 | ### Encircling points automagically 157 | 158 | ```{r encircle} 159 | d <- data.frame(x=c(1,1,2),y=c(1,2,2)*100) 160 | 161 | gg <- ggplot(d,aes(x,y)) 162 | gg <- gg + scale_x_continuous(expand=c(0.5,1)) 163 | gg <- gg + scale_y_continuous(expand=c(0.5,1)) 164 | 165 | gg + geom_encircle(s_shape=1, expand=0) + geom_point() 166 | 167 | gg + geom_encircle(s_shape=1, expand=0.1, colour="red") + geom_point() 168 | 169 | gg + geom_encircle(s_shape=0.5, expand=0.1, colour="purple") + geom_point() 170 | 171 | gg + geom_encircle(data=subset(d, x==1), colour="blue", spread=0.02) + 172 | geom_point() 173 | 174 | gg +geom_encircle(data=subset(d, x==2), colour="cyan", spread=0.04) + 175 | geom_point() 176 | 177 | gg <- ggplot(mpg, aes(displ, hwy)) 178 | gg + geom_encircle(data=subset(mpg, hwy>40)) + geom_point() 179 | 180 | ss <- subset(mpg,hwy>31 & displ<2) 181 | 182 | gg + geom_encircle(data=ss, colour="blue", s_shape=0.9, expand=0.07) + 183 | geom_point() + geom_point(data=ss, colour="blue") 184 | ``` 185 | 186 | ### Step ribbons 187 | 188 | ```{r stepribbon} 189 | x <- 1:10 190 | df <- data.frame(x=x, y=x+10, ymin=x+7, ymax=x+12) 191 | 192 | gg <- ggplot(df, aes(x, y)) 193 | gg <- gg + geom_ribbon(aes(ymin=ymin, ymax=ymax), 194 | stat="stepribbon", fill="#b2b2b2") 195 | gg <- gg + geom_step(color="#2b2b2b") 196 | gg 197 | 198 | gg <- ggplot(df, aes(x, y)) 199 | gg <- gg + geom_ribbon(aes(ymin=ymin, ymax=ymax), 200 | stat="stepribbon", fill="#b2b2b2", 201 | direction="vh") 202 | gg <- gg + geom_step(color="#2b2b2b") 203 | gg 204 | ``` 205 | 206 | ### Lollipop charts 207 | 208 | ```{r lollipop} 209 | df <- read.csv(text="category,pct 210 | Other,0.09 211 | South Asian/South Asian Americans,0.12 212 | Interngenerational/Generational,0.21 213 | S Asian/Asian Americans,0.25 214 | Muslim Observance,0.29 215 | Africa/Pan Africa/African Americans,0.34 216 | Gender Equity,0.34 217 | Disability Advocacy,0.49 218 | European/European Americans,0.52 219 | Veteran,0.54 220 | Pacific Islander/Pacific Islander Americans,0.59 221 | Non-Traditional Students,0.61 222 | Religious Equity,0.64 223 | Caribbean/Caribbean Americans,0.67 224 | Latino/Latina,0.69 225 | Middle Eastern Heritages and Traditions,0.73 226 | Trans-racial Adoptee/Parent,0.76 227 | LBGTQ/Ally,0.79 228 | Mixed Race,0.80 229 | Jewish Heritage/Observance,0.85 230 | International Students,0.87", stringsAsFactors=FALSE, sep=",", header=TRUE) 231 | 232 | gg <- ggplot(df, aes(y=reorder(category, pct), x=pct)) 233 | gg <- gg + geom_lollipop(point.colour="steelblue", point.size=2, horizontal=TRUE) 234 | gg <- gg + scale_x_continuous(expand=c(0,0), labels=percent, 235 | breaks=seq(0, 1, by=0.2), limits=c(0, 1)) 236 | gg <- gg + labs(x=NULL, y=NULL, 237 | title="SUNY Cortland Multicultural Alumni survey results", 238 | subtitle="Ranked by race, ethnicity, home land and orientation\namong the top areas of concern", 239 | caption="Data from http://stephanieevergreen.com/lollipop/") 240 | gg <- gg + theme_minimal() 241 | gg <- gg + theme(panel.grid.major.y=element_blank()) 242 | gg <- gg + theme(panel.grid.minor=element_blank()) 243 | gg <- gg + theme(axis.line.y=element_line(color="#2b2b2b", size=0.15)) 244 | gg <- gg + theme(axis.text.y=element_text(margin=margin(r=0, l=0))) 245 | gg <- gg + theme(plot.margin=unit(rep(30, 4), "pt")) 246 | gg <- gg + theme(plot.title=element_text(face="bold")) 247 | gg <- gg + theme(plot.subtitle=element_text(margin=margin(b=10))) 248 | gg <- gg + theme(plot.caption=element_text(size=8, margin=margin(t=10))) 249 | gg 250 | ``` 251 | 252 | ### Dumbbell charts 253 | 254 | ```{r dumbbell2, message=FALSE, fig.width=7, fig.height=2.5} 255 | df <- data.frame(trt=LETTERS[1:5], l=c(20, 40, 10, 30, 50), r=c(70, 50, 30, 60, 80)) 256 | 257 | ggplot(df, aes(y=trt, x=l, xend=r)) + 258 | geom_dumbbell(size=3, color="#e3e2e1", 259 | colour_x = "#5b8124", colour_xend = "#bad744", 260 | dot_guide=TRUE, dot_guide_size=0.25) + 261 | labs(x=NULL, y=NULL, title="ggplot2 geom_dumbbell with dot guide") + 262 | theme_minimal() + 263 | theme(panel.grid.major.x=element_line(size=0.05)) + 264 | theme(panel.grid.major.y=element_blank()) 265 | ``` 266 | 267 | with optional vertical dodging 268 | 269 | ```{r dumbbellv, message=FALSE, fig.width=7, fig.height=2.5} 270 | df2 <- data.frame(trt = c(LETTERS[1:5], "D"), 271 | l = c(20, 40, 10, 30, 50, 40), 272 | r = c(70, 50, 30, 60, 80, 70)) 273 | 274 | ggplot(df2, aes(y=trt, x=l, xend=r)) + 275 | geom_dumbbell(size=3, color="#e3e2e1", 276 | colour_x = "#5b8124", colour_xend = "#bad744", 277 | dot_guide=TRUE, dot_guide_size=0.25, 278 | position=position_dodgev(height=0.8)) + 279 | labs(x=NULL, y=NULL, title="ggplot2 geom_dumbbell with dot guide") + 280 | theme_minimal() + 281 | theme(panel.grid.major.x=element_line(size=0.05)) 282 | ``` 283 | 284 | --------------------------------------------------------------------------------