),
31 | #' or C) a custom dataframe of time interval boundaries (see Details).
32 | #' @param fill The fill color of the boxes. The default is to use the colors
33 | #' included in `dat`. If a custom dataset is provided with `dat` without color
34 | #' and without fill, a greyscale will be used. Custom fill colors can be
35 | #' provided with this option and will be recycled if/as necessary.
36 | #' @param color The outline color of the interval boxes.
37 | #' @param alpha The transparency of the fill colors.
38 | #' @param height The proportional height (or width if `pos` is `left` or
39 | #' `right`) of the entire plot to use for the scale.
40 | #' @param gap The proportional height (or width) of the entire plot to use as a
41 | #' gap between the axis and the scale.
42 | #' @param pos Which side to add the scale to (left, right, top, or bottom).
43 | #' First letter may also be used.
44 | #' @param lab Whether to include labels.
45 | #' @param rot The amount of counter-clockwise rotation to add to the labels (in
46 | #' degrees).
47 | #' @param abbrv If including labels, whether to use abbreviations instead of
48 | #' full interval names.
49 | #' @param skip A vector of interval names indicating which intervals should not
50 | #' be labeled.
51 | #' @param size Label size.
52 | #' @param neg Set this to true if your x-axis is using negative values.
53 | #' @return A ggplot object.
54 | #' @keywords internal
55 | #' @export
56 | gggeo_scale_old <-
57 | function(gg, dat = "periods", fill = NULL, color = "black", alpha = 1,
58 | height = .05, gap = 0, pos = "bottom", lab = TRUE, rot = 0,
59 | abbrv = TRUE, skip = c("Quaternary", "Holocene", "Late Pleistocene"),
60 | size = 5, neg = FALSE) {
61 | lifecycle::deprecate_stop("2.0.0", "gggeo_scale_old()", "coord_geo()")
62 | }
63 |
--------------------------------------------------------------------------------
/.github/workflows/rhub.yaml:
--------------------------------------------------------------------------------
1 | # R-hub's generic GitHub Actions workflow file. It's canonical location is at
2 | # https://github.com/r-hub/actions/blob/v1/workflows/rhub.yaml
3 | # You can update this file to a newer version using the rhub2 package:
4 | #
5 | # rhub::rhub_setup()
6 | #
7 | # It is unlikely that you need to modify this file manually.
8 |
9 | name: R-hub
10 | run-name: "${{ github.event.inputs.id }}: ${{ github.event.inputs.name || format('Manually run by {0}', github.triggering_actor) }}"
11 |
12 | on:
13 | workflow_dispatch:
14 | inputs:
15 | config:
16 | description: 'A comma separated list of R-hub platforms to use.'
17 | type: string
18 | default: 'linux,windows,macos'
19 | name:
20 | description: 'Run name. You can leave this empty now.'
21 | type: string
22 | id:
23 | description: 'Unique ID. You can leave this empty now.'
24 | type: string
25 |
26 | jobs:
27 |
28 | setup:
29 | runs-on: ubuntu-latest
30 | outputs:
31 | containers: ${{ steps.rhub-setup.outputs.containers }}
32 | platforms: ${{ steps.rhub-setup.outputs.platforms }}
33 |
34 | steps:
35 | # NO NEED TO CHECKOUT HERE
36 | - uses: r-hub/actions/setup@v1
37 | with:
38 | config: ${{ github.event.inputs.config }}
39 | id: rhub-setup
40 |
41 | linux-containers:
42 | needs: setup
43 | if: ${{ needs.setup.outputs.containers != '[]' }}
44 | runs-on: ubuntu-latest
45 | name: ${{ matrix.config.label }}
46 | strategy:
47 | fail-fast: false
48 | matrix:
49 | config: ${{ fromJson(needs.setup.outputs.containers) }}
50 | container:
51 | image: ${{ matrix.config.container }}
52 |
53 | steps:
54 | - uses: r-hub/actions/checkout@v1
55 | - uses: r-hub/actions/platform-info@v1
56 | with:
57 | token: ${{ secrets.RHUB_TOKEN }}
58 | job-config: ${{ matrix.config.job-config }}
59 | - uses: r-hub/actions/setup-deps@v1
60 | with:
61 | token: ${{ secrets.RHUB_TOKEN }}
62 | job-config: ${{ matrix.config.job-config }}
63 | - uses: r-hub/actions/run-check@v1
64 | with:
65 | token: ${{ secrets.RHUB_TOKEN }}
66 | job-config: ${{ matrix.config.job-config }}
67 |
68 | other-platforms:
69 | needs: setup
70 | if: ${{ needs.setup.outputs.platforms != '[]' }}
71 | runs-on: ${{ matrix.config.os }}
72 | name: ${{ matrix.config.label }}
73 | strategy:
74 | fail-fast: false
75 | matrix:
76 | config: ${{ fromJson(needs.setup.outputs.platforms) }}
77 |
78 | steps:
79 | - uses: r-hub/actions/checkout@v1
80 | - uses: r-hub/actions/setup-r@v1
81 | with:
82 | job-config: ${{ matrix.config.job-config }}
83 | token: ${{ secrets.RHUB_TOKEN }}
84 | - uses: r-hub/actions/platform-info@v1
85 | with:
86 | token: ${{ secrets.RHUB_TOKEN }}
87 | job-config: ${{ matrix.config.job-config }}
88 | - uses: r-hub/actions/setup-deps@v1
89 | with:
90 | job-config: ${{ matrix.config.job-config }}
91 | token: ${{ secrets.RHUB_TOKEN }}
92 | - uses: r-hub/actions/run-check@v1
93 | with:
94 | job-config: ${{ matrix.config.job-config }}
95 | token: ${{ secrets.RHUB_TOKEN }}
96 |
--------------------------------------------------------------------------------
/R/coord_trans_flip.R:
--------------------------------------------------------------------------------
1 | #' Transformed and flipped Cartesian coordinate system
2 | #'
3 | #' `coord_trans_flip` behaves similarly to [ggplot2::coord_trans()] in that it
4 | #' occurs after statistical transformation and will affect the visual appearance
5 | #' of geoms. The main difference is that it also flips the x and y coordinates
6 | #' like [ggplot2::coord_flip()].
7 | #'
8 | #' @importFrom ggplot2 ggproto
9 | #' @inheritParams ggplot2::coord_trans
10 | #' @export
11 | #' @examples
12 | #' library(ggplot2)
13 | #' ggplot(mtcars, aes(disp, wt)) +
14 | #' geom_point() +
15 | #' coord_trans_flip(x = "log10", y = "log10")
16 | coord_trans_flip <- function(x = "identity", y = "identity",
17 | xlim = NULL, ylim = NULL,
18 | clip = "on", expand = TRUE) {
19 | # resolve transformers
20 | if (is.character(x)) x <- as.trans(x)
21 | if (!is.trans(x)) {
22 | cli::cli_abort("`x` must be a transformer function or a string.")
23 | }
24 | if (is.character(y)) y <- as.trans(y)
25 | if (!is.trans(y)) {
26 | cli::cli_abort("`y` must be a transformer function or a string.")
27 | }
28 |
29 | # check arguments
30 | clip <- arg_match0(clip, c("off", "on"))
31 | check_bool(expand)
32 |
33 | ggproto(NULL, CoordTransFlip,
34 | trans = list(x = x, y = y),
35 | limits = list(x = xlim, y = ylim),
36 | expand = expand,
37 | clip = clip
38 | )
39 | }
40 |
41 | # copied from ggplot2
42 | flip_axis_labels <- function(x) {
43 | old_names <- names(x)
44 |
45 | new_names <- old_names
46 | new_names <- gsub("^x", "z", new_names)
47 | new_names <- gsub("^y", "x", new_names)
48 | new_names <- gsub("^z", "y", new_names)
49 |
50 | setNames(x, new_names)
51 | }
52 |
53 | #' @rdname coord_trans_flip
54 | #' @format NULL
55 | #' @usage NULL
56 | #' @importFrom ggplot2 ggproto CoordTrans CoordFlip ggproto_parent
57 | #' @export
58 | CoordTransFlip <- ggproto("CoordTransFlip", CoordFlip,
59 | transform = function(self, data, panel_params) {
60 | # Need the panel params to be unflipped to correctly transform the data
61 | panel_params <- flip_axis_labels(panel_params)
62 | data <- ggproto_parent(CoordTrans, self)$transform(data, panel_params)
63 | flip_axis_labels(data)
64 | },
65 | backtransform_range = function(self, panel_params) {
66 | un_flipped_range <-
67 | ggproto_parent(CoordTrans, self)$backtransform_range(panel_params)
68 | list(x = un_flipped_range$y, y = un_flipped_range$x)
69 | },
70 | range = function(self, panel_params) {
71 | # summarise_layout() expects the original x and y ranges here,
72 | # not the ones we would get after flipping the axes
73 | un_flipped_range <- ggproto_parent(CoordTrans, self)$range(panel_params)
74 | list(x = un_flipped_range$y, y = un_flipped_range$x)
75 | },
76 | setup_panel_params = function(self, scale_x, scale_y, params = list()) {
77 | parent <- ggproto_parent(CoordTrans, self)
78 | panel_params <- parent$setup_panel_params(scale_x, scale_y, params)
79 | flip_axis_labels(panel_params)
80 | },
81 | labels = function(labels, panel_params) {
82 | CoordTrans$labels(flip_axis_labels(labels), panel_params)
83 | },
84 | setup_layout = function(layout, params) {
85 | CoordFlip$setup_layout(layout, params)
86 | },
87 | modify_scales = function(scales_x, scales_y) {
88 | CoordFlip$modify_scales(scales_x, scales_y)
89 | }
90 | )
91 |
--------------------------------------------------------------------------------
/man/geo_pattern.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/patterns.R
3 | \name{geo_pattern}
4 | \alias{geo_pattern}
5 | \alias{geo_grob}
6 | \title{Get a FGDC geologic plotting pattern}
7 | \usage{
8 | geo_pattern(
9 | code,
10 | scale = 2,
11 | col = NULL,
12 | fill = NULL,
13 | alpha = NULL,
14 | bg = "white"
15 | )
16 |
17 | geo_grob(code, col = NULL, fill = NULL, alpha = NULL, bg = "white")
18 | }
19 | \arguments{
20 | \item{code}{The number corresponding to the pattern to return. Strings and
21 | numbers are permitted.}
22 |
23 | \item{scale}{The visual scale of the pattern (higher values mean the pattern
24 | is more zoomed in).}
25 |
26 | \item{col}{The color to use for the lines of the pattern.}
27 |
28 | \item{fill}{The color used to fill various closed shapes (e.g., circles) in
29 | the pattern.}
30 |
31 | \item{alpha}{The transparency to use for the fill of the pattern.}
32 |
33 | \item{bg}{The background color to use for the pattern.}
34 | }
35 | \value{
36 | \code{geo_grob()} returns a \link[grid:gTree]{grob} object with a single
37 | instance of the desired pattern. \code{geo_pattern()} returns a
38 | \link[grid:patterns]{GridPattern} object with a repeated instance of the
39 | desired pattern.
40 | }
41 | \description{
42 | Retrieve a single geologic pattern as defined in the \href{https://ngmdb.usgs.gov/fgdc_gds/geolsymstd.php}{FGDC Digital Cartographic Standard for Geologic Map Symbolization} by the \href{https://www.usgs.gov/}{U.S. Geological Survey} and the \href{https://ngmdb.usgs.gov/fgdc_gds/index.php}{Geologic Data Subcommittee (GDS)} of the \href{https://www.fgdc.gov/}{Federal Geographic Data Committee (FGDC)}.
43 | }
44 | \details{
45 | For specific codes, see the "pattern numbers" in the \href{https://ngmdb.usgs.gov/fgdc_gds/geolsymstd/fgdc-geolsym-patternchart.pdf}{full pattern chart}
46 | for valid \code{code} values. Daven Quinn has also assembled more accessible
47 | documentation of the \href{https://davenquinn.com/projects/geologic-patterns/#pattern-reference}{map patterns/codes}
48 | and \href{https://davenquinn.com/projects/geologic-patterns/#series-600}{lithology patterns/codes}.
49 | The set of patterns with names is also included in the built-in dataset
50 | \link{fgdc_names} (and a label dictionary is available using \code{\link[=fgdc_dict]{fgdc_dict()}}.
51 | \code{\link[rmacrostrat:def_lithologies]{rmacrostrat::def_lithologies()}} can also be used to look up pattern codes
52 | for various lithologies (see the "fill" column). Note that codes associated
53 | with color variants (e.g., "101-M") are supported but will result in the
54 | default color variant instead (usually black and white, e.g., "101-K").
55 |
56 | These patterns were originally processed and optimized by Daven Quinn and
57 | are hosted on \href{https://github.com/davenquinn/geologic-patterns/}{GitHub}.
58 | }
59 | \examples{
60 | library(grid)
61 | # Get a generic igneous pattern
62 | pattern1 <- geo_pattern(code = "313-K")
63 | # Get the pattern for a sandstone
64 | pattern2 <- geo_pattern(code = "607")
65 |
66 | # plot the two patterns
67 | grid.newpage()
68 | grid.draw(rectGrob(gp = gpar(fill = pattern1)))
69 | grid.newpage()
70 | grid.draw(rectGrob(gp = gpar(fill = pattern2)))
71 | }
72 | \seealso{
73 | FGDC patterns:
74 | \code{\link{fgdc_dict}()},
75 | \code{\link{fgdc_names}},
76 | \code{\link{grid.pattern_geo}()},
77 | \code{\link{scale_fill_geopattern}()}
78 | }
79 | \concept{patterns}
80 |
--------------------------------------------------------------------------------
/tests/testthat/setup-data.R:
--------------------------------------------------------------------------------
1 | suppressPackageStartupMessages(library(ggplot2, quietly = TRUE))
2 |
3 | if (suppressPackageStartupMessages(require(divDyn, quietly = TRUE))) {
4 | data(corals)
5 | corals_stages_clean <- subset(corals, stage != "")
6 | coral_div <- aggregate(cbind(n = genus) ~ stage,
7 | data = corals_stages_clean,
8 | FUN = function(x) length(x)
9 | )
10 | coral_div$stage_age <- (stages$max_age[match(coral_div$stage, stages$name)] +
11 | stages$min_age[match(coral_div$stage, stages$name)]) / 2
12 |
13 | coral_div_diet <- aggregate(cbind(n = genus) ~ stage + diet,
14 | data = corals_stages_clean,
15 | FUN = function(x) length(x)
16 | )
17 | coral_div_diet$stage_age <-
18 | (stages$max_age[match(coral_div_diet$stage, stages$name)] +
19 | stages$min_age[match(coral_div_diet$stage, stages$name)]) / 2
20 |
21 | corals_periods_clean <- subset(corals, period != "")
22 | coral_div_dis <- aggregate(cbind(n = genus) ~ period + diet,
23 | data = corals_periods_clean,
24 | FUN = function(x) length(x)
25 | )
26 | coral_div_dis$period_age <-
27 | (periods$max_age[match(coral_div_dis$period, periods$name)] +
28 | periods$min_age[match(coral_div_dis$period, periods$name)]) / 2
29 | coral_div_dis <-
30 | coral_div_dis[rev(order(coral_div_dis$period_age)), , drop = FALSE]
31 | coral_div_dis$period <- factor(coral_div_dis$period,
32 | levels = unique(coral_div_dis$period))
33 | }
34 |
35 | if (suppressPackageStartupMessages(require(ape, quietly = TRUE))) {
36 | set.seed(1)
37 | tree <- rtree(100)
38 | }
39 |
40 | if (suppressPackageStartupMessages(require(paleotree, quietly = TRUE))) {
41 | data(RaiaCopesRule)
42 | }
43 |
44 | if (suppressPackageStartupMessages(require(phytools, quietly = TRUE))) {
45 | data(mammal.tree)
46 | }
47 |
48 | if (suppressPackageStartupMessages(require(dispRity, quietly = TRUE))) {
49 | data(demo_data)
50 | }
51 |
52 | if (suppressPackageStartupMessages(require(palaeoverse, quietly = TRUE))) {
53 | data(tetrapods)
54 | }
55 |
56 | suppressPackageStartupMessages(require(gsloid, quietly = TRUE))
57 | suppressPackageStartupMessages(require(ggtree, quietly = TRUE))
58 | suppressPackageStartupMessages(require(dispRity, quietly = TRUE))
59 | suppressPackageStartupMessages(require(grid, quietly = TRUE))
60 | suppressPackageStartupMessages(require(ggpattern, quietly = TRUE))
61 |
62 | # copied from vdiffr
63 | str_standardise <- function(s, sep = "-") {
64 | s <- gsub("[^a-z0-9]", sep, tolower(s))
65 | s <- gsub(paste0(sep, sep, "+"), sep, s)
66 | s <- gsub(paste0("^", sep, "|", sep, "$"), "", s)
67 | s
68 | }
69 |
70 | # copied from https://github.com/r-lib/vdiffr/issues/132#issuecomment-1477006436
71 | write_svg_bleeding_edge <- function(plot, file, title = "") {
72 | svglite::svglite(file)
73 | on.exit(grDevices::dev.off())
74 | # warning: `print_plot()` is not exported by {vdiffr}
75 | vdiffr:::print_plot(plot, title)
76 | }
77 |
78 | expect_doppelganger_deeptime <- function(title, fig, patterns = FALSE) {
79 | title_new <- paste(title, "new")
80 | fig_name <- str_standardise(title_new)
81 | file <- paste0(fig_name, ".svg")
82 | announce_snapshot_file(name = file)
83 |
84 | variant <- switch(packageVersion("ggplot2") > "3.5.2", "ggplot4", NULL)
85 |
86 | if (patterns) {
87 | expect_doppelganger(title_new, fig, writer = write_svg_bleeding_edge,
88 | variant = variant)
89 | } else {
90 | expect_doppelganger(title_new, fig, variant = variant)
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/man/gggeo_scale_old.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/gggeo_scale_old.R
3 | \name{gggeo_scale_old}
4 | \alias{gggeo_scale_old}
5 | \title{Add a geologic scale on top of ggplots}
6 | \usage{
7 | gggeo_scale_old(
8 | gg,
9 | dat = "periods",
10 | fill = NULL,
11 | color = "black",
12 | alpha = 1,
13 | height = 0.05,
14 | gap = 0,
15 | pos = "bottom",
16 | lab = TRUE,
17 | rot = 0,
18 | abbrv = TRUE,
19 | skip = c("Quaternary", "Holocene", "Late Pleistocene"),
20 | size = 5,
21 | neg = FALSE
22 | )
23 | }
24 | \arguments{
25 | \item{gg}{The ggplot object.}
26 |
27 | \item{dat}{Either A) a string indicating a built-in dataframe with interval
28 | data from the ICS ("periods", "epochs", "stages", "eons", or "eras"),
29 | B) a string indicating a timescale from macrostrat (see list here:
30 | \url{https://macrostrat.org/api/defs/timescales?all}),
31 | or C) a custom dataframe of time interval boundaries (see Details).}
32 |
33 | \item{fill}{The fill color of the boxes. The default is to use the colors
34 | included in \code{dat}. If a custom dataset is provided with \code{dat} without color
35 | and without fill, a greyscale will be used. Custom fill colors can be
36 | provided with this option and will be recycled if/as necessary.}
37 |
38 | \item{color}{The outline color of the interval boxes.}
39 |
40 | \item{alpha}{The transparency of the fill colors.}
41 |
42 | \item{height}{The proportional height (or width if \code{pos} is \code{left} or
43 | \code{right}) of the entire plot to use for the scale.}
44 |
45 | \item{gap}{The proportional height (or width) of the entire plot to use as a
46 | gap between the axis and the scale.}
47 |
48 | \item{pos}{Which side to add the scale to (left, right, top, or bottom).
49 | First letter may also be used.}
50 |
51 | \item{lab}{Whether to include labels.}
52 |
53 | \item{rot}{The amount of counter-clockwise rotation to add to the labels (in
54 | degrees).}
55 |
56 | \item{abbrv}{If including labels, whether to use abbreviations instead of
57 | full interval names.}
58 |
59 | \item{skip}{A vector of interval names indicating which intervals should not
60 | be labeled.}
61 |
62 | \item{size}{Label size.}
63 |
64 | \item{neg}{Set this to true if your x-axis is using negative values.}
65 | }
66 | \value{
67 | A ggplot object.
68 | }
69 | \description{
70 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}}
71 |
72 | This function takes a ggplot object and adds a geologic time scale at the
73 | specified side.
74 | }
75 | \details{
76 | If custom data is provided (with \code{dat}), it should consist of at least 3
77 | columns of data. See \code{data(periods)} for an example.
78 | \itemize{
79 | \item The \code{name} column lists the names of each time interval. These will
80 | be used as labels if no abbreviations are provided.
81 | \item The \code{max_age} column lists the oldest boundary of each time interval.
82 | \item The \code{min_age} column lists the youngest boundary of each time
83 | interval.
84 | \item The \code{abbr} column is optional and lists abbreviations that may be
85 | used as labels.
86 | \item The \code{color} column is also optional and lists a hex color code (which
87 | can be obtained with \code{rgb()}) for each time interval.
88 | }
89 | }
90 | \section{Life cycle}{
91 |
92 | This function is fully deprecated in favor of \code{\link[=coord_geo]{coord_geo()}} as of
93 | \strong{deeptime} version 2.0.0. It will be removed in a future version.
94 | }
95 |
96 | \keyword{internal}
97 |
--------------------------------------------------------------------------------
/man/disparity_through_time.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/disparity_through_time.R
3 | \name{disparity_through_time}
4 | \alias{disparity_through_time}
5 | \title{Disparity through time plot using lattice}
6 | \usage{
7 | disparity_through_time(
8 | x,
9 | data,
10 | groups,
11 | pch = 16,
12 | col.point = c("blue"),
13 | scales = list(arrows = FALSE, distance = 1, col = "black", z = list(rot = 90)),
14 | colorkey = FALSE,
15 | screen = list(z = 90, x = 70, y = 180),
16 | aspect = c(1.5, 4),
17 | drape = TRUE,
18 | col.regions = c("white"),
19 | alpha.regions = c(1),
20 | perspective = FALSE,
21 | R.mat = matrix(c(1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), 4, 4),
22 | par.settings = list(axis.line = list(col = "transparent"), layout.heights =
23 | list(top.padding = 0, main.key.padding = 0, key.axis.padding = 0, axis.xlab.padding =
24 | 0, xlab.key.padding = 0, key.sub.padding = 0, bottom.padding = 0), layout.widths =
25 | list(left.padding = 0, key.ylab.padding = 0, ylab.axis.padding = 0, axis.key.padding
26 | = 0, right.padding = 0)),
27 | lattice.options = list(axis.padding = list(factor = 0)),
28 | ...
29 | )
30 | }
31 | \arguments{
32 | \item{x}{a formula (most likely of the form \code{z ~ x * y})}
33 |
34 | \item{data}{a data frame in which variables in the formula are to be
35 | evaluated}
36 |
37 | \item{groups}{a variable in \code{data} to be used as a grouping variable (this is
38 | probably the z variable)}
39 |
40 | \item{pch}{the point type}
41 |
42 | \item{col.point}{color(s) for points on surfaces}
43 |
44 | \item{scales}{a list specifying how the axes are drawn (see
45 | \code{\link[lattice:xyplot]{lattice::xyplot()}} for details)}
46 |
47 | \item{colorkey}{logical, should a legend be drawn (or a list describing the
48 | legend; see \code{\link[lattice:levelplot]{lattice::levelplot()}} for details)}
49 |
50 | \item{screen}{a list of the rotations that should be applied to each axis}
51 |
52 | \item{aspect}{a numeric vector of length 2, giving the relative aspects of
53 | the y-size/x-size and z-size/x-size of the enclosing cube}
54 |
55 | \item{drape}{logical, whether the surfaces should be colored based on
56 | \code{col.regions} and \code{alpha.regions}}
57 |
58 | \item{col.regions}{color(s) for surfaces}
59 |
60 | \item{alpha.regions}{alpha value(s) for surfaces}
61 |
62 | \item{perspective}{logical, whether to plot a perspective view}
63 |
64 | \item{R.mat}{a transformational matrix that is applied to the orientation of
65 | the axes}
66 |
67 | \item{par.settings}{plotting settings (see \code{\link[lattice:trellis.par.get]{lattice::trellis.par.set()}})}
68 |
69 | \item{lattice.options}{lattice settings (see \code{\link[lattice:lattice.options]{lattice::lattice.options()}})}
70 |
71 | \item{...}{Other arguments passed to \code{\link[lattice:cloud]{lattice::wireframe()}}}
72 | }
73 | \value{
74 | An object of class \code{"trellis"}, as output by \code{\link[lattice:cloud]{lattice::wireframe()}}.
75 | }
76 | \description{
77 | Plots points on 2-D surfaces within a a 3-D framework. See
78 | \code{\link[lattice:cloud]{lattice::wireframe()}} and \code{\link[lattice:panel.cloud]{lattice::panel.cloud()}} for customization
79 | options.
80 | }
81 | \examples{
82 | g <- data.frame(
83 | x = runif(100, 0, 60), y = runif(100, 0, 10),
84 | z = factor(rep(periods$name[1:5], each = 20),
85 | levels = periods$name[1:5]
86 | )
87 | )
88 | disparity_through_time(z ~ x * y,
89 | data = g, groups = z, aspect = c(1.5, 2),
90 | xlim = c(0, 60), ylim = c(0, 10), col.regions = "lightgreen",
91 | col.point = c("red", "blue")
92 | )
93 | }
94 |
--------------------------------------------------------------------------------
/vignettes/coord.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Transforming coordinate systems"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{Transforming coordinate systems}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | ```{r, include = FALSE}
11 | knitr::opts_chunk$set(collapse = TRUE, fig.width = 7, fig.height = 5, fig.align = "center")
12 | ```
13 |
14 |
15 | `{ggplot2}` has many built-in [coordinate systems](https://ggplot2-book.org/coord.html) which are used to both 1) produce the two-dimensional position of the plotted data and 2) draw custom axes and panel backgrounds. `coord_geo()` uses this second purpose to draw special axes that include timescales. However, __deeptime__ also includes a number of other coordinate systems whose primary function is to modify the way data is plotted. To demonstrate this, we'll first need to load some packages.
16 |
17 | ```{r message = FALSE}
18 | # Load deeptime
19 | library(deeptime)
20 | # Load ggplot for making plots
21 | # It has some example data too
22 | library(ggplot2)
23 | ```
24 |
25 | ## coord_trans meets coord_flip
26 | One limitation of the traditional `coord_trans()` function in `{ggplot2}` is that you can not flip the axes while also transforming the axes. Historically, you would need to either 1) use `scale_x_continuous()` or `scale_y_continuous()` to transform one or both of your axes (which could result in the untransparent loss of data) in combination with `coord_flip()` or 2) transform your data before supplying it to `ggplot()`. `coord_trans_flip()` accomplishes this without the need for `scales` or transforming your data. It works just like `coord_trans()`, with the added functionality of the axis flip from `coord_flip()`.
27 | ```{r}
28 | ggplot(mtcars, aes(disp, wt)) +
29 | geom_point() +
30 | coord_trans_flip(x = "sqrt", y = "log10") +
31 | theme_classic()
32 | ```
33 |
34 |
35 | Note: back in 2020, `{ggplot2}` [updated](https://tidyverse.org/blog/2020/03/ggplot2-3-3-0/#bi-directional-geoms-and-stats) all the directional stats and geoms (e.g., boxplots and histograms) to work in both directions based on the aesthetic mapping. This somewhat makes this function redundant, but I still find it useful.
36 |
37 | ## 2D linear transformations
38 | Another limitation of the traditional `coord_trans()` is that each axis is transformed independently. `coord_trans_xy()` expands this functionality to allow for a two-dimensional linear transformation as generated by `ggforce::linear_trans()`. This allows for rotations, stretches, shears, translations, and reflections. A dummy example using the `?mtcars` dataset from `{ggplot2}` is included below. While applications of this functionality may seem abstract for real data, see the [plotting traits](traits.html) article for a potential real-world application using species trait data.
39 |
40 |
41 | ```{r}
42 | # make transformer
43 | library(ggforce)
44 | trans <- linear_trans(shear(50, 0))
45 |
46 | # set up data to be plotted
47 | square <- data.frame(
48 | disp = c(
49 | min(mtcars$disp), min(mtcars$disp),
50 | max(mtcars$disp), max(mtcars$disp)
51 | ),
52 | wt = c(
53 | min(mtcars$wt), max(mtcars$wt),
54 | max(mtcars$wt), min(mtcars$wt)
55 | )
56 | )
57 |
58 | # plot data normally
59 | library(ggplot2)
60 | ggplot(mtcars, aes(disp, wt)) +
61 | geom_polygon(data = square, fill = NA, color = "black") +
62 | geom_point(color = "black") +
63 | coord_cartesian() +
64 | theme_classic()
65 | # plot data with transformation
66 | ggplot(mtcars, aes(disp, wt)) +
67 | geom_polygon(data = square, fill = NA, color = "black") +
68 | geom_point(color = "black") +
69 | coord_trans_xy(trans = trans, expand = TRUE) +
70 | theme_classic()
71 | ```
72 |
73 |
74 |
--------------------------------------------------------------------------------
/man/get_scale_data.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/get_scale_data.R
3 | \name{get_scale_data}
4 | \alias{get_scale_data}
5 | \title{Get geological timescale data}
6 | \usage{
7 | get_scale_data(name, true_colors = TRUE)
8 | }
9 | \arguments{
10 | \item{name}{The name of the desired timescale.}
11 |
12 | \item{true_colors}{Return original international time scale colors? (as
13 | opposed to custom Macrostrat plotting colors)}
14 | }
15 | \value{
16 | A \code{data.frame} with the following columns:
17 | \item{name}{the names of the time intervals}
18 | \item{max_age}{the oldest boundaries of the time intervals, in millions of
19 | years}
20 | \item{min_age}{the youngest boundaries of the time intervals, in millions
21 | of years}
22 | \item{abbr}{either traditional abbreviations of the names of the time
23 | intervals (if they exist) or custom abbreviations created with R}
24 | \item{color}{hex color codes associated with the time intervals (if
25 | applicable)}
26 | \item{lab_color}{default label colors for the time interals, either white
27 | or black, whichever has better contrast with the background color, based
28 | on \href{https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en}{recommendations by the International Telecommunication Union}}
29 | }
30 | \description{
31 | This function takes a name of a geological timescale and returns data for the
32 | timescale. Valid names include those of built-in \code{data.frames} (\code{\link[=periods]{periods()}},
33 | \code{\link[=epochs]{epochs()}}, \code{\link[=stages]{stages()}}, \code{\link[=eons]{eons()}}, or \code{\link[=eras]{eras()}}), partial matches of those
34 | names (e.g., "per" or "age"), and partial or exact matches to those hosted
35 | by Macrostrat (see Details below). Note that the colors in the built-in
36 | \code{data.frames} are according to the Commission for the Geological Map of the
37 | World. If you would like to obtain custom Macrostrat colors that are better
38 | for mapping, you should specify the full name of a timescale (e.g.,
39 | "international periods") and set \code{true_colors} to \code{FALSE}. Note that these
40 | colors only vary for the Precambrian.
41 | }
42 | \details{
43 | The following timescales are available from the Macrostrat API as of
44 | 2025-11-19:
45 | \itemize{
46 | \item international ages
47 | \item international epochs
48 | \item international periods
49 | \item calcareous nannoplankton zones
50 | \item New Zealand ages
51 | \item custom COSUNA
52 | \item North American land mammal ages
53 | \item international intervals
54 | \item COSUNA
55 | \item international eras
56 | \item international eons
57 | \item Trilobite Zonation - Laurentia
58 | \item Conodont Zonation
59 | \item North American Regional
60 | \item Ammonite Zonation - Boreal
61 | \item Ammonite Zonation - Western Interior
62 | \item international intervals covering all time
63 | \item Scotese Reconstruction
64 | \item Geomagnetic Polarity Chron
65 | \item Geomagnetic Polarity Subchron
66 | \item Planktic foraminiferal Primary Biozones
67 | \item Planktic foraminiferal Secondary Biozones
68 | \item Planktic foraminiferal datums
69 | \item Martian Periods
70 | \item Martian Epochs
71 | \item Cretaceous Planktic foraminifer zonations
72 | \item Low latitude radiolarian zonation
73 | \item Neogene North Pacific Diatom Biochronology
74 | \item Neogene North Pacific Diatom Biochronology Subzones
75 | \item Siberian Regional
76 | \item Australian Regional
77 | \item Western Europe Regional
78 | \item Russian Platform Regional Stages
79 | \item Russian Precambrian Eras
80 | \item Russian Precambrian Eons
81 | \item Russian Epochs
82 | \item Russian Stages
83 | }
84 |
85 | The most up-to-date list can be found via the Macrostrat API \href{https://macrostrat.org/api/defs/timescales?all}{here}.
86 | }
87 |
--------------------------------------------------------------------------------
/data-raw/names.txt:
--------------------------------------------------------------------------------
1 | 601 Gravel or conglomerate (1st option)
2 | 602 Gravel or conglomerate (2nd option)
3 | 603 Crossbedded gravel or conglomerate
4 | 605 Breccia (1st option)
5 | 606 Breccia (2nd option)
6 | 607 Massive sand or sandstone
7 | 608 Bedded sand or sandstone
8 | 609 Crossbedded sand or sandstone (1st option)
9 | 610 Crossbedded sand or sandstone (2nd option)
10 | 611 Ripple-bedded sand or sandstone
11 | 612 Argillaceous or shaly sandstone
12 | 613 Calcareous sandstone
13 | 614 Dolomitic sandstone
14 | 616 Silt, siltstone, or shaly silt
15 | 617 Calcareous siltstone
16 | 618 Dolomitic siltstone
17 | 619 Sandy or silty shale
18 | 620 Clay or clay shale
19 | 621 Cherty shale
20 | 622 Dolomitic shale
21 | 623 Calcareous shale or marl
22 | 624 Carbonaceous shale
23 | 625 Oil shale
24 | 626 Chalk
25 | 627 Limestone
26 | 628 Clastic limestone
27 | 629 Fossiliferous clastic limestone
28 | 630 Nodular or irregularly bedded limestone
29 | 631 Limestone, irregular (burrow?) fillings of saccharoidal dolomite
30 | 632 Crossbedded limestone
31 | 633 Cherty crossbedded limestone
32 | 634 Cherty and sandy crossbedded clastic limestone
33 | 635 Oolitic limestone
34 | 636 Sandy limestone
35 | 637 Silty limestone
36 | 638 Argillaceous or shaly limestone
37 | 639 Cherty limestone (1st option)
38 | 640 Cherty limestone (2nd option)
39 | 641 Dolomitic limestone, limy dolostone, or limy dolomite
40 | 642 Dolostone or dolomite
41 | 643 Cross-bedded dolostone or dolomite
42 | 644 Oolitic dolostone or dolomite
43 | 645 Sandy dolostone or dolomite
44 | 646 Silty dolostone or dolomite
45 | 647 Argillaceous or shaly dolostone or dolomite
46 | 648 Cherty dolostone or dolomite
47 | 649 Bedded chert (1st option)
48 | 650 Bedded chert (2nd option)
49 | 651 Fossiliferous bedded chert
50 | 652 Fossiliferous rock
51 | 653 Diatomaceous rock
52 | 654 Subgraywacke
53 | 655 Cross-bedded subgraywacke
54 | 656 Ripple-bedded subgraywacke
55 | 657 Peat
56 | 658 Coal
57 | 659 Bony coal or impure coal
58 | 660 Underclay
59 | 661 Flint clay
60 | 662 Bentonite
61 | 663 Glauconite
62 | 664 Limonite
63 | 665 Siderite
64 | 666 Phosphatic-nodular rock
65 | 667 Gypsum
66 | 668 Salt
67 | 669 Interbedded sandstone and siltstone
68 | 670 Interbedded sandstone and shale
69 | 671 Interbedded ripple-bedded sandstone and shale
70 | 672 Interbedded shale and silty limestone (shale dominant)
71 | 673 Interbedded shale and limestone (shale dominant) (1st option)
72 | 674 Interbedded shale and limestone (shale dominant) (2nd option)
73 | 675 Interbedded calcareous shale and limestone (shale dominant)
74 | 676 Interbedded silty limestone and shale
75 | 677 Interbedded limestone and shale (1st option)
76 | 678 Interbedded limestone and shale (2nd option)
77 | 679 Interbedded limestone and shale (limestone dominant)
78 | 680 Interbedded limestone and calcareous shale
79 | 681 Till or diamicton (1st option)
80 | 682 Till or diamicton (2nd option)
81 | 683 Till or diamicton (3rd option)
82 | 684 Loess (1st option)
83 | 685 Loess (2nd option)
84 | 686 Loess (3rd option)
85 | 701 Metamorphism
86 | 702 Quartzite
87 | 703 Slate
88 | 704 Schistose or gneissoid granite
89 | 705 Schist
90 | 706 Contorted schist
91 | 707 Schist and gneiss
92 | 708 Gneiss
93 | 709 Contorted gneiss
94 | 710 Soapstone, talc, or serpentinite
95 | 711 Tuffaceous rock
96 | 712 Crystal tuff
97 | 713 Devitrified tuff
98 | 714 Volcanic breccia and tuff
99 | 715 Volcanic breccia or agglomerate
100 | 716 Zeolitic rock
101 | 717 Basaltic flows
102 | 718 Granite (1st option)
103 | 719 Granite (2nd option)
104 | 720 Banded igneous rock
105 | 721 Igneous rock (1st option)
106 | 722 Igneous rock (2nd option)
107 | 723 Igneous rock (3rd option)
108 | 724 Igneous rock (4th option)
109 | 725 Igneous rock (5th option)
110 | 726 Igneous rock (6th option)
111 | 727 Igneous rock (7th option)
112 | 728 Igneous rock (8th option)
113 | 729 Porphyritic rock (1st option)
114 | 730 Porphyritic rock (2nd option)
115 | 731 Vitrophyre
116 | 732 Quartz
117 | 733 Ore
118 |
--------------------------------------------------------------------------------
/_pkgdown.yml:
--------------------------------------------------------------------------------
1 | url: https://williamgearty.com/deeptime/
2 | template:
3 | bootstrap: 5
4 | bootswatch: flatly
5 | bslib:
6 | navbar-padding-y: 8px
7 | includes:
8 | in_header: |
9 |
10 |
11 |
18 |
19 | figures:
20 | dev: grDevices::png
21 |
22 | development:
23 | mode: auto
24 |
25 | authors:
26 | William Gearty:
27 | href: https://williamgearty.com
28 |
29 | articles:
30 | - title: Articles
31 | navbar: ~
32 | contents:
33 | - coord_geo
34 | - phylogenies
35 | - coord
36 | - traits
37 | - time
38 | - geo
39 | - ggarrange2
40 |
41 | reference:
42 | - title: Adding geological timescales to plots
43 | desc: >
44 | The original purpose of deeptime, `coord_geo()` adds a highly
45 | customizable timescale to any `{ggplot2}` plot. Other functions now supplement
46 | it to aid in the visualization of data over long time scales.
47 | contents:
48 | - coord_geo
49 | - scale_color_geo
50 | - get_scale_data
51 | - guide_geo
52 |
53 | - subtitle: Built-in interval data
54 | desc: >
55 | deeptime includes a selection of built-in interval data from the
56 | most up-to-date Geological Time Scale. These dataframes include name,
57 | max age, min age, abbreviation, and color columns.
58 | contents:
59 | - eons
60 | - eras
61 | - periods
62 | - epochs
63 | - stages
64 |
65 | - subtitle: Deprecated functions
66 | desc: >
67 | The following function(s) represent early iterations of what is
68 | now `coord_geo()`. These function(s) still work but are considered
69 | "deprecated". They will be removed in a future version of deeptime, and
70 | users are strongly encouraged to use `coord_geo()` instead, which has more
71 | features and is still under active development.
72 | contents:
73 | - gggeo_scale
74 |
75 | - title: Adding geological timescales to phylogenies
76 | desc: >
77 | These functions can be used to add timescales specifically to phylogenies
78 | that are plotted with [ggtree](https://www.bioconductor.org/packages/ggtree).
79 | contents:
80 | - coord_geo
81 | - coord_geo_radial
82 | - coord_geo_polar
83 | - scale_color_geo
84 | - get_scale_data
85 | - guide_geo
86 |
87 | - subtitle: Adding text labels to phylogenies
88 | desc: >
89 | When using deeptime coordinate systems, these geoms may work better than geoms
90 | from ggtree.
91 | contents:
92 | - geom_text_phylo
93 | - geom_text_clade
94 |
95 | - title: Transforming coordinate systems
96 | desc: >
97 | These functions can be used to modify the way that your data is plotted
98 | by `{ggplot2}`.
99 | contents:
100 | - coord_trans_flip
101 | - coord_trans_xy
102 |
103 | - title: Plotting trait data
104 | desc: >
105 | These functions can be used for visualizing species trait data.
106 | contents:
107 | - geom_phylomorpho
108 | - disparity_through_time
109 | - panel.disparity
110 | - coord_trans_xy
111 |
112 | - title: Plotting temporal data
113 | desc: >
114 | These functions can be used for visualizing categorical temporal data.
115 | contents:
116 | - geom_points_range
117 | - stat_points_range
118 | - facet_grid_color
119 | - facet_wrap_color
120 | - facet_nested_color
121 | - facet_nested_wrap_color
122 |
123 | - title: Plotting geologic data
124 | desc: >
125 | These functions can be used for visualizing geologic/stratigraphic data.
126 | contents:
127 | - grid.pattern_geo
128 | - geo_pattern
129 | - scale_fill_geopattern
130 | - fgdc_names
131 | - fgdc_dict
132 |
133 | - title: Combining and arranging plots
134 | desc: >
135 | These functions can be used to combine and arrange plots into
136 | publishable-quality figures.
137 | contents:
138 | - ggarrange2
139 | - gtable_frame2
140 |
--------------------------------------------------------------------------------
/man/coord_trans_xy.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/coord_trans_xy.R
3 | \docType{data}
4 | \name{coord_trans_xy}
5 | \alias{coord_trans_xy}
6 | \alias{CoordTransXY}
7 | \title{Transformed XY Cartesian coordinate system}
8 | \usage{
9 | coord_trans_xy(
10 | trans = NULL,
11 | xlim = NULL,
12 | ylim = NULL,
13 | expand = FALSE,
14 | default = FALSE,
15 | clip = "on"
16 | )
17 | }
18 | \arguments{
19 | \item{trans}{Transformer for x and y axes.}
20 |
21 | \item{xlim, ylim}{Limits for the x and y axes.}
22 |
23 | \item{expand}{If \code{TRUE}, the default, adds a small expansion factor to
24 | the limits to ensure that data and axes don't overlap. If \code{FALSE},
25 | limits are taken exactly from the data or \code{xlim}/\code{ylim}.
26 | Giving a logical vector will separately control the expansion for the four
27 | directions (top, left, bottom and right). The \code{expand} argument will be
28 | recycled to length 4 if necessary. Alternatively, can be a named logical
29 | vector to control a single direction, e.g. \code{expand = c(bottom = FALSE)}.}
30 |
31 | \item{default}{Is this the default coordinate system? If \code{FALSE} (the default),
32 | then replacing this coordinate system with another one creates a message alerting
33 | the user that the coordinate system is being replaced. If \code{TRUE}, that warning
34 | is suppressed.}
35 |
36 | \item{clip}{Should drawing be clipped to the extent of the plot panel? A
37 | setting of \code{"on"} (the default) means yes, and a setting of \code{"off"}
38 | means no. In most cases, the default of \code{"on"} should not be changed,
39 | as setting \code{clip = "off"} can cause unexpected results. It allows
40 | drawing of data points anywhere on the plot, including in the plot margins. If
41 | limits are set via \code{xlim} and \code{ylim} and some data points fall outside those
42 | limits, then those data points may show up in places such as the axes, the
43 | legend, the plot title, or the plot margins.}
44 | }
45 | \description{
46 | \code{coord_trans_xy} behaves similarly to \code{\link[ggplot2:coord_transform]{ggplot2::coord_trans()}} in that it
47 | occurs after statistical transformation and will affect the visual appearance
48 | of geoms. The main difference is that it takes a single transformer that is
49 | applied to the x and y axes simultaneously. Any transformers produced by
50 | \code{\link[ggforce:linear_trans]{ggforce::linear_trans()}} that have x and y arguments should work, but any
51 | other transformers produced using \code{\link[scales:new_transform]{scales::trans_new()}} that take x and y
52 | arguments should also work. Axis limits will be adjusted to account for
53 | transformation unless limits are specified with \code{xlim} or \code{ylim}.
54 | }
55 | \details{
56 | This coordinate system only works with geoms where all points are
57 | defined with x and y coordinates (e.g., \code{\link[ggplot2:geom_point]{ggplot2::geom_point()}},
58 | \code{\link[ggplot2:geom_polygon]{ggplot2::geom_polygon()}}). This does not currently work with geoms where
59 | point coordinates are extrapolated (e.g., \code{\link[ggplot2:geom_tile]{ggplot2::geom_rect()}}).
60 | Furthermore, when used with ggplot2 3.5.0 and later, some transformation
61 | edge cases may cause problems with rendering axis lines. This includes not
62 | currently support "capping" axes. I hope to support all of these geoms,
63 | edge cases, and features in the future.
64 | }
65 | \examples{
66 | # make transformer
67 | library(ggforce)
68 | trans <- linear_trans(shear(2, 0), rotate(-pi / 3))
69 |
70 | # set up data to be plotted
71 | square <- data.frame(x = c(0, 0, 4, 4), y = c(0, 1, 1, 0))
72 | points <- data.frame(x = runif(100, 0, 4), y = runif(100, 0, 1))
73 |
74 | # plot data normally
75 | library(ggplot2)
76 | ggplot(data = points, aes(x = x, y = y)) +
77 | geom_polygon(data = square, fill = NA, color = "black") +
78 | geom_point(color = "black") +
79 | coord_cartesian(expand = FALSE) +
80 | theme_classic()
81 |
82 | # plot data with transformation
83 | ggplot(data = points, aes(x = x, y = y)) +
84 | geom_polygon(data = square, fill = NA, color = "black") +
85 | geom_point(color = "black") +
86 | coord_trans_xy(trans = trans, expand = FALSE) +
87 | theme_classic()
88 | }
89 | \keyword{datasets}
90 |
--------------------------------------------------------------------------------
/vignettes/ggarrange2.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Combining and arranging plots"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{Combining and arranging plots}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | ```{r, include = FALSE}
11 | knitr::opts_chunk$set(collapse = TRUE, fig.width = 7, fig.height = 5, fig.align = "center")
12 | ```
13 |
14 | ```{r setup, message = FALSE}
15 | library(deeptime)
16 | # Load ggplot2
17 | library(ggplot2)
18 | # Load ggtree
19 | library(ggtree)
20 | # Load paleotree for some example data
21 | library(paleotree)
22 | data(RaiaCopesRule)
23 | ```
24 |
25 |
26 | ## The history of arranging and combining plots
27 | Combining multiple plots together into figures is a key component of developing publishable data visualizations. Many other packages provide ways to combine and arrange plots. For example, the `gridExtra` package has the [`grid.arrange()` function](https://cran.r-project.org/package=gridExtra/vignettes/arrangeGrob.html) which allows the user to arrange plots in fairly complex layouts. However, the main drawback (for most cases) of this function is that the components of the plots (axes, labels, panels, etc.) are not aligned. The [`ggarrange()` function](https://cran.r-project.org/package=egg/vignettes/Overview.html#arranging-and-aligning-multiple-plots) in the `egg` package uses a 3x3 decomposition of the individual plots to align some of the plot components. The central cells correspond to the core panels, surrounded by axes, legends, etc.
28 |
29 | ## Arranging plots with deeptime
30 | __deeptime__ expands on this functionality with `ggarrange2()` to perform 7x7 decomposition of individual plots, as shown below. This ensures that more components of the individual plots are aligned with one another (e.g., the axis labels, the axis tick labels). The central cell corresponds to the plot panel(s), the rectangle of cells around that corresponds to the axes, the rectangle of cells around that corresponds to the axis titles, and the rectangle of cells around that corresponds to legends.
31 | ```{r}
32 | p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
33 | geom_point() +
34 | theme_classic(base_size = 20)
35 | ggarrange2(p1, debug = TRUE)
36 | ```
37 |
38 | ## Combining plots
39 | With this 7x7 decomposition process, it becomes very simple to combine plots into single figures with properly aligned components.
40 | ```{r}
41 | p1 <- ggplot(ammoniteTraitsRaia) +
42 | geom_point(aes(x = Log_D, y = FD)) +
43 | labs(x = "Body size", y = "Suture complexity") +
44 | theme_classic()
45 |
46 | p2 <- ggplot(ammoniteTraitsRaia) +
47 | geom_point(aes(x = Log_D, y = log_dur)) +
48 | labs(x = "Body size", y = "Stratigraphic duration (myr)") +
49 | theme_classic()
50 | gg1 <- ggarrange2(p1, p2, widths = c(2, 1), draw = FALSE)
51 | ```
52 |
53 | You can chain calls to `ggarrange2()` to accomplish highly complex combinations and arrangements:
54 | ```{r}
55 | p3 <- ggtree(ammoniteTreeRaia, position = position_nudge(x = -ammoniteTreeRaia$root.time)) +
56 | coord_geo(
57 | xlim = c(-415, -66), ylim = c(-2, Ntip(ammoniteTreeRaia)), pos = "bottom",
58 | size = 4, abbrv = FALSE, neg = TRUE
59 | ) +
60 | scale_x_continuous(breaks = seq(-425, -50, 25), labels = -seq(-425, -50, 25)) +
61 | theme_tree2() +
62 | theme(plot.margin = margin(7, 11, 7, 11))
63 | ggarrange2(gg1, p3, nrow = 2, heights = c(1, 2))
64 | ```
65 |
66 | You can also accomplish complex plot layouts by supplying a matrix of integers to the `layout` argument, like with the base R `layout()` function. This can be used to insert empty plots or change the order of plots. Note that repeating a number will duplicate a plot, not expand it across multiple plot spots.
67 | ```{r}
68 | ggarrange2(p1, p2, p3,
69 | layout = matrix(c(1, 2, 0, 3), nrow = 2, byrow = TRUE),
70 | widths = c(1, 3)
71 | )
72 | ```
73 |
74 | ## Other resources for arranging plots
75 | Note that I provide no guarantee that `ggarrange2()` solves every problem when arranging plots. The following other options may also be very useful:
76 |
77 | - The `{cowplot}` package has the `cowplot::plot_grid()` function which accomplishes many of the same features as `ggarrange2()`.
78 | - The `{patchwork}` package has very intuitive tools for combining and arranging plots (e.g., using mathematical symbols).
79 |
80 |
--------------------------------------------------------------------------------
/tests/testthat/test-patterns.R:
--------------------------------------------------------------------------------
1 | test_that("scale_fill_geopattern works", {
2 | # invalid code
3 | vals <- c("101", "313", "603", "999")
4 | gg <- ggplot(mpg, aes(factor(cyl), fill = vals[factor(cyl)])) +
5 | geom_bar() +
6 | scale_fill_geopattern()
7 | expect_error(print(gg))
8 |
9 | skip_if(R.Version()$os != "mingw32") # only test the rest on Windows
10 | vals <- c("101", "313", "603", "733")
11 | gg <- ggplot(mpg, aes(factor(cyl), fill = vals[factor(cyl)])) +
12 | geom_bar() +
13 | scale_fill_geopattern()
14 | expect_doppelganger_deeptime("scale_fill_geopattern", gg, patterns = TRUE)
15 |
16 | # custom labels
17 | gg <- ggplot(mpg, aes(factor(cyl), fill = vals[factor(cyl)])) +
18 | geom_bar() +
19 | scale_fill_geopattern(labels = c("101" = "test"))
20 | expect_doppelganger_deeptime("scale_fill_geopattern_labels", gg, patterns = TRUE)
21 |
22 | # custom limits
23 | gg <- ggplot(mpg, aes(factor(cyl), fill = vals[factor(cyl)])) +
24 | geom_bar() +
25 | scale_fill_geopattern(limits = c("101", "313"))
26 | expect_doppelganger_deeptime("scale_fill_geopattern_limits", gg, patterns = TRUE)
27 |
28 | # test with NA values
29 | vals <- c("101", "313", "603", NA)
30 | gg <- ggplot(mpg, aes(factor(cyl), fill = vals[factor(cyl)])) +
31 | geom_bar() +
32 | scale_fill_geopattern()
33 | expect_doppelganger_deeptime("scale_fill_geopattern_NA", gg, patterns = TRUE)
34 |
35 | # test with custom NA value
36 | gg <- ggplot(mpg, aes(factor(cyl), fill = vals[factor(cyl)])) +
37 | geom_bar() +
38 | scale_fill_geopattern(na.value = geo_pattern("701"))
39 | expect_doppelganger_deeptime("scale_fill_geopattern_NA2", gg, patterns = TRUE)
40 | })
41 |
42 | test_that("geo_grob works", {
43 | grob <- geo_grob("101")
44 | expect_true(grid::is.grob(grob))
45 |
46 | expect_error(geo_grob(999))
47 | expect_error(geo_grob("test"))
48 |
49 | expect_doppelganger_deeptime("geo_grob", {
50 | grid.newpage()
51 | grid.draw(grob)
52 | })
53 | })
54 |
55 | test_that("geo_pattern works", {
56 | patt <- geo_pattern("101")
57 | expect_true(is(patt, "GridPattern"))
58 |
59 | expect_error(geo_pattern(999))
60 | expect_error(geo_pattern("test"))
61 |
62 | pattern1 <- geo_pattern(code = "313-K")
63 | pattern2 <- geo_pattern(code = "607")
64 |
65 | expect_doppelganger_deeptime("geo_pattern1", {
66 | grid.newpage()
67 | grid.draw(rectGrob(gp = gpar(fill = pattern1)))
68 | }, patterns = TRUE)
69 |
70 | expect_doppelganger_deeptime("geo_pattern2", {
71 | grid.newpage()
72 | grid.draw(rectGrob(gp = gpar(fill = pattern2)))
73 | }, patterns = TRUE)
74 | })
75 |
76 | test_that("grid.pattern_geo works", {
77 | x <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6))
78 | y <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6))
79 |
80 | expect_doppelganger_deeptime("grid.pattern_geo", {
81 | grid.newpage()
82 | grid.pattern_geo(params = list(pattern_type = "633", pattern_scale = 4),
83 | boundary_df = data.frame(x, y, id = 1))
84 | }, patterns = TRUE)
85 | })
86 |
87 | test_that("ggpattern works", {
88 | skip_if_not_installed("ggpattern")
89 | df <- data.frame(trt = c("a", "b", "c"), outcome = c(2.3, 1.9, 3.2))
90 | gg <- ggplot(df, aes(trt, outcome)) +
91 | geom_col_pattern(aes(color = trt, pattern_type = trt), pattern = 'geo',
92 | pattern_color = "black", fill = "white",
93 | pattern_fill = "white") +
94 | scale_pattern_type_manual(values = c("101", "313", "999")) +
95 | scale_color_viridis_d() +
96 | theme(legend.key.size = unit(1.5, 'cm'))
97 | expect_error(print(gg))
98 |
99 | skip_if(R.Version()$os != "mingw32") # only test the rest on Windows
100 | gg <- ggplot(df, aes(trt, outcome)) +
101 | geom_col_pattern(aes(color = trt, pattern_type = trt), pattern = 'geo',
102 | pattern_color = "black", fill = "white",
103 | pattern_fill = "white") +
104 | scale_pattern_type_manual(values = c("101", "313", "634")) +
105 | scale_color_viridis_d() +
106 | theme(legend.key.size = unit(1.5, 'cm'))
107 | expect_doppelganger_deeptime("ggpattern", gg, patterns = TRUE)
108 | })
109 |
110 | test_that("fgdc_dict works", {
111 | dict <- fgdc_dict()
112 | expect_true(is.function(dict))
113 | vals <- c("603", "626", "720", "733")
114 | expect_equal(dict(vals), c("Crossbedded gravel or conglomerate", "Chalk",
115 | "Banded igneous rock", "Ore"))
116 | dict <- fgdc_dict(clean = FALSE, wrap = 10)
117 | expect_equal(dict("601"), "Gravel or\nconglomerate\n(1st\noption)")
118 | })
119 |
--------------------------------------------------------------------------------
/man/grid.pattern_geo.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/patterns.R
3 | \name{grid.pattern_geo}
4 | \alias{grid.pattern_geo}
5 | \title{Plot an individual FGDC pattern using grid}
6 | \usage{
7 | grid.pattern_geo(params, boundary_df, aspect_ratio, legend = FALSE)
8 | }
9 | \arguments{
10 | \item{params}{A list of pattern parameters to customize the plotted pattern
11 | (see "Details").}
12 |
13 | \item{boundary_df}{A \code{data.frame} consisting of three columns: "x"
14 | (x-coordinates), "y" (y-coordinates), and "id" (polygon group ID). This
15 | \code{data.frame} defines the boundary (as a closed polygon) of the plotted
16 | pattern.}
17 |
18 | \item{aspect_ratio}{Unused.}
19 |
20 | \item{legend}{Unused.}
21 | }
22 | \description{
23 | This function can be used to plot a single geologic pattern as defined in the
24 | \href{https://ngmdb.usgs.gov/fgdc_gds/geolsymstd.php}{FGDC Digital Cartographic Standard for Geologic Map Symbolization} by the \href{https://www.usgs.gov/}{U.S. Geological Survey} and the \href{https://ngmdb.usgs.gov/fgdc_gds/index.php}{Geologic Data Subcommittee (GDS)} of the \href{https://www.fgdc.gov/}{Federal Geographic Data Committee (FGDC)}. The pattern is plotted on the
25 | existing canvas (i.e., use \code{\link[grid:grid.newpage]{grid::grid.newpage()}} to make a new canvas).
26 | }
27 | \details{
28 | The following \code{params} are accepted:
29 | \describe{
30 | \item{\strong{\code{pattern_alpha}}}{ Alpha transparency for pattern. default: 1}
31 | \item{\strong{\code{pattern_colour}}}{ Color used for strokes and points in
32 | the pattern. default: 'black'}
33 | \item{\strong{\code{pattern_fill}}}{ Color used to fill various closed shapes
34 | (e.g., circles) in the pattern. default: \code{NA}}
35 | \item{\strong{\code{pattern_scale}}}{ Scale. default: 2}
36 | \item{\strong{\code{pattern_type}}}{ Code for the FGDC pattern to use. See
37 | \code{\link[=geo_pattern]{geo_pattern()}} for more details. default: "101" }
38 | \item{\strong{\code{fill}}}{ Color used for the background. default: "white" }
39 | }
40 | }
41 | \section{Warning}{
42 | Pattern fills are not supported on all graphics devices.
43 | Not all devices are under active development, and such devices are unlikely
44 | to add support for new features (such as pattern fills). The new features
45 | have only been implemented on a subset of graphics devices so far:
46 | \code{\link[=cairo_pdf]{cairo_pdf()}}, \code{\link[=cairo_ps]{cairo_ps()}}, \code{\link[=x11]{x11(type="cairo")}},
47 | \code{\link[=png]{png(type="cairo")}},
48 | \code{\link[=jpeg]{jpeg(type="cairo")}},
49 | \code{\link[=tiff]{tiff(type="cairo")}}, \code{\link[=svg]{svg()}}, and \code{\link[=pdf]{pdf()}}. Although
50 | there is no support yet for \code{\link[=quartz]{quartz()}} or \code{\link[=windows]{windows()}}, almost all of the
51 | graphics devices above will work on all major platforms. Further, the
52 | \href{https://ragg.r-lib.org/}{ragg} and
53 | \href{https://svglite.r-lib.org/index.html}{svglite} packages contain graphics
54 | devices that support patterns. When using a graphics device where patterns
55 | are not supported, closed shapes will be rendered with a transparent fill.
56 | Note that, at least on Windows machines, the default device in RStudio and
57 | in the knitr package is \code{\link[=png]{png()}}, which does not support patterns. In
58 | RStudio, you can go to ‘Tools > Global Options > General > Graphics’ and
59 | choose the ‘Cairo PNG’ device from the dropdown menu to display patterns.
60 | Similar issues may arise when using RStudio on other operating systems.
61 | }
62 |
63 | \examples{
64 | # use the function directly to make a hexagon with the pattern
65 | library(grid)
66 | x <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6))
67 | y <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6))
68 | grid.newpage()
69 | grid.pattern_geo(params = list(pattern_type = "633", pattern_scale = 4),
70 | boundary_df = data.frame(x, y, id = 1))
71 | \dontshow{if (require(ggpattern)) withAutoprint(\{ # examplesIf}
72 | # use the function via ggpattern by specifying `pattern = 'geo'`
73 | library(ggplot2)
74 | library(ggpattern)
75 | df <- data.frame(trt = c("a", "b", "c"), outcome = c(2.3, 1.9, 3.2))
76 | ggplot(df, aes(trt, outcome)) +
77 | geom_col_pattern(aes(color = trt, pattern_type = trt), pattern = 'geo',
78 | pattern_color = "black", fill = "white", pattern_fill = "white") +
79 | scale_pattern_type_manual(values = c("101", "313", "634")) +
80 | scale_color_viridis_d() +
81 | theme(legend.key.size = unit(1.5, 'cm'))
82 | \dontshow{\}) # examplesIf}
83 | }
84 | \seealso{
85 | FGDC patterns:
86 | \code{\link{fgdc_dict}()},
87 | \code{\link{fgdc_names}},
88 | \code{\link{geo_pattern}()},
89 | \code{\link{scale_fill_geopattern}()}
90 | }
91 | \concept{patterns}
92 |
--------------------------------------------------------------------------------
/vignettes/traits.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Plotting trait data"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{Plotting trait data}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | ```{r, include = FALSE}
11 | knitr::opts_chunk$set(collapse = TRUE, fig.width = 7, fig.height = 5, fig.align = "center")
12 | ```
13 |
14 |
15 | Many packages exist to visualize trait data for biological species. __deeptime__ similarly has a few novel ways to help you plot your data in useful ways. We'll first load some packages and example data so we can demonstrate some of this functionality.
16 |
17 | ```{r message = FALSE}
18 | # Load deeptime
19 | library(deeptime)
20 | # Load other packages
21 | library(ggplot2)
22 | library(dplyr)
23 | # Load dispRity for example data
24 | library(dispRity)
25 | data(demo_data)
26 | # Load paleotree for example data
27 | library(phytools)
28 | data(mammal.tree)
29 | data(mammal.data)
30 | ```
31 |
32 | ## Plot disparity through time
33 | A common way to visualize trait data, especially for fossil species, is to show the two-dimensional trait distribution for several time intervals. This allows the viewer to easily compare the trait distribution through time. However, producing such a plot has historically been very time intensive, often involving the use of custom code and image editing software (e.g., [Inkscape](https://inkscape.org/)). While a single function to accomplish such a visualization still does not exist for `{ggplot2}` (yet...), the `coord_trans_xy()` function can be used to generate a similar plot with sheared trait space across several time intervals.
34 |
35 | ```{r}
36 | # make transformer
37 | library(ggforce)
38 | trans <- linear_trans(shear(.75, 0))
39 |
40 | # prepare data to be plotted
41 | crinoids <- as.data.frame(demo_data$wright$matrix[[1]][, 1:2])
42 | crinoids$time <- "before extinction"
43 | crinoids$time[demo_data$wright$subsets$after$elements] <- "after extinction"
44 |
45 | # a box to outline the trait space
46 | square <- data.frame(V1 = c(-.6, -.6, .6, .6), V2 = c(-.4, .4, .4, -.4))
47 |
48 | ggplot() +
49 | geom_segment(
50 | data = data.frame(
51 | x = -.6, y = seq(-.4, .4, .2),
52 | xend = .6, yend = seq(-0.4, .4, .2)
53 | ),
54 | aes(x = x, y = y, xend = xend, yend = yend),
55 | linetype = "dashed", color = "grey"
56 | ) +
57 | geom_segment(
58 | data = data.frame(
59 | x = seq(-.6, .6, .2), y = -.4,
60 | xend = seq(-.6, .6, .2), yend = .4
61 | ),
62 | aes(x = x, y = y, xend = xend, yend = yend),
63 | linetype = "dashed", color = "grey"
64 | ) +
65 | geom_polygon(data = square, aes(x = V1, y = V2), fill = NA, color = "black") +
66 | geom_point(data = crinoids, aes(x = V1, y = V2), color = "black") +
67 | coord_trans_xy(trans = trans, expand = FALSE) +
68 | labs(x = "PCO1", y = "PCO2") +
69 | theme_classic() +
70 | facet_wrap(~time, ncol = 1, strip.position = "right") +
71 | theme(panel.spacing = unit(1, "lines"), panel.background = element_blank())
72 | ```
73 |
74 | ### Disparity in base R
75 | The `disparity_through_time()` function accomplishes nearly all of the work for you if you are comfortable plotting within the `{lattice}` framework (base R). Note that it may take some tweaking (especially the `aspect` argument) to get the results to look the way you want.
76 |
77 | ```{r, fig.height = 4}
78 | crinoids$time <- factor(crinoids$time)
79 | disparity_through_time(time ~ V2 * V1,
80 | data = crinoids, groups = time, aspect = c(1.5, .6),
81 | xlim = c(-.6, .6), ylim = c(-.5, .5),
82 | col.regions = "lightyellow", col.point = c("red", "blue"),
83 | par.settings = list(
84 | axis.line = list(col = "transparent"),
85 | layout.heights =
86 | list(
87 | top.padding = -20, main.key.padding = 0,
88 | key.axis.padding = 0, axis.xlab.padding = 0,
89 | xlab.key.padding = 0, key.sub.padding = 0,
90 | bottom.padding = -20
91 | ),
92 | layout.widths =
93 | list(
94 | left.padding = -10, key.ylab.padding = 0,
95 | ylab.axis.padding = 0, axis.key.padding = 0,
96 | right.padding = 0
97 | )
98 | )
99 | )
100 | ```
101 |
102 | ## Phylomorphospaces
103 | Often, trait data will be accompanied with a phylogeny. You may want to visualize both your phylogeny, the traits of your species, and the evolution of the trait along your phylogeny. To accomplish this, you can create a two-dimensional phylomorphospace. The `{phytools}` package has the `phytools::phylomorphospace()` function for accomplishing this in base R. The `geom_phylomorpho()` function in __deeptime__ will help you accomplish this with `ggplot()`. Note that labels can be added using `geom_label()` or `ggrepel::geom_label_repel()`, but they are not demonstrated here because they would obscure the phylogenetic relationships.
104 | ```{r message = FALSE, warning = FALSE}
105 | mammal.data$label <- rownames(mammal.data)
106 |
107 | ggplot(mammal.data, aes(x = bodyMass, y = homeRange, label = label)) +
108 | geom_phylomorpho(mammal.tree) +
109 | theme_classic()
110 | ```
111 |
112 |
113 |
--------------------------------------------------------------------------------
/man/scale_geo.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/scales.R
3 | \name{scale_color_geo}
4 | \alias{scale_color_geo}
5 | \alias{scale_colour_geo}
6 | \alias{scale_fill_geo}
7 | \alias{scale_discrete_geo}
8 | \title{Geological Time Scale color scales}
9 | \usage{
10 | scale_color_geo(dat, ...)
11 |
12 | scale_fill_geo(dat, ...)
13 |
14 | scale_discrete_geo(dat, aesthetics, ...)
15 | }
16 | \arguments{
17 | \item{dat}{Either A) a string indicating a built-in dataframe with interval
18 | data from the ICS ("periods", "epochs", "stages", "eons", or "eras"),
19 | B) a string indicating a timescale from macrostrat (see list here:
20 | \url{https://macrostrat.org/api/defs/timescales?all}),
21 | or C) a custom data.frame of time interval boundaries
22 | (see \code{\link[=coord_geo]{coord_geo()}}).}
23 |
24 | \item{...}{
25 | Arguments passed on to \code{\link[ggplot2:discrete_scale]{ggplot2::discrete_scale}}
26 | \describe{
27 | \item{\code{scale_name}}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} The name of the scale
28 | that should be used for error messages associated with this scale.}
29 | \item{\code{name}}{The name of the scale. Used as the axis or legend title. If
30 | \code{waiver()}, the default, the name of the scale is taken from the first
31 | mapping used for that aesthetic. If \code{NULL}, the legend title will be
32 | omitted.}
33 | \item{\code{minor_breaks}}{One of:
34 | \itemize{
35 | \item \code{NULL} for no minor breaks
36 | \item \code{waiver()} for the default breaks (none for discrete, one minor break
37 | between each major break for continuous)
38 | \item A numeric vector of positions
39 | \item A function that given the limits returns a vector of minor breaks. Also
40 | accepts rlang \link[rlang:as_function]{lambda} function notation. When
41 | the function has two arguments, it will be given the limits and major
42 | break positions.
43 | }}
44 | \item{\code{labels}}{One of the options below. Please note that when \code{labels} is a
45 | vector, it is highly recommended to also set the \code{breaks} argument as a
46 | vector to protect against unintended mismatches.
47 | \itemize{
48 | \item \code{NULL} for no labels
49 | \item \code{waiver()} for the default labels computed by the
50 | transformation object
51 | \item A character vector giving labels (must be same length as \code{breaks})
52 | \item An expression vector (must be the same length as breaks). See ?plotmath for details.
53 | \item A function that takes the breaks as input and returns labels
54 | as output. Also accepts rlang \link[rlang:as_function]{lambda} function
55 | notation.
56 | }}
57 | \item{\code{limits}}{One of:
58 | \itemize{
59 | \item \code{NULL} to use the default scale values
60 | \item A character vector that defines possible values of the scale and their
61 | order
62 | \item A function that accepts the existing (automatic) values and returns
63 | new ones. Also accepts rlang \link[rlang:as_function]{lambda} function
64 | notation.
65 | }}
66 | \item{\code{na.translate}}{Unlike continuous scales, discrete scales can easily show
67 | missing values, and do so by default. If you want to remove missing values
68 | from a discrete scale, specify \code{na.translate = FALSE}.}
69 | \item{\code{na.value}}{If \code{na.translate = TRUE}, what aesthetic value should the
70 | missing values be displayed as? Does not apply to position scales
71 | where \code{NA} is always placed at the far right.}
72 | \item{\code{drop}}{Should unused factor levels be omitted from the scale?
73 | The default, \code{TRUE}, uses the levels that appear in the data;
74 | \code{FALSE} includes the levels in the factor. Please note that to display
75 | every level in a legend, the layer should use \code{show.legend = TRUE}.}
76 | \item{\code{guide}}{A function used to create a guide or its name. See
77 | \code{\link[ggplot2:guides]{guides()}} for more information.}
78 | \item{\code{call}}{The \code{call} used to construct the scale for reporting messages.}
79 | \item{\code{super}}{The super class to use for the constructed scale}
80 | }}
81 |
82 | \item{aesthetics}{Character string or vector of character strings listing the
83 | name(s) of the aesthetic(s) that this scale works with. This can be useful, for
84 | example, to apply colour settings to the \code{colour} and \code{fill} aesthetics at the
85 | same time, via \code{aesthetics = c("colour", "fill")}.}
86 | }
87 | \description{
88 | Color scales using the colors in the Geological Time Scale graphics.
89 | }
90 | \examples{
91 | library(ggplot2)
92 | df <- data.frame(
93 | x = runif(1000, 0, 10), y = runif(1000, 0, 10),
94 | color = sample(periods$name, 1000, TRUE), shape = 21
95 | )
96 | ggplot(df) +
97 | geom_point(aes(x = x, y = y, fill = color), shape = 21) +
98 | scale_fill_geo("periods", name = "Period") +
99 | theme_classic()
100 |
101 | # cut continuous variable into discrete
102 | df <- data.frame(x = runif(1000, 0, 1000), y = runif(1000, 0, 8))
103 | df$color <- cut(df$x, c(periods$min_age, periods$max_age[22]), periods$name)
104 | ggplot(df) +
105 | geom_point(aes(x = x, y = y, color = color)) +
106 | scale_x_reverse() +
107 | scale_color_geo("periods", name = "Period") +
108 | coord_geo(xlim = c(1000, 0), ylim = c(0, 8)) +
109 | theme_classic()
110 | }
111 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | S3method(print,ggarrange2)
4 | export(CoordGeo)
5 | export(CoordGeoPolar)
6 | export(CoordGeoRadial)
7 | export(CoordTransFlip)
8 | export(CoordTransXY)
9 | export(FacetGridColor)
10 | export(FacetNestedColor)
11 | export(FacetNestedWrapColor)
12 | export(FacetWrapColor)
13 | export(GuideGeo)
14 | export(coord_geo)
15 | export(coord_geo_polar)
16 | export(coord_geo_radial)
17 | export(coord_trans_flip)
18 | export(coord_trans_xy)
19 | export(disparity_through_time)
20 | export(facet_grid_color)
21 | export(facet_grid_geo)
22 | export(facet_nested_color)
23 | export(facet_nested_geo)
24 | export(facet_nested_wrap_color)
25 | export(facet_nested_wrap_geo)
26 | export(facet_wrap_color)
27 | export(facet_wrap_geo)
28 | export(fgdc_dict)
29 | export(geo_grob)
30 | export(geo_pattern)
31 | export(geom_phylomorpho)
32 | export(geom_points_range)
33 | export(geom_text_clade)
34 | export(geom_text_phylo)
35 | export(get_scale_data)
36 | export(ggarrange2)
37 | export(gggeo_scale)
38 | export(gggeo_scale_old)
39 | export(grid.pattern_geo)
40 | export(gtable_frame2)
41 | export(guide_geo)
42 | export(panel.disparity)
43 | export(scale_color_geo)
44 | export(scale_colour_geo)
45 | export(scale_discrete_geo)
46 | export(scale_fill_geo)
47 | export(scale_fill_geopattern)
48 | export(stat_points_range)
49 | import(deeptimedata)
50 | import(grImport2)
51 | import(rlang)
52 | import(scales)
53 | importFrom(curl,nslookup)
54 | importFrom(ggfittext,geom_fit_text)
55 | importFrom(ggforce,linear_trans)
56 | importFrom(ggh4x,FacetNested)
57 | importFrom(ggh4x,FacetNestedWrap)
58 | importFrom(ggh4x,strip_nested)
59 | importFrom(ggplot2,CoordCartesian)
60 | importFrom(ggplot2,CoordFlip)
61 | importFrom(ggplot2,CoordPolar)
62 | importFrom(ggplot2,CoordRadial)
63 | importFrom(ggplot2,CoordTrans)
64 | importFrom(ggplot2,FacetGrid)
65 | importFrom(ggplot2,FacetWrap)
66 | importFrom(ggplot2,Geom)
67 | importFrom(ggplot2,GeomLabel)
68 | importFrom(ggplot2,GeomLinerange)
69 | importFrom(ggplot2,GeomPoint)
70 | importFrom(ggplot2,GeomPointrange)
71 | importFrom(ggplot2,GeomText)
72 | importFrom(ggplot2,GuideAxis)
73 | importFrom(ggplot2,ScaleDiscrete)
74 | importFrom(ggplot2,Stat)
75 | importFrom(ggplot2,aes)
76 | importFrom(ggplot2,annotate)
77 | importFrom(ggplot2,calc_element)
78 | importFrom(ggplot2,coord_polar)
79 | importFrom(ggplot2,coord_radial)
80 | importFrom(ggplot2,discrete_scale)
81 | importFrom(ggplot2,draw_key_pointrange)
82 | importFrom(ggplot2,element_blank)
83 | importFrom(ggplot2,element_line)
84 | importFrom(ggplot2,geom_rect)
85 | importFrom(ggplot2,geom_segment)
86 | importFrom(ggplot2,geom_text)
87 | importFrom(ggplot2,geom_vline)
88 | importFrom(ggplot2,ggplot)
89 | importFrom(ggplot2,ggplotGrob)
90 | importFrom(ggplot2,ggproto)
91 | importFrom(ggplot2,ggproto_parent)
92 | importFrom(ggplot2,has_flipped_aes)
93 | importFrom(ggplot2,last_plot)
94 | importFrom(ggplot2,layer)
95 | importFrom(ggplot2,new_guide)
96 | importFrom(ggplot2,position_nudge)
97 | importFrom(ggplot2,remove_missing)
98 | importFrom(ggplot2,scale_color_identity)
99 | importFrom(ggplot2,scale_fill_identity)
100 | importFrom(ggplot2,scale_fill_manual)
101 | importFrom(ggplot2,scale_x_continuous)
102 | importFrom(ggplot2,scale_x_reverse)
103 | importFrom(ggplot2,scale_y_continuous)
104 | importFrom(ggplot2,set_last_plot)
105 | importFrom(ggplot2,standardise_aes_names)
106 | importFrom(ggplot2,theme)
107 | importFrom(ggplot2,theme_void)
108 | importFrom(ggplot2,transform_position)
109 | importFrom(ggplot2,waiver)
110 | importFrom(ggplot2,xlim)
111 | importFrom(ggplot2,zeroGrob)
112 | importFrom(grDevices,col2rgb)
113 | importFrom(grDevices,dev.interactive)
114 | importFrom(grDevices,dev.new)
115 | importFrom(grDevices,n2mfrow)
116 | importFrom(grid,addGrob)
117 | importFrom(grid,editGrob)
118 | importFrom(grid,gList)
119 | importFrom(grid,gPath)
120 | importFrom(grid,gTree)
121 | importFrom(grid,gpar)
122 | importFrom(grid,grid.draw)
123 | importFrom(grid,grid.ls)
124 | importFrom(grid,grid.newpage)
125 | importFrom(grid,grid.polygon)
126 | importFrom(grid,grobHeight)
127 | importFrom(grid,grobName)
128 | importFrom(grid,grobWidth)
129 | importFrom(grid,is.grob)
130 | importFrom(grid,is.unit)
131 | importFrom(grid,nullGrob)
132 | importFrom(grid,pattern)
133 | importFrom(grid,rectGrob)
134 | importFrom(grid,reorderGrob)
135 | importFrom(grid,textGrob)
136 | importFrom(grid,unit)
137 | importFrom(grid,unit.c)
138 | importFrom(grid,viewport)
139 | importFrom(gridExtra,gtable_cbind)
140 | importFrom(gridExtra,gtable_rbind)
141 | importFrom(gtable,gtable)
142 | importFrom(gtable,gtable_add_cols)
143 | importFrom(gtable,gtable_add_grob)
144 | importFrom(gtable,gtable_add_padding)
145 | importFrom(gtable,gtable_add_rows)
146 | importFrom(gtable,gtable_col)
147 | importFrom(gtable,gtable_filter)
148 | importFrom(gtable,gtable_height)
149 | importFrom(gtable,gtable_matrix)
150 | importFrom(gtable,gtable_row)
151 | importFrom(gtable,gtable_width)
152 | importFrom(lattice,panel.cloud)
153 | importFrom(lattice,panel.wireframe)
154 | importFrom(lattice,wireframe)
155 | importFrom(lifecycle,deprecated)
156 | importFrom(methods,is)
157 | importFrom(rlang,"%||%")
158 | importFrom(rlang,":=")
159 | importFrom(rlang,arg_match0)
160 | importFrom(rlang,exec)
161 | importFrom(rlang,is_function)
162 | importFrom(scales,label_dictionary)
163 | importFrom(scales,rescale)
164 | importFrom(scales,squish_infinite)
165 | importFrom(scales,transform_identity)
166 | importFrom(stats,setNames)
167 | importFrom(utils,modifyList)
168 | importFrom(utils,packageVersion)
169 | importFrom(utils,read.csv)
170 |
--------------------------------------------------------------------------------
/man/geom_phylomorpho.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/phylomorpho.R
3 | \name{geom_phylomorpho}
4 | \alias{geom_phylomorpho}
5 | \title{Plot a 2-D phylomorphospace in ggplot2}
6 | \usage{
7 | geom_phylomorpho(
8 | tree,
9 | mapping = NULL,
10 | data = NULL,
11 | position = "identity",
12 | ...,
13 | seg_args = list(),
14 | point_args = list(),
15 | arrow = NULL,
16 | arrow.fill = NULL,
17 | lineend = "butt",
18 | linejoin = "round",
19 | na.rm = FALSE,
20 | show.legend = NA,
21 | inherit.aes = TRUE
22 | )
23 | }
24 | \arguments{
25 | \item{tree}{An object of class "phylo".}
26 |
27 | \item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and
28 | \code{inherit.aes = TRUE} (the default), it is combined with the default mapping
29 | at the top level of the plot. You must supply \code{mapping} if there is no plot
30 | mapping.}
31 |
32 | \item{data}{The data to be displayed in this layer. There are three
33 | options:
34 |
35 | If \code{NULL}, the default, the data is inherited from the plot
36 | data as specified in the call to \code{\link[ggplot2:ggplot]{ggplot()}}.
37 |
38 | A \code{data.frame}, or other object, will override the plot
39 | data. All objects will be fortified to produce a data frame. See
40 | \code{\link[ggplot2:fortify]{fortify()}} for which variables will be created.
41 |
42 | A \code{function} will be called with a single argument,
43 | the plot data. The return value must be a \code{data.frame}, and
44 | will be used as the layer data. A \code{function} can be created
45 | from a \code{formula} (e.g. \code{~ head(.x, 10)}).}
46 |
47 | \item{position}{A position adjustment to use on the data for this layer. This
48 | can be used in various ways, including to prevent overplotting and
49 | improving the display. The \code{position} argument accepts the following:
50 | \itemize{
51 | \item The result of calling a position function, such as \code{position_jitter()}.
52 | This method allows for passing extra arguments to the position.
53 | \item A string naming the position adjustment. To give the position as a
54 | string, strip the function name of the \code{position_} prefix. For example, to
55 | use \code{position_jitter()}, give the position as \code{"jitter"}.
56 | }}
57 |
58 | \item{...}{Other arguments passed on to both \code{\link[ggplot2:geom_segment]{ggplot2::geom_segment()}} and
59 | \code{\link[ggplot2:geom_point]{ggplot2::geom_point()}}.}
60 |
61 | \item{seg_args}{A list of arguments passed only to \code{\link[ggplot2:geom_segment]{ggplot2::geom_segment()}}.}
62 |
63 | \item{point_args}{A list of arguments passed only to \code{\link[ggplot2:geom_point]{ggplot2::geom_point()}}.}
64 |
65 | \item{arrow}{specification for arrow heads, as created by \code{\link[grid:arrow]{grid::arrow()}}.}
66 |
67 | \item{arrow.fill}{fill colour to use for the arrow head (if closed). \code{NULL}
68 | means use \code{colour} aesthetic.}
69 |
70 | \item{lineend}{Line end style (round, butt, square).}
71 |
72 | \item{linejoin}{Line join style (round, mitre, bevel).}
73 |
74 | \item{na.rm}{If \code{FALSE}, the default, missing values are removed with
75 | a warning. If \code{TRUE}, missing values are silently removed.}
76 |
77 | \item{show.legend}{logical. Should this layer be included in the legends?
78 | \code{NA}, the default, includes if any aesthetics are mapped.
79 | \code{FALSE} never includes, and \code{TRUE} always includes.
80 | It can also be a named logical vector to finely select the aesthetics to
81 | display. To include legend keys for all levels, even
82 | when no data exists, use \code{TRUE}. If \code{NA}, all levels are shown in legend,
83 | but unobserved levels are omitted.}
84 |
85 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics,
86 | rather than combining with them. This is most useful for helper functions
87 | that define both data and aesthetics and shouldn't inherit behaviour from
88 | the default plot specification, e.g. \code{\link[ggplot2:annotation_borders]{annotation_borders()}}.}
89 | }
90 | \description{
91 | This behaves similar to \code{\link[phytools:phylomorphospace]{phytools::phylomorphospace()}}, but is for plotting a
92 | 2-D phylomorphospace with \code{\link[ggplot2:ggplot]{ggplot2::ggplot()}}. This function works like any
93 | other \code{ggplot2} geom; it can be combined with other geoms (see the example
94 | below), and the output can be modified using scales, themes, etc.
95 | }
96 | \details{
97 | The ancestral states are estimated using \code{\link[phytools:fastAnc]{phytools::fastAnc()}}. Note that
98 | \code{phytools} is not necessarily installed with \code{deeptime}, but it is required
99 | to use this function. Following the estimation of the ancestral states, the
100 | nodes are connected using \code{\link[ggplot2:geom_segment]{ggplot2::geom_segment()}}, while the tips are
101 | indicated using \code{\link[ggplot2:geom_point]{ggplot2::geom_point()}}.
102 |
103 | The default expectation is that the order of the data is the same order as
104 | the tip labels of the tree (\code{tree$tip.label}). However, if this is not the
105 | case, you can map the optional \code{label} aesthetic to a column in the data that
106 | contains the tip names (see example below).
107 | }
108 | \examples{
109 | library(ggplot2)
110 | \dontshow{if (require(ape)) withAutoprint(\{ # examplesIf}
111 | library(ape)
112 | tr <- rtree(10)
113 | dat <- data.frame(
114 | x = runif(10), y = runif(10), label = tr$tip.label,
115 | row.names = tr$tip.label
116 | )
117 | ggplot(dat, aes(x = x, y = y, label = label)) +
118 | geom_phylomorpho(tr) +
119 | geom_label(size = 5)
120 | \dontshow{\}) # examplesIf}
121 | }
122 |
--------------------------------------------------------------------------------
/R/phylomorpho.R:
--------------------------------------------------------------------------------
1 | #' Plot a 2-D phylomorphospace in ggplot2
2 | #'
3 | #' This behaves similar to [phytools::phylomorphospace()], but is for plotting a
4 | #' 2-D phylomorphospace with [ggplot2::ggplot()]. This function works like any
5 | #' other `ggplot2` geom; it can be combined with other geoms (see the example
6 | #' below), and the output can be modified using scales, themes, etc.
7 | #'
8 | #' The ancestral states are estimated using [phytools::fastAnc()]. Note that
9 | #' `phytools` is not necessarily installed with `deeptime`, but it is required
10 | #' to use this function. Following the estimation of the ancestral states, the
11 | #' nodes are connected using [ggplot2::geom_segment()], while the tips are
12 | #' indicated using [ggplot2::geom_point()].
13 | #'
14 | #' The default expectation is that the order of the data is the same order as
15 | #' the tip labels of the tree (`tree$tip.label`). However, if this is not the
16 | #' case, you can map the optional `label` aesthetic to a column in the data that
17 | #' contains the tip names (see example below).
18 | #'
19 | #' @param tree An object of class "phylo".
20 | #' @param position A position adjustment to use on the data for this layer. This
21 | #' can be used in various ways, including to prevent overplotting and
22 | #' improving the display. The `position` argument accepts the following:
23 | #' * The result of calling a position function, such as `position_jitter()`.
24 | #' This method allows for passing extra arguments to the position.
25 | #' * A string naming the position adjustment. To give the position as a
26 | #' string, strip the function name of the `position_` prefix. For example, to
27 | #' use `position_jitter()`, give the position as `"jitter"`.
28 | #' @param seg_args A list of arguments passed only to [ggplot2::geom_segment()].
29 | #' @param point_args A list of arguments passed only to [ggplot2::geom_point()].
30 | #' @param ... Other arguments passed on to both [ggplot2::geom_segment()] and
31 | #' [ggplot2::geom_point()].
32 | #' @importFrom ggplot2 layer
33 | #' @inheritParams ggplot2::layer
34 | #' @inheritParams ggplot2::geom_segment
35 | #' @export
36 | #' @examples
37 | #' library(ggplot2)
38 | #' @examplesIf require(ape)
39 | #' library(ape)
40 | #' tr <- rtree(10)
41 | #' dat <- data.frame(
42 | #' x = runif(10), y = runif(10), label = tr$tip.label,
43 | #' row.names = tr$tip.label
44 | #' )
45 | #' ggplot(dat, aes(x = x, y = y, label = label)) +
46 | #' geom_phylomorpho(tr) +
47 | #' geom_label(size = 5)
48 | geom_phylomorpho <- function(tree, mapping = NULL, data = NULL,
49 | position = "identity", ...,
50 | seg_args = list(), point_args = list(),
51 | arrow = NULL, arrow.fill = NULL,
52 | lineend = "butt", linejoin = "round",
53 | na.rm = FALSE, show.legend = NA,
54 | inherit.aes = TRUE) {
55 | rlang::check_installed("phytools", reason = "to use `geom_phylomorpho()`")
56 | if (!is(tree, "phylo")) {
57 | cli::cli_abort("`tree` must be a phylo object.")
58 | }
59 | mapping2 <- mapping
60 | mapping2$label <- NULL
61 | list(
62 | layer(
63 | data = data,
64 | mapping = mapping,
65 | stat = StatPhylomorpho,
66 | geom = "segment",
67 | position = position,
68 | show.legend = show.legend,
69 | inherit.aes = inherit.aes,
70 | params = c(list(
71 | tree = tree,
72 | arrow = arrow,
73 | arrow.fill = arrow.fill,
74 | lineend = lineend,
75 | linejoin = linejoin,
76 | na.rm = na.rm,
77 | ...
78 | ), seg_args)
79 | ),
80 | layer(
81 | data = data,
82 | mapping = mapping2,
83 | stat = "identity",
84 | geom = "point",
85 | position = position,
86 | show.legend = show.legend,
87 | inherit.aes = inherit.aes,
88 | params = c(list(
89 | na.rm = na.rm,
90 | ...
91 | ), point_args)
92 | )
93 | )
94 | }
95 |
96 | #' @importFrom ggplot2 ggproto Stat
97 | StatPhylomorpho <- ggproto("StatPhylomorpho", Stat,
98 | required_aes = c("x", "y"),
99 | optional_aes = c("label"),
100 | compute_group = function(data, params) {
101 | data
102 | },
103 | compute_panel = function(self, data, scales, params, tree) {
104 | if (nrow(data) != length(tree$tip.label)) {
105 | cli::cli_abort("`data` must contain the same number of rows as species in
106 | `tree`.")
107 | }
108 | if ("label" %in% colnames(data)) {
109 | rownames(data) <- data$label
110 | data$label <- NULL
111 | } else {
112 | rownames(data) <- tree$tip.label
113 | }
114 | # copied from phytools
115 | A <- apply(data, 2, phytools::fastAnc, tree = tree)
116 | aa <- setNames(
117 | c(data[tree$tip.label, "x"], A[, 1]),
118 | c(seq_along(tree$tip.label), rownames(A))
119 | )
120 | bb <- setNames(
121 | c(data[tree$tip.label, "y"], A[, 2]),
122 | c(seq_along(tree$tip.label), rownames(A))
123 | )
124 | XX <- matrix(aa[as.character(tree$edge)], nrow(tree$edge), 2)
125 | YY <- matrix(bb[as.character(tree$edge)], nrow(tree$edge), 2)
126 | xx <- setNames(c(XX[1, 1], XX[, 2]), c(tree$edge[1, 1], tree$edge[, 2]))
127 | xx <- xx[order(as.numeric(names(xx)))]
128 | yy <- setNames(c(YY[1, 1], YY[, 2]), c(tree$edge[1, 1], tree$edge[, 2]))
129 | yy <- yy[order(as.numeric(names(yy)))]
130 | df <- data.frame(
131 | x = xx[tree$edge[, 1]], xend = xx[tree$edge[, 2]],
132 | y = yy[tree$edge[, 1]], yend = yy[tree$edge[, 2]]
133 | )
134 | return(df)
135 | }
136 | )
137 |
--------------------------------------------------------------------------------
/R/get_scale_data.R:
--------------------------------------------------------------------------------
1 | #' Get geological timescale data
2 | #'
3 | #' This function takes a name of a geological timescale and returns data for the
4 | #' timescale. Valid names include those of built-in `data.frames` ([periods()],
5 | #' [epochs()], [stages()], [eons()], or [eras()]), partial matches of those
6 | #' names (e.g., "per" or "age"), and partial or exact matches to those hosted
7 | #' by Macrostrat (see Details below). Note that the colors in the built-in
8 | #' `data.frames` are according to the Commission for the Geological Map of the
9 | #' World. If you would like to obtain custom Macrostrat colors that are better
10 | #' for mapping, you should specify the full name of a timescale (e.g.,
11 | #' "international periods") and set `true_colors` to `FALSE`. Note that these
12 | #' colors only vary for the Precambrian.
13 | #'
14 | #' @details The following timescales are available from the Macrostrat API as of
15 | #' `r Sys.Date()`:
16 | #' \itemize{
17 | #' `r macrostrat_timescales()`
18 | #' }
19 | #'
20 | #' The most up-to-date list can be found via the Macrostrat API [here](https://macrostrat.org/api/defs/timescales?all).
21 | #'
22 | #' @param name The name of the desired timescale.
23 | #' @param true_colors Return original international time scale colors? (as
24 | #' opposed to custom Macrostrat plotting colors)
25 | #' @return A `data.frame` with the following columns:
26 | #' \item{name}{the names of the time intervals}
27 | #' \item{max_age}{the oldest boundaries of the time intervals, in millions of
28 | #' years}
29 | #' \item{min_age}{the youngest boundaries of the time intervals, in millions
30 | #' of years}
31 | #' \item{abbr}{either traditional abbreviations of the names of the time
32 | #' intervals (if they exist) or custom abbreviations created with R}
33 | #' \item{color}{hex color codes associated with the time intervals (if
34 | #' applicable)}
35 | #' \item{lab_color}{default label colors for the time interals, either white
36 | #' or black, whichever has better contrast with the background color, based
37 | #' on [recommendations by the International Telecommunication Union](https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en)}
38 | #' @importFrom utils read.csv
39 | #' @importFrom curl nslookup
40 | #' @export
41 | get_scale_data <- function(name, true_colors = TRUE) {
42 | check_required(name)
43 | check_bool(true_colors)
44 | possible_names <- c("periods", "epochs", "stages", "eras", "eons")
45 | name_match <- grep(name, possible_names, ignore.case = TRUE)
46 | if (length(name_match) > 0) {
47 | if (length(name_match) > 1) {
48 | cli::cli_abort("`name` matches multiple built-in timescales. Please be
49 | more specific.")
50 | } else {
51 | name <- possible_names[name_match]
52 | if (name == "periods") {
53 | dat <- deeptime::periods
54 | } else if (name == "epochs") {
55 | dat <- deeptime::epochs
56 | } else if (name == "stages") {
57 | dat <- deeptime::stages
58 | } else if (name == "eras") {
59 | dat <- deeptime::eras
60 | } else if (name == "eons") {
61 | dat <- deeptime::eons
62 | }
63 | }
64 | } else {
65 | # try to get the timescale from macrostrat
66 | # check that we are online and macrostrat is online
67 | tryCatch(# nocov start
68 | {
69 | nslookup("macrostrat.org")
70 | },
71 | error = function(e) {
72 | cli::cli_abort("Macrostrat is not available. Either the site is down or
73 | you are not connected to the internet.")
74 | }
75 | )# nocov end
76 | avail_scales <- read.csv(url(paste0("https://macrostrat.org/api/v2/defs/",
77 | "timescales?all&format=csv")),
78 | stringsAsFactors = FALSE)
79 | # check exact matches
80 | name_match <- match(tolower(name), tolower(avail_scales$timescale))
81 | if (is.na(name_match)) {
82 | # check partial matches
83 | name_match <- grep(name, avail_scales$timescale, ignore.case = TRUE)
84 | if (length(name_match) == 0) {
85 | cli::cli_abort("`name` does not match a built-in or Macrostrat
86 | timescale.")
87 | } else if (length(name_match) > 1) {
88 | cli::cli_abort("`name` matches multiple Macrostrat timescales. Please be
89 | more specific.")
90 | }
91 | }
92 | # get full timescale name and retrieve data from Macrostrat
93 | name <- avail_scales$timescale[name_match]
94 | URL <- url(paste0("https://macrostrat.org/api/v2/defs/intervals",
95 | "?format=csv×cale=", gsub(" ", "%20", name),
96 | ifelse(true_colors, "&true_colors=true", "")))
97 | raw_dat <- tryCatch(
98 | {
99 | read.csv(URL, header = TRUE, stringsAsFactors = FALSE)
100 | },
101 | error = function(e) {# nocov start
102 | cli::cli_abort("Macrostrat is not available. Either the site is down
103 | or you are not connected to the internet.")
104 | }# nocov end
105 | )
106 | clean_dat <- raw_dat[, c("name", "b_age", "t_age", "abbrev", "color")]
107 | colnames(clean_dat) <- c("name", "max_age", "min_age", "abbr", "color")
108 | no_abbr <- (is.na(clean_dat$abbr) | clean_dat$abbr == "")
109 | clean_dat$abbr[no_abbr] <-
110 | abbreviate(clean_dat$name, minlength = 1,
111 | use.classes = TRUE, named = FALSE)[no_abbr]
112 | clean_dat$abbr[clean_dat$name == "Stage 10"] <- "S10" # fix abbreviation
113 | dat <- clean_dat
114 | dat$lab_color <- white_or_black(dat$color)
115 | }
116 | dat
117 | }
118 |
119 | # Determine best label colors based on luminance as per
120 | # https://stackoverflow.com/a/1855903/4660582
121 | # values are from https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en
122 | #' @importFrom grDevices col2rgb
123 | white_or_black <- function(colors) {
124 | rgbs <- col2rgb(colors)
125 | luminance <- apply(rgbs, 2, function(x) {
126 | (0.299 * x[1] + 0.587 * x[2] + 0.114 * x[3]) / 255
127 | })
128 | ifelse(luminance > .5, "black", "white")
129 | }
130 |
131 | # generate docs for available Macrostrat timescales
132 | macrostrat_timescales <- function() {# nocov start
133 | scales <- read.csv(url(paste0("https://macrostrat.org/api/v2/defs/timescales",
134 | "?all&format=csv")),
135 | stringsAsFactors = FALSE)
136 | return(paste0("\\item ", scales$timescale, collapse = "\n"))
137 | }# nocov end
138 |
--------------------------------------------------------------------------------
/R/disparity_through_time.R:
--------------------------------------------------------------------------------
1 | calculateAxisComponents <- function(...) {
2 | asNamespace("lattice")$calculateAxisComponents(...)
3 | }
4 |
5 | #' Combined wireframe and cloud panel
6 | #'
7 | #' Plots the provided data on 2-D surfaces within a 3-D framework. See
8 | #' [disparity_through_time()].
9 | #' @param x,y,z,groups,subscripts,... Same as for [lattice::panel.cloud()]
10 | #' @return No return value, plots the results of both [lattice::panel.cloud()]
11 | #' and [lattice::panel.wireframe()].
12 | #' @importFrom lattice panel.wireframe panel.cloud
13 | #' @export
14 | panel.disparity <- function(x, y, z, groups, subscripts, ...) {
15 | args <- list(...)
16 | xlabelinfo <- calculateAxisComponents(args$xlim,
17 | at = args$scales.3d$x.scales$at,
18 | num.limit = NULL,
19 | labels = args$scales.3d$x.scales$labels,
20 | logsc = args$scales.3d$x.scales$log,
21 | abbreviate = args$scales.3d$x.scales$abbreviate,
22 | minlength = args$scales.3d$x.scales$minlength,
23 | format.posixt = args$scales.3d$x.scales$format,
24 | n = args$scales.3d$x.scales$tick.number
25 | )
26 | ylabelinfo <- calculateAxisComponents(args$ylim,
27 | at = args$scales.3d$y.scales$at,
28 | num.limit = NULL,
29 | labels = args$scales.3d$y.scales$labels,
30 | logsc = args$scales.3d$y.scales$log,
31 | abbreviate = args$scales.3d$y.scales$abbreviate,
32 | minlength = args$scales.3d$y.scales$minlength,
33 | format.posixt = args$scales.3d$y.scales$format,
34 | n = args$scales.3d$y.scales$tick.number
35 | )
36 | zlabelinfo <- calculateAxisComponents(args$zlim,
37 | at = args$scales.3d$z.scales$at,
38 | num.limit = NULL,
39 | labels = args$scales.3d$z.scales$labels,
40 | logsc = args$scales.3d$z.scales$log,
41 | abbreviate = args$scales.3d$z.scales$abbreviate,
42 | minlength = args$scales.3d$z.scales$minlength,
43 | format.posixt = args$scales.3d$z.scales$format,
44 | n = args$scales.3d$z.scales$tick.number
45 | )
46 | tmp <- expand.grid(x = sort(union(xlabelinfo$at, xlabelinfo$num.limit)),
47 | y = sort(union(ylabelinfo$at, ylabelinfo$num.limit)),
48 | gr = zlabelinfo$at)
49 | panel.wireframe(x = tmp$x, y = tmp$y, z = tmp$gr, groups = tmp$gr,
50 | subscripts = seq_len(nrow(tmp)), ...)
51 | panel.cloud(x = x, y = y, z = z, groups = groups,
52 | subscripts = subscripts, par.box = list("col" = NA), ...)
53 | }
54 |
55 | #' Disparity through time plot using lattice
56 | #'
57 | #' Plots points on 2-D surfaces within a a 3-D framework. See
58 | #' [lattice::wireframe()] and [lattice::panel.cloud()] for customization
59 | #' options.
60 | #'
61 | #' @param x a formula (most likely of the form `z ~ x * y`)
62 | #' @param data a data frame in which variables in the formula are to be
63 | #' evaluated
64 | #' @param groups a variable in `data` to be used as a grouping variable (this is
65 | #' probably the z variable)
66 | #' @param scales a list specifying how the axes are drawn (see
67 | #' [lattice::xyplot()] for details)
68 | #' @param pch the point type
69 | #' @param col.point color(s) for points on surfaces
70 | #' @param drape logical, whether the surfaces should be colored based on
71 | #' `col.regions` and `alpha.regions`
72 | #' @param col.regions color(s) for surfaces
73 | #' @param alpha.regions alpha value(s) for surfaces
74 | #' @param colorkey logical, should a legend be drawn (or a list describing the
75 | #' legend; see [lattice::levelplot()] for details)
76 | #' @param screen a list of the rotations that should be applied to each axis
77 | #' @param R.mat a transformational matrix that is applied to the orientation of
78 | #' the axes
79 | #' @param aspect a numeric vector of length 2, giving the relative aspects of
80 | #' the y-size/x-size and z-size/x-size of the enclosing cube
81 | #' @param perspective logical, whether to plot a perspective view
82 | #' @param par.settings plotting settings (see [lattice::trellis.par.set()])
83 | #' @param lattice.options lattice settings (see [lattice::lattice.options()])
84 | #' @param ... Other arguments passed to [lattice::wireframe()]
85 | #' @return An object of class `"trellis"`, as output by [lattice::wireframe()].
86 | #' @importFrom lattice wireframe
87 | #' @export
88 | #' @examples
89 | #' g <- data.frame(
90 | #' x = runif(100, 0, 60), y = runif(100, 0, 10),
91 | #' z = factor(rep(periods$name[1:5], each = 20),
92 | #' levels = periods$name[1:5]
93 | #' )
94 | #' )
95 | #' disparity_through_time(z ~ x * y,
96 | #' data = g, groups = z, aspect = c(1.5, 2),
97 | #' xlim = c(0, 60), ylim = c(0, 10), col.regions = "lightgreen",
98 | #' col.point = c("red", "blue")
99 | #' )
100 | disparity_through_time <-
101 | function(x, data, groups, pch = 16, col.point = c("blue"),
102 | scales = list(
103 | arrows = FALSE, distance = 1, col = "black",
104 | z = list(rot = 90)
105 | ),
106 | colorkey = FALSE,
107 | screen = list(z = 90, x = 70, y = 180), aspect = c(1.5, 4),
108 | drape = TRUE, col.regions = c("white"), alpha.regions = c(1),
109 | perspective = FALSE, R.mat = matrix(
110 | c(
111 | 1, 1, 0, 0,
112 | 0, 1, 0, 0,
113 | 0, 0, 1, 0,
114 | 0, 0, 0, 1
115 | ),
116 | 4, 4
117 | ),
118 | par.settings = list(
119 | axis.line = list(col = "transparent"),
120 | layout.heights = list(
121 | top.padding = 0,
122 | main.key.padding = 0,
123 | key.axis.padding = 0,
124 | axis.xlab.padding = 0,
125 | xlab.key.padding = 0,
126 | key.sub.padding = 0,
127 | bottom.padding = 0
128 | ),
129 | layout.widths = list(
130 | left.padding = 0,
131 | key.ylab.padding = 0,
132 | ylab.axis.padding = 0,
133 | axis.key.padding = 0,
134 | right.padding = 0
135 | )
136 | ),
137 | lattice.options = list(axis.padding = list(factor = 0)), ...) {
138 | eval(substitute(lattice::wireframe(
139 | x = x, data = data, groups = groups, pch = pch, col.point = col.point,
140 | scales = scales, colorkey = colorkey, screen = screen,
141 | panel = deeptime::panel.disparity, aspect = aspect, drape = drape,
142 | col.regions = col.regions, alpha.regions = alpha.regions,
143 | perspective = perspective, R.mat = R.mat,
144 | par.settings = par.settings, lattice.options = lattice.options, ...
145 | )), envir = parent.frame())
146 | }
147 |
--------------------------------------------------------------------------------
/R/data.R:
--------------------------------------------------------------------------------
1 | #' Eon data from the International Commission on Stratigraphy (v2024/12)
2 | #'
3 | #' A dataset containing the boundary ages, abbreviations, and colors for the
4 | #' eons of the Geologic Time Scale. Based on The ICS International
5 | #' Chronostratigraphic Chart (v2024/12), by Cohen, Finney, Gibbard, and Fan.
6 | #'
7 | #' @format A data frame with 3 rows and 5 variables:
8 | #' \describe{
9 | #' \item{name}{eon name}
10 | #' \item{max_age}{maximum age, in millions of years}
11 | #' \item{min_age}{minimum age, in millions of years}
12 | #' \item{abbr}{eon name abbreviations}
13 | #' \item{color}{the colors for each eon, according to the Commission for the
14 | #' Geological Map of the World}
15 | #' \item{lab_color}{the label colors for each eon, either white or black,
16 | #' whichever has better contrast with the background color, based on
17 | #' [recommendations by the International Telecommunication Union](https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en)}
18 | #' }
19 | #' @family built-in timescales
20 | #' @source via
21 | "eons"
22 |
23 | #' Era data from the International Commission on Stratigraphy (v2024/12)
24 | #'
25 | #' A dataset containing the boundary ages, abbreviations, and colors for the
26 | #' eras of the Geologic Time Scale. Based on The ICS International
27 | #' Chronostratigraphic Chart (v2024/12), by Cohen, Finney, Gibbard, and Fan.
28 | #'
29 | #' @format A data frame with 10 rows and 5 variables:
30 | #' \describe{
31 | #' \item{name}{era name}
32 | #' \item{max_age}{maximum age, in millions of years}
33 | #' \item{min_age}{minimum age, in millions of years}
34 | #' \item{abbr}{era name abbreviations}
35 | #' \item{color}{the colors for each era, according to the Commission for the
36 | #' Geological Map of the World}
37 | #' \item{lab_color}{the label colors for each era, either white or black,
38 | #' whichever has better contrast with the background color, based on
39 | #' [recommendations by the International Telecommunication Union](https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en)}
40 | #' }
41 | #' @family built-in timescales
42 | #' @source via
43 | "eras"
44 |
45 | #' Period data from the International Commission on Stratigraphy (v2024/12)
46 | #'
47 | #' A dataset containing the boundary ages, abbreviations, and colors for the
48 | #' periods of the Geologic Time Scale. Based on The ICS International
49 | #' Chronostratigraphic Chart (v2024/12), by Cohen, Finney, Gibbard, and Fan.
50 | #'
51 | #' @format A data frame with 22 rows and 5 variables:
52 | #' \describe{
53 | #' \item{name}{period name}
54 | #' \item{max_age}{maximum age, in millions of years}
55 | #' \item{min_age}{minimum age, in millions of years}
56 | #' \item{abbr}{period name abbreviations}
57 | #' \item{color}{the colors for each period, according to the Commission for
58 | #' the Geological Map of the World}
59 | #' \item{lab_color}{the label colors for each period, either white or black,
60 | #' whichever has better contrast with the background color, based on
61 | #' [recommendations by the International Telecommunication Union](https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en)}
62 | #' }
63 | #' @family built-in timescales
64 | #' @source via
65 | "periods"
66 |
67 | #' Epoch data from the International Commission on Stratigraphy (v2024/12)
68 | #'
69 | #' A dataset containing the boundary ages, abbreviations, and colors for the
70 | #' epochs of the Geologic Time Scale. Based on The ICS International
71 | #' Chronostratigraphic Chart (v2024/12), by Cohen, Finney, Gibbard, and Fan.
72 | #'
73 | #' @format A data frame with 34 rows and 5 variables:
74 | #' \describe{
75 | #' \item{name}{epoch name}
76 | #' \item{max_age}{maximum age, in millions of years}
77 | #' \item{min_age}{minimum age, in millions of years}
78 | #' \item{abbr}{epoch name abbreviations}
79 | #' \item{color}{the colors for each epoch, according to the Commission for the
80 | #' Geological Map of the World}
81 | #' \item{lab_color}{the label colors for each epoch, either white or black,
82 | #' whichever has better contrast with the background color, based on
83 | #' [recommendations by the International Telecommunication Union](https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en)}
84 | #' }
85 | #' @family built-in timescales
86 | #' @source via
87 | "epochs"
88 |
89 | #' Stage data from the International Commission on Stratigraphy (v2024/12)
90 | #'
91 | #' A dataset containing the boundary ages, abbreviations, and colors for the
92 | #' stages of the Geologic Time Scale. Based on The ICS International
93 | #' Chronostratigraphic Chart (v2024/12), by Cohen, Finney, Gibbard, and Fan.
94 | #'
95 | #' @format A data frame with 102 rows and 5 variables:
96 | #' \describe{
97 | #' \item{name}{stage name}
98 | #' \item{max_age}{maximum age, in millions of years}
99 | #' \item{min_age}{minimum age, in millions of years}
100 | #' \item{abbr}{stage name abbreviations}
101 | #' \item{color}{the colors for each stage, according to the Commission for the
102 | #' Geological Map of the World}
103 | #' \item{lab_color}{the label colors for each stage, either white or black,
104 | #' whichever has better contrast with the background color, based on
105 | #' [recommendations by the International Telecommunication Union](https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en)}
106 | #' }
107 | #' @family built-in timescales
108 | #' @source via
109 | "stages"
110 |
111 | #' Pattern numbers and names for patterns from the FGDC Digital Cartographic
112 | #' Standard for Geologic Map Symbolization
113 | #'
114 | #' A dataset containing the FGDC pattern numbers and verbatim names from the
115 | #' [FGDC Digital Cartographic Standard for Geologic Map
116 | #' Symbolization](https://ngmdb.usgs.gov/fgdc_gds/geolsymstd.php) by the [U.S.
117 | #' Geological Survey](https://www.usgs.gov/) and the [Geologic Data Subcommittee
118 | #' (GDS)](https://ngmdb.usgs.gov/fgdc_gds/index.php) of the [Federal Geographic
119 | #' Data Committee (FGDC)](https://www.fgdc.gov/). Only patterns with names are
120 | #' included (i.e., patterns 601-733).
121 | #'
122 | #' These pattern numbers and names were originally extracted by Daven Quinn and
123 | #' are hosted on [GitHub](https://github.com/davenquinn/geologic-patterns/).
124 | #'
125 | #' @format A data frame with 117 rows and 2 variables:
126 | #' \describe{
127 | #' \item{code}{the pattern number according to the FGDC standard}
128 | #' \item{name}{the verbatim name for the pattern according to the FGDC standard}
129 | #' }
130 | #' @family patterns
131 | #' @source
132 | #'
133 | #' via
134 | "fgdc_names"
135 |
--------------------------------------------------------------------------------
/man/scale_fill_geopattern.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/patterns.R
3 | \name{scale_fill_geopattern}
4 | \alias{scale_fill_geopattern}
5 | \title{Geologic pattern fill scale}
6 | \usage{
7 | scale_fill_geopattern(na.value = "grey50", ...)
8 | }
9 | \arguments{
10 | \item{na.value}{The aesthetic value to use for missing (NA) values. May be
11 | either a color or a \link[grid:patterns]{GridPattern} object (such as that
12 | returned by \code{\link[=geo_pattern]{geo_pattern()}}).}
13 |
14 | \item{...}{
15 | Arguments passed on to \code{\link[ggplot2:discrete_scale]{ggplot2::discrete_scale}}
16 | \describe{
17 | \item{\code{scale_name}}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} The name of the scale
18 | that should be used for error messages associated with this scale.}
19 | \item{\code{name}}{The name of the scale. Used as the axis or legend title. If
20 | \code{waiver()}, the default, the name of the scale is taken from the first
21 | mapping used for that aesthetic. If \code{NULL}, the legend title will be
22 | omitted.}
23 | \item{\code{breaks}}{One of:
24 | \itemize{
25 | \item \code{NULL} for no breaks
26 | \item \code{waiver()} for the default breaks (the scale limits)
27 | \item A character vector of breaks
28 | \item A function that takes the limits as input and returns breaks
29 | as output. Also accepts rlang \link[rlang:as_function]{lambda} function
30 | notation.
31 | }}
32 | \item{\code{minor_breaks}}{One of:
33 | \itemize{
34 | \item \code{NULL} for no minor breaks
35 | \item \code{waiver()} for the default breaks (none for discrete, one minor break
36 | between each major break for continuous)
37 | \item A numeric vector of positions
38 | \item A function that given the limits returns a vector of minor breaks. Also
39 | accepts rlang \link[rlang:as_function]{lambda} function notation. When
40 | the function has two arguments, it will be given the limits and major
41 | break positions.
42 | }}
43 | \item{\code{labels}}{One of the options below. Please note that when \code{labels} is a
44 | vector, it is highly recommended to also set the \code{breaks} argument as a
45 | vector to protect against unintended mismatches.
46 | \itemize{
47 | \item \code{NULL} for no labels
48 | \item \code{waiver()} for the default labels computed by the
49 | transformation object
50 | \item A character vector giving labels (must be same length as \code{breaks})
51 | \item An expression vector (must be the same length as breaks). See ?plotmath for details.
52 | \item A function that takes the breaks as input and returns labels
53 | as output. Also accepts rlang \link[rlang:as_function]{lambda} function
54 | notation.
55 | }}
56 | \item{\code{limits}}{One of:
57 | \itemize{
58 | \item \code{NULL} to use the default scale values
59 | \item A character vector that defines possible values of the scale and their
60 | order
61 | \item A function that accepts the existing (automatic) values and returns
62 | new ones. Also accepts rlang \link[rlang:as_function]{lambda} function
63 | notation.
64 | }}
65 | \item{\code{na.translate}}{Unlike continuous scales, discrete scales can easily show
66 | missing values, and do so by default. If you want to remove missing values
67 | from a discrete scale, specify \code{na.translate = FALSE}.}
68 | \item{\code{drop}}{Should unused factor levels be omitted from the scale?
69 | The default, \code{TRUE}, uses the levels that appear in the data;
70 | \code{FALSE} includes the levels in the factor. Please note that to display
71 | every level in a legend, the layer should use \code{show.legend = TRUE}.}
72 | \item{\code{guide}}{A function used to create a guide or its name. See
73 | \code{\link[ggplot2:guides]{guides()}} for more information.}
74 | \item{\code{call}}{The \code{call} used to construct the scale for reporting messages.}
75 | }}
76 | }
77 | \description{
78 | Fill scale using the \href{https://ngmdb.usgs.gov/fgdc_gds/geolsymstd.php}{FGDC Digital Cartographic Standard for Geologic Map Symbolization}. Fill values
79 | should correspond to specific pattern codes (see "Details").
80 | }
81 | \details{
82 | For specific codes, see the "pattern numbers" in the \href{https://ngmdb.usgs.gov/fgdc_gds/geolsymstd/fgdc-geolsym-patternchart.pdf}{full pattern chart}
83 | for valid \code{code} values. Daven Quinn has also assembled more accessible
84 | documentation of the \href{https://davenquinn.com/projects/geologic-patterns/#pattern-reference}{map patterns/codes}
85 | and \href{https://davenquinn.com/projects/geologic-patterns/#series-600}{lithology patterns/codes}.
86 | The set of patterns with names is also included in the built-in dataset
87 | \link{fgdc_names} (and a label dictionary is available using \code{\link[=fgdc_dict]{fgdc_dict()}}.
88 | \code{\link[rmacrostrat:def_lithologies]{rmacrostrat::def_lithologies()}} can also be used to look up pattern codes
89 | for various lithologies (see the "fill" column). Note that codes associated
90 | with color variants (e.g., "101-M") are supported but will result in the
91 | default color variant instead (usually black and white, e.g., "101-K").
92 |
93 | These patterns were originally processed and optimized by Daven Quinn and
94 | are hosted on \href{https://github.com/davenquinn/geologic-patterns/}{GitHub}.
95 | }
96 | \section{Warning}{
97 | Pattern fills are not supported on all graphics devices.
98 | Not all devices are under active development, and such devices are unlikely
99 | to add support for new features (such as pattern fills). The new features
100 | have only been implemented on a subset of graphics devices so far:
101 | \code{\link[=cairo_pdf]{cairo_pdf()}}, \code{\link[=cairo_ps]{cairo_ps()}}, \code{\link[=x11]{x11(type="cairo")}},
102 | \code{\link[=png]{png(type="cairo")}},
103 | \code{\link[=jpeg]{jpeg(type="cairo")}},
104 | \code{\link[=tiff]{tiff(type="cairo")}}, \code{\link[=svg]{svg()}}, and \code{\link[=pdf]{pdf()}}. Although
105 | there is no support yet for \code{\link[=quartz]{quartz()}} or \code{\link[=windows]{windows()}}, almost all of the
106 | graphics devices above will work on all major platforms. Further, the
107 | \href{https://ragg.r-lib.org/}{ragg} and
108 | \href{https://svglite.r-lib.org/index.html}{svglite} packages contain graphics
109 | devices that support patterns. When using a graphics device where patterns
110 | are not supported, closed shapes will be rendered with a transparent fill.
111 | Note that, at least on Windows machines, the default device in RStudio and
112 | in the knitr package is \code{\link[=png]{png()}}, which does not support patterns. In
113 | RStudio, you can go to ‘Tools > Global Options > General > Graphics’ and
114 | choose the ‘Cairo PNG’ device from the dropdown menu to display patterns.
115 | Similar issues may arise when using RStudio on other operating systems.
116 | }
117 |
118 | \examples{
119 | library(ggplot2)
120 | vals <- c("101", "313", "603", "733")
121 | ggplot(mpg, aes(factor(cyl), fill = vals[factor(cyl)])) +
122 | geom_bar() +
123 | scale_fill_geopattern(name = NULL)
124 | }
125 | \seealso{
126 | FGDC patterns:
127 | \code{\link{fgdc_dict}()},
128 | \code{\link{fgdc_names}},
129 | \code{\link{geo_pattern}()},
130 | \code{\link{grid.pattern_geo}()}
131 | }
132 | \concept{patterns}
133 |
--------------------------------------------------------------------------------
/man/facet_wrap_color.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/facet_color.R
3 | \docType{data}
4 | \name{facet_wrap_color}
5 | \alias{facet_wrap_color}
6 | \alias{facet_wrap_geo}
7 | \alias{FacetWrapColor}
8 | \title{Wrap a 1d ribbon of panels into 2d with colored strips}
9 | \usage{
10 | facet_wrap_color(
11 | facets,
12 | colors,
13 | nrow = NULL,
14 | ncol = NULL,
15 | scales = "fixed",
16 | shrink = TRUE,
17 | labeller = "label_value",
18 | lab_colors = "auto",
19 | as.table = TRUE,
20 | drop = TRUE,
21 | dir = "h",
22 | strip.position = "top",
23 | axes = "margins",
24 | axis.labels = "all"
25 | )
26 |
27 | facet_wrap_geo(
28 | facets,
29 | colors = stages,
30 | nrow = NULL,
31 | ncol = NULL,
32 | scales = "fixed",
33 | shrink = TRUE,
34 | labeller = "label_value",
35 | lab_colors = "auto",
36 | as.table = TRUE,
37 | drop = TRUE,
38 | dir = "h",
39 | strip.position = "top",
40 | axes = "margins",
41 | axis.labels = "all"
42 | )
43 | }
44 | \arguments{
45 | \item{facets}{A set of variables or expressions quoted by \code{\link[ggplot2:vars]{vars()}}
46 | and defining faceting groups on the rows or columns dimension.
47 | The variables can be named (the names are passed to \code{labeller}).
48 |
49 | For compatibility with the classic interface, can also be a
50 | formula or character vector. Use either a one sided formula, \code{~a + b},
51 | or a character vector, \code{c("a", "b")}.}
52 |
53 | \item{colors}{Specifies which colors to use to replace the strip backgrounds.
54 | Either A) a function that returns a color for a given strip label, B) the
55 | character name of a function that does the same, C) a named character
56 | vector with names matching strip labels and values indicating the desired
57 | colors, or D) a data.frame representing a lookup table with columns named
58 | "name" (matching strip labels) and "color" (indicating desired colors). If
59 | the function returns \code{NA}, the default background color will be used.}
60 |
61 | \item{nrow, ncol}{Number of rows and columns.}
62 |
63 | \item{scales}{Should scales be fixed (\code{"fixed"}, the default),
64 | free (\code{"free"}), or free in one dimension (\code{"free_x"},
65 | \code{"free_y"})?}
66 |
67 | \item{shrink}{If \code{TRUE}, will shrink scales to fit output of
68 | statistics, not raw data. If \code{FALSE}, will be range of raw data
69 | before statistical summary.}
70 |
71 | \item{labeller}{A function that takes one data frame of labels and
72 | returns a list or data frame of character vectors. Each input
73 | column corresponds to one factor. Thus there will be more than
74 | one with \code{vars(cyl, am)}. Each output
75 | column gets displayed as one separate line in the strip
76 | label. This function should inherit from the "labeller" S3 class
77 | for compatibility with \code{\link[ggplot2:labeller]{labeller()}}. You can use different labeling
78 | functions for different kind of labels, for example use \code{\link[ggplot2:label_parsed]{label_parsed()}} for
79 | formatting facet labels. \code{\link[ggplot2:label_value]{label_value()}} is used by default,
80 | check it for more details and pointers to other options.}
81 |
82 | \item{lab_colors}{Specifies which colors to use for the strip labels. Either
83 | A) a function that returns a color for a given strip label, B) the
84 | character name of a function that does the same, C) a named character
85 | vector with names matching strip labels and values indicating the desired
86 | colors, D) a data.frame representing a lookup table with columns named
87 | "name" (matching strip labels) and "lab_color" (indicating desired colors),
88 | or E) "auto" (the default), which set the labels to black or white,
89 | whichever has better contrast with the background color, based on
90 | \href{https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en}{recommendations by the International Telecommunication Union}.
91 | If the function returns \code{NA}, the default label color will be used.}
92 |
93 | \item{as.table}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#superseded}{\figure{lifecycle-superseded.svg}{options: alt='[Superseded]'}}}{\strong{[Superseded]}} The \code{as.table} argument
94 | is now absorbed into the \code{dir} argument via the two letter options.
95 | If \code{TRUE}, the facets are laid out like a table with highest values at the
96 | bottom-right. If \code{FALSE}, the facets are laid out like a plot with the
97 | highest value at the top-right.}
98 |
99 | \item{drop}{If \code{TRUE}, the default, all factor levels not used in the
100 | data will automatically be dropped. If \code{FALSE}, all factor levels
101 | will be shown, regardless of whether or not they appear in the data.}
102 |
103 | \item{dir}{Direction: either \code{"h"} for horizontal, the default, or \code{"v"},
104 | for vertical. When \code{"h"} or \code{"v"} will be combined with \code{as.table} to
105 | set final layout. Alternatively, a combination of \code{"t"} (top) or
106 | \code{"b"} (bottom) with \code{"l"} (left) or \code{"r"} (right) to set a layout directly.
107 | These two letters give the starting position and the first letter gives
108 | the growing direction. For example \code{"rt"} will place the first panel in
109 | the top-right and starts filling in panels right-to-left.}
110 |
111 | \item{strip.position}{By default, the labels are displayed on the top of
112 | the plot. Using \code{strip.position} it is possible to place the labels on
113 | either of the four sides by setting \code{strip.position = c("top",
114 | "bottom", "left", "right")}}
115 |
116 | \item{axes}{Determines which axes will be drawn in case of fixed scales.
117 | When \code{"margins"} (default), axes will be drawn at the exterior margins.
118 | \code{"all_x"} and \code{"all_y"} will draw the respective axes at the interior
119 | panels too, whereas \code{"all"} will draw all axes at all panels.}
120 |
121 | \item{axis.labels}{Determines whether to draw labels for interior axes when
122 | the scale is fixed and the \code{axis} argument is not \code{"margins"}. When
123 | \code{"all"} (default), all interior axes get labels. When \code{"margins"}, only
124 | the exterior axes get labels, and the interior axes get none. When
125 | \code{"all_x"} or \code{"all_y"}, only draws the labels at the interior axes in the
126 | x- or y-direction respectively.}
127 | }
128 | \description{
129 | \code{facet_wrap_color} behaves similarly to \code{\link[ggplot2:facet_wrap]{ggplot2::facet_wrap()}} in that it
130 | wraps a 1d sequence of panels into 2d. The main difference is that it also
131 | allows the user to specify the background and label colors of the individual
132 | facet strips using the \code{colors} and \code{lab_colors} arguments. This is generally
133 | a better use of screen space than \code{\link[=facet_grid_color]{facet_grid_color()}} because most displays
134 | are roughly rectangular.
135 | }
136 | \details{
137 | \code{facet_wrap_geo(...)} is an alias of \code{facet_wrap_color()} with the default of
138 | \code{colors} set to \code{stages}.
139 | }
140 | \examples{
141 | library(ggplot2)
142 | df <- data.frame(x = 1:10, y = 1:10, period = c("Permian", "Triassic"))
143 | ggplot(df) +
144 | geom_point(aes(x, y)) +
145 | facet_wrap_color(vars(period), colors = periods)
146 | }
147 | \seealso{
148 | Other faceting functions:
149 | \code{\link{facet_grid_color}()},
150 | \code{\link{facet_nested_color}()},
151 | \code{\link{facet_nested_wrap_color}()}
152 | }
153 | \concept{faceting functions}
154 | \keyword{datasets}
155 |
--------------------------------------------------------------------------------
/man/facet_grid_color.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/facet_color.R
3 | \docType{data}
4 | \name{facet_grid_color}
5 | \alias{facet_grid_color}
6 | \alias{facet_grid_geo}
7 | \alias{FacetGridColor}
8 | \title{Lay out panels in a grid with colored strips}
9 | \usage{
10 | facet_grid_color(
11 | colors,
12 | rows = NULL,
13 | cols = NULL,
14 | scales = "fixed",
15 | space = "fixed",
16 | shrink = TRUE,
17 | labeller = "label_value",
18 | lab_colors = "auto",
19 | as.table = TRUE,
20 | switch = NULL,
21 | drop = TRUE,
22 | margins = FALSE,
23 | axes = "margins",
24 | axis.labels = "all"
25 | )
26 |
27 | facet_grid_geo(
28 | colors = stages,
29 | rows = NULL,
30 | cols = NULL,
31 | scales = "fixed",
32 | space = "fixed",
33 | shrink = TRUE,
34 | labeller = "label_value",
35 | lab_colors = "auto",
36 | as.table = TRUE,
37 | switch = NULL,
38 | drop = TRUE,
39 | margins = FALSE,
40 | axes = "margins",
41 | axis.labels = "all"
42 | )
43 | }
44 | \arguments{
45 | \item{colors}{Specifies which colors to use to replace the strip backgrounds.
46 | Either A) a function that returns a color for a given strip label, B) the
47 | character name of a function that does the same, C) a named character
48 | vector with names matching strip labels and values indicating the desired
49 | colors, or D) a data.frame representing a lookup table with columns named
50 | "name" (matching strip labels) and "color" (indicating desired colors). If
51 | the function returns \code{NA}, the default background color will be used.}
52 |
53 | \item{rows, cols}{A set of variables or expressions quoted by
54 | \code{\link[ggplot2:vars]{vars()}} and defining faceting groups on the rows or columns
55 | dimension. The variables can be named (the names are passed to
56 | \code{labeller}).
57 |
58 | For compatibility with the classic interface, \code{rows} can also be
59 | a formula with the rows (of the tabular display) on the LHS and
60 | the columns (of the tabular display) on the RHS; the dot in the
61 | formula is used to indicate there should be no faceting on this
62 | dimension (either row or column).}
63 |
64 | \item{scales}{Are scales shared across all facets (the default,
65 | \code{"fixed"}), or do they vary across rows (\code{"free_x"}),
66 | columns (\code{"free_y"}), or both rows and columns (\code{"free"})?}
67 |
68 | \item{space}{If \code{"fixed"}, the default, all panels have the same size.
69 | If \code{"free_y"} their height will be proportional to the length of the
70 | y scale; if \code{"free_x"} their width will be proportional to the
71 | length of the x scale; or if \code{"free"} both height and width will
72 | vary. This setting has no effect unless the appropriate scales also vary.}
73 |
74 | \item{shrink}{If \code{TRUE}, will shrink scales to fit output of
75 | statistics, not raw data. If \code{FALSE}, will be range of raw data
76 | before statistical summary.}
77 |
78 | \item{labeller}{A function that takes one data frame of labels and
79 | returns a list or data frame of character vectors. Each input
80 | column corresponds to one factor. Thus there will be more than
81 | one with \code{vars(cyl, am)}. Each output
82 | column gets displayed as one separate line in the strip
83 | label. This function should inherit from the "labeller" S3 class
84 | for compatibility with \code{\link[ggplot2:labeller]{labeller()}}. You can use different labeling
85 | functions for different kind of labels, for example use \code{\link[ggplot2:label_parsed]{label_parsed()}} for
86 | formatting facet labels. \code{\link[ggplot2:label_value]{label_value()}} is used by default,
87 | check it for more details and pointers to other options.}
88 |
89 | \item{lab_colors}{Specifies which colors to use for the strip labels. Either
90 | A) a function that returns a color for a given strip label, B) the
91 | character name of a function that does the same, C) a named character
92 | vector with names matching strip labels and values indicating the desired
93 | colors, D) a data.frame representing a lookup table with columns named
94 | "name" (matching strip labels) and "lab_color" (indicating desired colors),
95 | or E) "auto" (the default), which set the labels to black or white,
96 | whichever has better contrast with the background color, based on
97 | \href{https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en}{recommendations by the International Telecommunication Union}.
98 | If the function returns \code{NA}, the default label color will be used.}
99 |
100 | \item{as.table}{If \code{TRUE}, the default, the facets are laid out like
101 | a table with highest values at the bottom-right. If \code{FALSE}, the
102 | facets are laid out like a plot with the highest value at the top-right.}
103 |
104 | \item{switch}{By default, the labels are displayed on the top and
105 | right of the plot. If \code{"x"}, the top labels will be
106 | displayed to the bottom. If \code{"y"}, the right-hand side
107 | labels will be displayed to the left. Can also be set to
108 | \code{"both"}.}
109 |
110 | \item{drop}{If \code{TRUE}, the default, all factor levels not used in the
111 | data will automatically be dropped. If \code{FALSE}, all factor levels
112 | will be shown, regardless of whether or not they appear in the data.}
113 |
114 | \item{margins}{Either a logical value or a character
115 | vector. Margins are additional facets which contain all the data
116 | for each of the possible values of the faceting variables. If
117 | \code{FALSE}, no additional facets are included (the
118 | default). If \code{TRUE}, margins are included for all faceting
119 | variables. If specified as a character vector, it is the names of
120 | variables for which margins are to be created.}
121 |
122 | \item{axes}{Determines which axes will be drawn. When \code{"margins"}
123 | (default), axes will be drawn at the exterior margins. \code{"all_x"} and
124 | \code{"all_y"} will draw the respective axes at the interior panels too, whereas
125 | \code{"all"} will draw all axes at all panels.}
126 |
127 | \item{axis.labels}{Determines whether to draw labels for interior axes when
128 | the \code{axes} argument is not \code{"margins"}. When \code{"all"} (default), all
129 | interior axes get labels. When \code{"margins"}, only the exterior axes get
130 | labels and the interior axes get none. When \code{"all_x"} or \code{"all_y"}, only
131 | draws the labels at the interior axes in the x- or y-direction
132 | respectively.}
133 | }
134 | \description{
135 | \code{facet_grid_color} behaves similarly to \code{\link[ggplot2:facet_grid]{ggplot2::facet_grid()}} in that it
136 | forms a matrix of panels defined by row and column faceting variables. The
137 | main difference is that it also allows the user to specify the background and
138 | label colors of the individual facet strips using the \code{colors} and
139 | \code{lab_colors} arguments. If you have only one variable with many levels, try
140 | \code{\link[=facet_wrap_color]{facet_wrap_color()}}.
141 | }
142 | \details{
143 | \code{facet_grid_geo(...)} is an alias of \code{facet_grid_color()} with the default of
144 | \code{colors} set to \code{stages}.
145 | }
146 | \examples{
147 | library(ggplot2)
148 | df <- data.frame(x = 1:10, y = 1:10, period = c("Permian", "Triassic"))
149 | ggplot(df) +
150 | geom_point(aes(x, y)) +
151 | facet_grid_color(cols = vars(period), colors = periods)
152 | }
153 | \seealso{
154 | Other faceting functions:
155 | \code{\link{facet_nested_color}()},
156 | \code{\link{facet_nested_wrap_color}()},
157 | \code{\link{facet_wrap_color}()}
158 | }
159 | \concept{faceting functions}
160 | \keyword{datasets}
161 |
--------------------------------------------------------------------------------