├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ └── R-CMD-check.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── alphaMaskGrob.R ├── clippingPathGrob.R ├── grid-pattern-fill.R ├── grid-pattern.R ├── gridpattern-package.R ├── mean_col.R ├── pattern-array-ambient.R ├── pattern-array-image.R ├── pattern-array-magick.R ├── pattern-array-placeholder.R ├── pattern-array-plasma.R ├── pattern-both-gradient.R ├── pattern-both-rose.R ├── pattern-both-text.R ├── pattern-geometry-circle.R ├── pattern-geometry-crosshatch.R ├── pattern-geometry-fill.R ├── pattern-geometry-none.R ├── pattern-geometry-pch.R ├── pattern-geometry-regular_polygon.R ├── pattern-geometry-stripe.R ├── pattern-geometry-tiling.R ├── pattern-geometry-wave.R ├── pattern-geometry-weave.R ├── pattern-pattern-aRtsy.R ├── pattern_hex.R ├── pattern_square.R ├── pattern_weave.R ├── reset_image_cache.R ├── standalone-guess_has_R4.1_features.R ├── standalone-update_alpha.R ├── star_scale.R ├── utils-array.R ├── utils-geometry.R ├── utils-ggpattern.R ├── utils-ggplot2.R ├── utils-grid.R ├── utils-magick-fill.R ├── utils-magick-misc.R ├── utils-magick-pattern.R ├── utils-magick-read.R ├── utils-misc.R ├── utils-params.R ├── utils-polygon_df.R ├── utils-sf.R ├── z_guess_has_R4.1_features_docs.R ├── z_update_alpha_docs.R └── zzz.R ├── README.Rmd ├── README.md ├── Rakefile ├── _pkgdown.yml ├── cran-comments.md ├── man ├── alphaMaskGrob.Rd ├── clippingPathGrob.Rd ├── figures │ ├── README-circle-1.png │ ├── README-crosshatch-1.png │ ├── README-ggpattern-1.png │ ├── README-ggplot2-1.png │ ├── README-hex_ggpattern-1.png │ ├── README-piecepackr-1.png │ ├── README-regular_hex-1.png │ ├── README-regular_star-1.png │ ├── README-rhombitrihexagonal-1.png │ ├── README-rose-1.png │ ├── README-text-1.png │ ├── README-truncated_hexagonal-1.png │ ├── README-wave-1.png │ ├── README-weave-1.png │ ├── logo.png │ └── logo.svg ├── grid.pattern.Rd ├── grid.pattern_aRtsy.Rd ├── grid.pattern_ambient.Rd ├── grid.pattern_circle.Rd ├── grid.pattern_crosshatch.Rd ├── grid.pattern_fill.Rd ├── grid.pattern_gradient.Rd ├── grid.pattern_image.Rd ├── grid.pattern_magick.Rd ├── grid.pattern_none.Rd ├── grid.pattern_pch.Rd ├── grid.pattern_placeholder.Rd ├── grid.pattern_plasma.Rd ├── grid.pattern_polygon_tiling.Rd ├── grid.pattern_regular_polygon.Rd ├── grid.pattern_rose.Rd ├── grid.pattern_stripe.Rd ├── grid.pattern_text.Rd ├── grid.pattern_wave.Rd ├── grid.pattern_weave.Rd ├── gridpattern-package.Rd ├── guess_has_R4.1_features.Rd ├── mean_col.Rd ├── patternFill.Rd ├── pattern_hex.Rd ├── pattern_square.Rd ├── pattern_weave.Rd ├── reset_image_cache.Rd ├── star_scale.Rd └── update_alpha.Rd ├── raw-data └── logo.R ├── tests ├── figs │ └── array │ │ ├── alphaMaskGrob_cairo.png │ │ ├── alphaMaskGrob_feature.png │ │ ├── alphaMaskGrob_manual.png │ │ ├── alphaMaskGrob_ragg.png │ │ ├── ambient.png │ │ ├── ambient_worley.png │ │ ├── clipGrob_cairo.png │ │ ├── clipGrob_feature.png │ │ ├── clipGrob_manual.png │ │ ├── clipGrob_ragg.png │ │ ├── gradient.png │ │ ├── gradient_horizontal.png │ │ ├── image.png │ │ ├── image_expand.png │ │ ├── image_none.png │ │ ├── image_squish.png │ │ ├── image_tile.png │ │ ├── magick.png │ │ ├── placeholder.png │ │ ├── plasma.png │ │ ├── plasma_zero.png │ │ ├── rose.png │ │ ├── simple.png │ │ └── text.png ├── testthat.R ├── testthat │ ├── _snaps │ │ ├── geometry │ │ │ ├── centroid.svg │ │ │ ├── circle.svg │ │ │ ├── crosshatch.svg │ │ │ ├── default.svg │ │ │ ├── eight-sided-star.svg │ │ │ ├── fill.svg │ │ │ ├── hexagon.svg │ │ │ ├── none.svg │ │ │ ├── regular-polygon.svg │ │ │ ├── square.svg │ │ │ ├── stripe-gpar.svg │ │ │ ├── stripe.svg │ │ │ ├── two-id.svg │ │ │ ├── wave-sine.svg │ │ │ ├── wave-triangle.svg │ │ │ └── weave.svg │ │ ├── pch │ │ │ ├── col-fill.svg │ │ │ ├── compound.svg │ │ │ ├── fill-fill.svg │ │ │ └── simple.svg │ │ └── tiling │ │ │ ├── 12-12-4.svg │ │ │ ├── 12-3-12-3.svg │ │ │ ├── 18-18-3.svg │ │ │ ├── 2-2-2-2.svg │ │ │ ├── 2-3-12.svg │ │ │ ├── 3-3-3-12-3-3-12.svg │ │ │ ├── 3-3-3-3-alt.svg │ │ │ ├── 3-3-3-3.svg │ │ │ ├── 3-3-8-3-4-3-8.svg │ │ │ ├── 3-3-8-4-8.svg │ │ │ ├── 3-4-6-3-12.svg │ │ │ ├── 3-4-8-3-8.svg │ │ │ ├── 3-6-6.svg │ │ │ ├── 4-2-4-2.svg │ │ │ ├── 4-4-4.svg │ │ │ ├── 4-6-4-6-4-6.svg │ │ │ ├── 4-6-4-6.svg │ │ │ ├── 4-8-4-8.svg │ │ │ ├── 6-6-6-6.svg │ │ │ ├── 8-4-8-4.svg │ │ │ ├── 9-3-9-3.svg │ │ │ ├── elongated-triangular.svg │ │ │ ├── herringbone.svg │ │ │ ├── hexagonal-tiling.svg │ │ │ ├── pythagorean.svg │ │ │ ├── rhombille.svg │ │ │ ├── rhombitrihexagonal-tiling.svg │ │ │ ├── snub-square-tiling.svg │ │ │ ├── snub-trihex-tiling.svg │ │ │ ├── square-tiling.svg │ │ │ ├── tetrakis-square.svg │ │ │ ├── triangular-tiling.svg │ │ │ ├── trihexagonal-tiling.svg │ │ │ ├── trunc-hex-tiling.svg │ │ │ ├── trunc-square-tiling.svg │ │ │ └── trunc-trihex-tiling.svg │ ├── test_aRtsy.R │ ├── test_array.R │ ├── test_geometry.R │ ├── test_hex.R │ ├── test_pch.R │ ├── test_square.R │ ├── test_tiling.R │ ├── test_utils.R │ └── test_weave.R └── text_diagrams │ ├── basket.txt │ ├── diagonal.txt │ ├── diagonal_1.txt │ ├── diagonal_skew.txt │ ├── hex.txt │ ├── hex1_1.txt │ ├── hex1_2.txt │ ├── hex2_2.txt │ ├── hex2_4.txt │ ├── hex3_2.txt │ ├── hex3_7.txt │ ├── hex_skew_5.txt │ ├── horizontal.txt │ ├── matt.txt │ ├── matt3221.txt │ ├── matt_21.txt │ ├── matt_irregular.txt │ ├── plain.txt │ ├── rib_warp │ ├── rib_warp.txt │ ├── rib_warp_irregular.txt │ ├── satin_5.txt │ ├── square_1122.txt │ ├── square_3.txt │ ├── square_4.txt │ ├── square_5.txt │ ├── square_tiling_3.txt │ ├── square_twill.txt │ ├── twill3221.txt │ ├── twill_13.txt │ ├── twill_13_herringbone.txt │ ├── twill_21.txt │ ├── twill_212.txt │ ├── twill_22.txt │ ├── twill_22_zigzag.txt │ ├── twill_3.txt │ └── vertical.txt └── vignettes ├── developing-patterns.Rmd └── tiling.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.appveyor.yml$ 2 | ^.travis.yml$ 3 | ^cran-comments.md$ 4 | ^LICENSE.md$ 5 | ^README.Rmd$ 6 | ^README.html$ 7 | ^Rakefile$ 8 | ^pkgdown$ 9 | ^_pkgdown.yml$ 10 | ^raw-data$ 11 | ^codecov.yml$ 12 | ^doc$ 13 | ^tmp$ 14 | ^Meta$ 15 | ^\.github$ 16 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 22 | - {os: ubuntu-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'oldrel-1'} 24 | 25 | env: 26 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 27 | R_KEEP_PKG_SOURCE: yes 28 | 29 | steps: 30 | - uses: actions/checkout@v4 31 | 32 | - uses: r-lib/actions/setup-pandoc@v2 33 | 34 | - uses: r-lib/actions/setup-r@v2 35 | with: 36 | r-version: ${{ matrix.config.r }} 37 | http-user-agent: ${{ matrix.config.http-user-agent }} 38 | use-public-rspm: true 39 | 40 | - uses: r-lib/actions/setup-r-dependencies@v2 41 | with: 42 | extra-packages: rcmdcheck 43 | 44 | - uses: r-lib/actions/check-r-package@v2 45 | 46 | - name: Show testthat output 47 | if: always() 48 | run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true 49 | shell: bash 50 | 51 | - name: Upload check results 52 | if: failure() 53 | uses: actions/upload-artifact@main 54 | with: 55 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results 56 | path: check 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | README.html 2 | codecov.yml 3 | *.swp 4 | /doc/ 5 | /Meta/ 6 | /pkgdown/ 7 | /tmp/ 8 | raw-data/*.png 9 | vignettes/*.R 10 | vignettes/*.html 11 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: gridpattern 2 | Type: Package 3 | Title: 'grid' Pattern Grobs 4 | Version: 1.3.3-1 5 | Authors@R: c( 6 | person("Trevor L.", "Davis", role=c("aut", "cre"), email="trevor.l.davis@gmail.com", 7 | comment = c(ORCID = "0000-0001-6341-4639")), 8 | person("Mike", "FC", role = "aut", comment = "Code/docs adapted from ggpattern"), 9 | person("ggplot2 authors", role = "ctb", comment = "some utility functions copied from ggplot2")) 10 | Description: Provides 'grid' grobs that fill in a user-defined area with various patterns. Includes enhanced versions of the geometric and image-based patterns originally contained in the 'ggpattern' package as well as original 'pch', 'polygon_tiling', 'regular_polygon', 'rose', 'text', 'wave', and 'weave' patterns plus support for custom user-defined patterns. 11 | URL: https://trevorldavis.com/R/gridpattern/, https://github.com/trevorld/gridpattern 12 | BugReports: https://github.com/trevorld/gridpattern/issues 13 | License: MIT + file LICENSE 14 | Encoding: UTF-8 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.3.1 17 | Depends: 18 | R (>= 3.4.0) 19 | Imports: 20 | glue, 21 | grDevices, 22 | grid, 23 | memoise, 24 | png, 25 | rlang, 26 | sf, 27 | utils 28 | Suggests: 29 | ambient, 30 | aRtsy, 31 | ggplot2 (>= 3.5.0), 32 | gtable, 33 | knitr, 34 | magick (>= 2.7.4), 35 | ragg (>= 1.2.0), 36 | rmarkdown, 37 | scales, 38 | svglite (>= 2.1.0), 39 | testthat, 40 | vdiffr (>= 1.0.6) 41 | VignetteBuilder: knitr, rmarkdown 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2024 2 | COPYRIGHT HOLDER: Trevor L. Davis 3 | 4 | YEAR: 2020 5 | COPYRIGHT HOLDER: mikefc@coolbutuseless.com 6 | 7 | YEAR: 2023 8 | COPYRIGHT HOLDER: ggplot2 authors 9 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright © 2024 Trevor L. Davis 5 | Copyright © 2020 mikefc@coolbutuseless.com 6 | Copyright © 2023 ggplot2 authors 7 | 8 | Permission is hereby granted, free of charge, to any person 9 | obtaining a copy of this software and associated documentation 10 | files (the “Software”), to deal in the Software without 11 | restriction, including without limitation the rights to use, 12 | copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the 14 | Software is furnished to do so, subject to the following 15 | conditions: 16 | 17 | The above copyright notice and this permission notice shall be 18 | included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 22 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 24 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 25 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27 | OTHER DEALINGS IN THE SOFTWARE. 28 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(makeContent,alpha_mask) 4 | S3method(makeContent,clipping_path) 5 | S3method(makeContent,pattern) 6 | S3method(print,pattern_hex) 7 | S3method(print,pattern_square) 8 | S3method(print,pattern_weave) 9 | S3method(update_pattern_alpha,GridPattern) 10 | S3method(update_pattern_alpha,GridTilingPattern) 11 | S3method(update_pattern_alpha,default) 12 | S3method(update_pattern_alpha,list) 13 | export(alphaMaskGrob) 14 | export(clippingPathGrob) 15 | export(grid.pattern) 16 | export(grid.pattern_aRtsy) 17 | export(grid.pattern_ambient) 18 | export(grid.pattern_circle) 19 | export(grid.pattern_crosshatch) 20 | export(grid.pattern_fill) 21 | export(grid.pattern_gradient) 22 | export(grid.pattern_image) 23 | export(grid.pattern_magick) 24 | export(grid.pattern_none) 25 | export(grid.pattern_pch) 26 | export(grid.pattern_placeholder) 27 | export(grid.pattern_plasma) 28 | export(grid.pattern_polygon_tiling) 29 | export(grid.pattern_regular_polygon) 30 | export(grid.pattern_rose) 31 | export(grid.pattern_stripe) 32 | export(grid.pattern_text) 33 | export(grid.pattern_wave) 34 | export(grid.pattern_weave) 35 | export(guess_has_R4.1_features) 36 | export(mean_col) 37 | export(names_aRtsy) 38 | export(names_hex) 39 | export(names_magick) 40 | export(names_magick_intensity) 41 | export(names_magick_stripe) 42 | export(names_pattern) 43 | export(names_placeholder) 44 | export(names_polygon_tiling) 45 | export(names_square) 46 | export(names_weave) 47 | export(patternFill) 48 | export(patternGrob) 49 | export(pattern_hex) 50 | export(pattern_square) 51 | export(pattern_weave) 52 | export(reset_image_cache) 53 | export(star_angle) 54 | export(star_scale) 55 | export(update_alpha) 56 | import(grid) 57 | importFrom(glue,glue) 58 | importFrom(grDevices,col2rgb) 59 | importFrom(grDevices,dev.capabilities) 60 | importFrom(grDevices,dev.capture) 61 | importFrom(grDevices,dev.off) 62 | importFrom(grDevices,png) 63 | importFrom(grDevices,rgb) 64 | importFrom(rlang,"%||%") 65 | importFrom(rlang,abort) 66 | importFrom(rlang,inform) 67 | importFrom(rlang,warn) 68 | importFrom(utils,hasName) 69 | importFrom(utils,head) 70 | importFrom(utils,packageVersion) 71 | importFrom(utils,tail) 72 | -------------------------------------------------------------------------------- /R/grid-pattern-fill.R: -------------------------------------------------------------------------------- 1 | #' Create patterned fills by pattern name 2 | #' 3 | #' `patternFill()` returns [grid::pattern()] fill objects. 4 | #' It is a wrapper around [patternGrob()]. 5 | #' 6 | #' @param ... Passed to [patternGrob()]. 7 | #' @param x,y,width,height The size of the [grid::pattern()] tile. 8 | #' @param default.units The default [grid::unit()] unit to use for `x`, `y`, `width`, and `height`. 9 | #' @param just,hjust,vjust The justification of the tile relative to its location. 10 | #' @param group A logical indicating whether the pattern is relative to the bounding box of the grob or whether it is relative to individual shapes within the grob. Ignored if R is less than version 4.2. 11 | #' @examples 12 | #' if (guess_has_R4.1_features("patterns") && 13 | #' require("grid", quietly = TRUE)) { 14 | #' grid.newpage() 15 | #' stripe_fill <- patternFill("stripe", fill = c("red", "blue")) 16 | #' grid.circle(gp = gpar(fill = stripe_fill)) 17 | #' } 18 | #' 19 | #' if (guess_has_R4.1_features("patterns") && 20 | #' require("ggplot2", quietly = TRUE) && 21 | #' (getRversion() >= "4.2")) { 22 | #' grid.newpage() 23 | #' weave_fill <- patternFill("weave", fill = "red", fill2 = "blue", 24 | #' colour = "transparent") 25 | #' hex_fill <- patternFill("polygon_tiling", type = "hexagonal", 26 | #' fill = c("black", "white", "grey"), 27 | #' colour = "transparent") 28 | #' df <- data.frame(trt = c("a", "b"), outcome = c(1.9, 3.2)) 29 | #' gg <- ggplot(df, aes(trt, outcome)) + 30 | #' geom_col(fill = list(weave_fill, hex_fill)) 31 | #' plot(gg) 32 | #' } 33 | #' @return A [grid::pattern()] fill object. 34 | #' @export 35 | patternFill <- function(..., 36 | x = 0.5, y = 0.5, width = 1, height = 1, 37 | default.units = "npc", 38 | just = "centre", hjust = NULL, vjust = NULL, 39 | group = TRUE) { 40 | stopifnot(getRversion() >= "4.1.0") 41 | args <- list(grob = patternGrob(...), 42 | x = x, y = y, width = width, height = height, 43 | default.units = default.units, 44 | just = just, hjust = hjust, vjust = vjust) 45 | # `group` was introduced in R 4.2 46 | if (getRversion() >= "4.2.0") 47 | args$group <- group 48 | do.call(grid::pattern, args) 49 | } 50 | -------------------------------------------------------------------------------- /R/gridpattern-package.R: -------------------------------------------------------------------------------- 1 | #' @section Package options: 2 | #' The following `gridpattern` options may be set globally via [base::options()]: 3 | #' \describe{ 4 | #' \item{ggpattern_array_funcs}{Set custom \dQuote{array} pattern functions.} 5 | #' \item{ggpattern_geometry_funcs}{Set custom \dQuote{geometry} pattern functions.} 6 | #' \item{ggpattern_res}{Set custom raster image resolution (pixels per inch) for certain patterns.} 7 | #' \item{ggpattern_use_R4.1_clipping}{If `TRUE` use the grid clipping path feature introduced in R v4.1.0. 8 | #' If `FALSE` do a `rasterGrob` approximation of the clipped pattern. 9 | #' If `NULL` try to guess an appropriate choice.} 10 | #' \item{ggpattern_use_R4.1_features}{If `TRUE` sets the default for all the other 11 | #' `ggpattern_use_R4.1_*` options arguments to `TRUE`. 12 | #' If `FALSE` sets them to `FALSE`.} 13 | #' \item{ggpattern_use_R4.1_gradients}{If `TRUE` use the grid gradient feature introduced in R v4.1.0. 14 | #' If `FALSE` do a `rasterGrob` approximation of the gradient pattern. 15 | #' If `NULL` try to guess an appropriate choice.} 16 | #' \item{ggpattern_use_R4.1_masks}{If `TRUE` use the grid mask feature introduced in R v4.1.0. 17 | #' If `FALSE` do a `rasterGrob` approximation of the masked pattern. 18 | #' If `NULL` try to guess an appropriate choice.} 19 | #' \item{ggpattern_use_R4.1_patterns}{If `TRUE` use the grid pattern feature introduced in R v4.1.0. 20 | #' Currently only used by a couple of examples.} 21 | #' } 22 | #' Note to use the R v4.1.0 features one needs R be (at least) version 4.1 and not all graphic devices 23 | #' support any/all these features. See \url{https://www.stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/definitions/definitions.html} for more information on these features. 24 | "_PACKAGE" 25 | -------------------------------------------------------------------------------- /R/mean_col.R: -------------------------------------------------------------------------------- 1 | #' Compute average color 2 | #' 3 | #' `mean_col()` computes an average color. 4 | #' 5 | #' We currently compute an average color 6 | #' by using the quadratic mean of the colors' RGBA values. 7 | #' 8 | #' @param ... Colors to average 9 | #' @return A color string of 9 characters: `"#"` followed by the 10 | #' red, blue, green, and alpha values in hexadecimal. 11 | #' @examples 12 | #' mean_col("black", "white") 13 | #' mean_col(c("black", "white")) 14 | #' mean_col("red", "blue") 15 | #' @export 16 | mean_col <- function(...) { 17 | cols <- unlist(list(...)) 18 | m <- grDevices::col2rgb(cols, alpha=TRUE) / 255.0 19 | # quadratic mean suggested at https://stackoverflow.com/a/29576746 20 | v <- apply(m, 1, quadratic_mean) 21 | grDevices::rgb(v[1], v[2], v[3], v[4]) 22 | } 23 | 24 | quadratic_mean <- function(x) sqrt(mean(x^2)) 25 | -------------------------------------------------------------------------------- /R/pattern-array-image.R: -------------------------------------------------------------------------------- 1 | #' Image patterned grobs 2 | #' 3 | #' `grid.pattern_image()` draws an image pattern onto the graphic device. 4 | #' 5 | #' Here is a description of the `type` arguments: 6 | #' \describe{ 7 | #' \item{expand}{Scale the image beyond the bounding box and crop it such that 8 | #' the image fully covers the width and the height of the region.} 9 | #' \item{fit}{Scale the image such that either the width or the height of the image fits in the bounding box. 10 | #' Affected by `gravity`} 11 | #' \item{none}{Position a single image in the region without attempting to scale to the bounding box size. 12 | #' Affected by `scale` and `gravity`.} 13 | #' \item{squish}{Distort the image to cover the bounding box of the region.} 14 | #' \item{tile}{Repeat the image to cover the bounding box. Affected by `tile`.} 15 | #' } 16 | #' 17 | #' @inheritParams grid.pattern_plasma 18 | #' @param filename Image of filename or URL 19 | #' @param type Image scaling type 20 | #' @param gravity Position of image within area. `magick::gravity_types()` returns a vector of supported values. 21 | #' @param filter Filter to use when scaling. `magick::filter_types()` returns a vector of supported values. 22 | #' @return A grid grob object invisibly. If `draw` is `TRUE` then also draws to the graphic device as a side effect. 23 | #' @examples 24 | #' \donttest{# May emit a "CPU time > 2.5 times elapsed time" NOTE in a CRAN check 25 | #' if (requireNamespace("magick")) { 26 | #' x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 27 | #' y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 28 | #' logo_filename <- system.file("img", "Rlogo.png" , package = "png") 29 | #' grid.pattern_image(x_hex, y_hex, filename = logo_filename, type = "fit") 30 | #' } 31 | #' if (requireNamespace("magick")) { 32 | #' # "tile" `type` image pattern depends on `magick` functionality 33 | #' # which is not reliable across platforms 34 | #' grid::grid.newpage() 35 | #' try(grid.pattern_image(x_hex, y_hex, filename = logo_filename, 36 | #' type = "tile")) 37 | #' } 38 | #' } 39 | #' @seealso [grid.pattern_placeholder()] is an image pattern that uses images 40 | #' downloaded from the internet. 41 | #' [reset_image_cache()] resets the image cache used by `grid.pattern_image()` 42 | #' and [grid.pattern_placeholder()]. 43 | #' @export 44 | grid.pattern_image <- function(x = c(0, 0, 1, 1), y = c(1, 0, 0, 1), id = 1L, ..., 45 | filename = "", type = "fit", scale = 1, 46 | gravity = switch(type, tile = "southwest", "center"), 47 | filter = "lanczos", 48 | alpha = gp$alpha %||% NA_real_, aspect_ratio = 1, key_scale_factor = 1, 49 | res = getOption("ggpattern_res", 72), 50 | default.units = "npc", name = NULL, gp = gpar(), draw = TRUE, vp = NULL) { 51 | grid.pattern("image", x, y, id, 52 | filename = filename, type = type, scale = scale, 53 | gravity = gravity, filter = filter, 54 | alpha = alpha, aspect_ratio = aspect_ratio, key_scale_factor = key_scale_factor, res = res, 55 | default.units = default.units, name = name, gp = gp , draw = draw, vp = vp) 56 | } 57 | 58 | #' Read a user specified filename/URL as an image 59 | #' 60 | #' @inheritParams create_gradient_as_array 61 | #' 62 | #' @return array 63 | #' 64 | #' @noRd 65 | img_read_as_array_wrapper <- function(width, height, params, legend) { 66 | 67 | assert_suggested("magick", "image") 68 | 69 | filename <- as.character(params$pattern_filename) 70 | 71 | fill_type <- tolower(as.character(params$pattern_type)) 72 | fill_type <- check_default(fill_type, options = fill_types) 73 | 74 | gravity <- tolower(as.character(params$pattern_gravity)) 75 | gravity <- check_default(gravity, tolower(magick::gravity_types()), 'center') 76 | 77 | filter <- tolower(as.character(params$pattern_filter)) 78 | filter <- check_default(filter, tolower(magick::filter_types()), 'lanczos') 79 | 80 | scale <- params$pattern_scale 81 | scale <- check_default(scale, default = 1, type = 'numeric') 82 | 83 | img_read_as_array( 84 | filename = filename, 85 | width = width, 86 | height = height, 87 | fill_type = fill_type, 88 | gravity = gravity, 89 | filter = filter, 90 | scale = scale 91 | ) 92 | } 93 | -------------------------------------------------------------------------------- /R/pattern-array-magick.R: -------------------------------------------------------------------------------- 1 | #' Magick patterned grobs 2 | #' 3 | #' `grid.pattern_magick()` draws a `imagemagick` pattern onto the graphic device. 4 | #' `names_magick`, `names_magick_intensity`, and 5 | #' `names_magick_stripe` are character vectors of supported `type` values 6 | #' plus subsets for shaded intensity and stripes. 7 | #' 8 | #' @inheritParams grid.pattern_image 9 | #' @param type Magick pattern types. `names_magick`, `names_magick_intensity`, and 10 | #' `names_magick_stripe` are character vectors of supported `type` values 11 | #' plus subsets for shaded intensity and stripes. 12 | #' @param fill Fill colour 13 | #' @return A grid grob object invisibly. If `draw` is `TRUE` then also draws to the graphic device as a side effect. 14 | #' @examples 15 | #' if (requireNamespace("magick")) { 16 | #' x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 17 | #' y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 18 | #' grid.pattern_magick(x_hex, y_hex, type="octagons", fill="blue", scale=2) 19 | #' } 20 | #' 21 | #' # supported magick pattern names 22 | #' print(names_magick) 23 | #' @seealso The `imagemagick` documentation for more information. 24 | #' @export 25 | grid.pattern_magick <- function(x = c(0, 0, 1, 1), y = c(1, 0, 0, 1), id = 1L, ..., 26 | type = "hexagons", fill = "grey20", scale = 1, filter = "box", 27 | alpha = gp$alpha %||% NA_real_, aspect_ratio = 1, key_scale_factor = 1, 28 | res = getOption("ggpattern_res", 72), 29 | default.units = "npc", name = NULL, gp = gpar(), draw = TRUE, vp = NULL) { 30 | grid.pattern("magick", x, y, id, 31 | type = type, fill = fill, scale = scale, scale = scale, filter = filter, 32 | alpha = alpha, aspect_ratio = aspect_ratio, 33 | key_scale_factor = key_scale_factor, res = res, 34 | default.units = default.units, name = name, gp = gp , draw = draw, vp = vp) 35 | } 36 | 37 | ## Names of patterns available in image magick, plus subsets for shaded intensity and stripes 38 | ## See \url{http://www.imagemagick.org/script/formats.php} for more information. 39 | 40 | #' @rdname grid.pattern_magick 41 | #' @export 42 | names_magick <- c( 43 | "bricks", "checkerboard", "circles", "crosshatch", "crosshatch30", 44 | "crosshatch45", "fishscales", "gray0", "gray5", "gray10", "gray15", 45 | "gray20", "gray25", "gray30", "gray35", "gray40", "gray45", "gray50", 46 | "gray55", "gray60", "gray65", "gray70", "gray75", "gray80", "gray85", 47 | "gray90", "gray95", "gray100", "hexagons", "horizontal", "horizontal2", 48 | "horizontal3", "horizontalsaw", "hs_bdiagonal", "hs_cross", "hs_diagcross", 49 | "hs_fdiagonal", "hs_horizontal", "hs_vertical", "left30", "left45", 50 | "leftshingle", "octagons", "right30", "right45", "rightshingle", 51 | "smallfishscales", "vertical", "vertical2", "vertical3", "verticalbricks", 52 | "verticalleftshingle", "verticalrightshingle", "verticalsaw" 53 | ) 54 | 55 | #' @rdname grid.pattern_magick 56 | #' @export 57 | names_magick_intensity <- c( 58 | "gray0", "gray5", "gray10", "gray15", 59 | "gray20", "gray25", "gray30", "gray35", "gray40", "gray45", "gray50", 60 | "gray55", "gray60", "gray65", "gray70", "gray75", "gray80", "gray85", 61 | "gray90", "gray95", "gray100" 62 | ) 63 | 64 | 65 | #' @rdname grid.pattern_magick 66 | #' @export 67 | names_magick_stripe <- c( 68 | "crosshatch", "crosshatch30", "crosshatch45", 69 | "horizontal", "horizontal2", "horizontal3", 70 | "hs_bdiagonal", "hs_cross", "hs_diagcross", 71 | "hs_fdiagonal", "hs_horizontal", "hs_vertical", "left30", "left45", 72 | "right30", "right45", 73 | "vertical", "vertical2", "vertical3" 74 | ) 75 | 76 | #' Read a user specified filename as an image 77 | #' 78 | #' @inheritParams create_gradient_as_array 79 | #' 80 | #' @return array 81 | #' 82 | #' @noRd 83 | create_magick_pattern_as_array <- function(width, height, params, legend) { 84 | 85 | assert_suggested("magick", "magick") 86 | 87 | if (legend) { 88 | params$pattern_scale <- params$pattern_scale * params$pattern_key_scale_factor 89 | } 90 | type <- check_default(as.character(params$pattern_type), 91 | options = names_magick, 92 | default = 'hexagons') 93 | 94 | scale <- check_default(params$pattern_scale, default = 1, type = 'numeric') 95 | 96 | filter <- tolower(as.character(params$pattern_filter)) 97 | filter <- check_default(filter, options = tolower(magick::filter_types()), default = 'box') 98 | 99 | colour <- as.character(params$pattern_fill) 100 | 101 | img <- create_magick_pattern_img_scaled( 102 | width = width, 103 | height = height, 104 | type = type, 105 | colour = colour, 106 | scale = scale, 107 | filter = filter 108 | ) 109 | 110 | convert_img_to_array(img) 111 | } 112 | -------------------------------------------------------------------------------- /R/pattern-array-plasma.R: -------------------------------------------------------------------------------- 1 | #' Plasma patterned grobs 2 | #' 3 | #' `grid.pattern_plasma()` draws a plasma pattern onto the graphic device. 4 | #' 5 | #' @inheritParams grid.pattern_gradient 6 | #' @param scale Extra scaling 7 | #' @return A grid grob object invisibly. If `draw` is `TRUE` then also draws to the graphic device as a side effect. 8 | #' @examples 9 | #' if (requireNamespace("magick")) { 10 | #' x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 11 | #' y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 12 | #' grid.pattern_plasma(x_hex, y_hex, fill = "green") 13 | #' } 14 | #' @seealso [grid.pattern_ambient()] provides a noise pattern using the `ambient` package. 15 | #' Pseudorandom seeds for the plasma pattern may be set via [magick::magick_set_seed()]. 16 | #' @export 17 | grid.pattern_plasma <- function(x = c(0, 0, 1, 1), y = c(1, 0, 0, 1), id = 1L, ..., 18 | fill = gp$fill %||% "grey80", scale = 1, alpha = gp$alpha %||% NA_real_, 19 | aspect_ratio = 1, key_scale_factor = 1, 20 | res = getOption("ggpattern_res", 72), 21 | default.units = "npc", name = NULL, gp = gpar(), draw = TRUE, vp = NULL) { 22 | grid.pattern("plasma", x, y, id, 23 | fill = fill, scale = scale, alpha = alpha, 24 | aspect_ratio = aspect_ratio, key_scale_factor = key_scale_factor, res = res, 25 | default.units = default.units, name = name, gp = gp , draw = draw, vp = vp) 26 | } 27 | 28 | #' Read a user specified filename as an image 29 | #' 30 | #' @inheritParams create_gradient_as_array 31 | #' 32 | #' @return array 33 | #' @noRd 34 | create_magick_plasma_as_array <- function(width, height, params, legend) { 35 | 36 | assert_suggested("magick", "plasma") 37 | 38 | colour <- as.character(params$pattern_fill) 39 | 40 | img <- create_magick_plasma_img( 41 | width = width, 42 | height = height, 43 | colour = colour 44 | ) 45 | 46 | convert_img_to_array(img) 47 | } 48 | 49 | #' Create plasma using imagemagick 50 | #' 51 | #' Ref: \url{https://www.imagemagick.org/Usage/canvas/} 52 | #' 53 | #' @param width,height image dimensions 54 | #' @param colour colour 55 | #' 56 | #' @noRd 57 | create_magick_plasma_img <- function(width=100, height=100, colour) { 58 | 59 | colour <- convert_r_colour_to_magick_colour(colour) 60 | 61 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 62 | # Create a pattern image of the required size 63 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 64 | pseudo <- "plasma:" 65 | img <- magick::image_blank(width, height, pseudo_image = pseudo) 66 | img <- magick::image_convert(img, colorspace = 'gray', depth = 8) 67 | img <- magick::image_blur(img, radius = 2) 68 | 69 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 70 | # Make the white transparent 71 | # Colorize the black pixels into the desired colour 72 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 73 | img <- magick::image_transparent(img, 'white') 74 | img <- magick::image_colorize(img, opacity = 50, colour) 75 | 76 | img 77 | } 78 | -------------------------------------------------------------------------------- /R/pattern-geometry-circle.R: -------------------------------------------------------------------------------- 1 | #' Circle patterned grobs 2 | #' 3 | #' `grid.pattern_circle()` draws a circle pattern onto the graphic device. 4 | #' 5 | #' @inheritParams grid.pattern 6 | #' @param ... Currently ignored. 7 | #' @param colour Stroke colour(s). 8 | #' @param fill Fill colour(s) or [grid::pattern()] / gradient object(s). 9 | #' @param angle Rotation angle in degrees. 10 | #' @param density Approx. fraction of area the pattern fills. 11 | #' @param spacing Spacing between repetitions of pattern (in `units` units). 12 | #' @param xoffset Shift pattern along x axis (in `units` units). 13 | #' @param yoffset Shift pattern along y axis (in `units` units). 14 | #' @param units [grid::unit()] units for `spacing`, `xoffset`, and `yoffset` parameters. 15 | #' @param alpha Alpha (between 0 and 1) or `NA` (default, preserves colors' alpha value). 16 | #' @param linetype Stroke linetype. 17 | #' @param linewidth Stroke linewidth. 18 | #' @param size For backwards compatibility can be used to set `linewidth`. 19 | #' @param grid Adjusts placement and density of certain graphical elements. 20 | #' `"square"` (default) is a square grid. 21 | #' `"hex"` is a hexagonal grid suitable for hexagonal and triangular tiling. 22 | #' `"hex_circle"` is a hexagonal grid suitable for circle packing. 23 | #' `"elongated_triangle"` is a grid used for the "elongated triangle" tiling. 24 | #' @param type Adjusts the repeating of certain aesthetics such as color. 25 | #' Can use any type in `names_hex`, `names_square`, or `names_weave`. 26 | #' See for [pattern_hex()], [pattern_square()], and [pattern_weave()] for 27 | #' more information about supported `type` arguments. 28 | #' @param subtype See for [pattern_hex()], [pattern_square()], and [pattern_weave()] for 29 | #' more information about supported `subtype` arguments. 30 | #' @return A grid grob object invisibly. If `draw` is `TRUE` then also draws to the graphic device as a side effect. 31 | #' @examples 32 | #' x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 33 | #' y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 34 | #' grid.pattern_circle(x_hex, y_hex, fill = c("blue", "yellow"), density = 0.5) 35 | #' grid::grid.newpage() 36 | #' grid.pattern_circle(x_hex, y_hex, density = 0.8, grid = "hex_circle", 37 | #' gp = grid::gpar(fill = c("blue", "yellow", "red"))) 38 | #' grid::grid.newpage() 39 | #' grid.pattern_circle(x_hex, y_hex, density = 1.2, grid = "hex_circle", 40 | #' gp = grid::gpar(fill = c("blue", "yellow", "red"))) 41 | #' # using a "twill_zigzag" 'weave' pattern 42 | #' grid::grid.newpage() 43 | #' grid.pattern_circle(x_hex, y_hex, fill = "blue", density = 0.5, type = "twill_zigzag") 44 | #' @seealso 45 | #' See [grid.pattern_regular_polygon()] for a more general case of this pattern. 46 | #' @export 47 | grid.pattern_circle <- function(x = c(0, 0, 1, 1), y = c(1, 0, 0, 1), id = 1L, ..., 48 | colour = gp$col %||% "grey20", fill = gp$fill %||% "grey80", angle = 30, 49 | density = 0.2, spacing = 0.05, xoffset = 0, yoffset = 0, units = "snpc", 50 | alpha = gp$alpha %||% NA_real_, 51 | linetype = gp$lty %||% 1, 52 | linewidth = size %||% gp$lwd %||% 1, 53 | size = NULL, 54 | grid = "square", type = NULL, subtype = NULL, 55 | default.units = "npc", name = NULL, gp = gpar(), draw = TRUE, vp = NULL) { 56 | if (missing(colour) && hasName(l <- list(...), "color")) colour <- l$color 57 | grid.pattern("circle", x, y, id, 58 | colour = colour, fill = fill, angle = angle, 59 | density = density, spacing = spacing, xoffset = xoffset, yoffset = yoffset, units = units, 60 | alpha = alpha, linetype = linetype, linewidth = linewidth, 61 | grid = grid, type = type, subtype = subtype, 62 | default.units = default.units, name = name, gp = gp , draw = draw, vp = vp) 63 | } 64 | 65 | create_pattern_circle_via_sf <- function(params, boundary_df, aspect_ratio, legend = FALSE) { 66 | params$pattern_shape <- "circle" 67 | grob <- create_pattern_regular_polygon_via_sf(params, boundary_df, aspect_ratio, legend = legend) 68 | grob <- editGrob(grob, name = "circle") 69 | grob 70 | } 71 | -------------------------------------------------------------------------------- /R/pattern-geometry-fill.R: -------------------------------------------------------------------------------- 1 | #' Create grob objects for the pattern elements within a boundary 2 | #' 3 | #' @param params params/coords for a single element. named list or single row data.frame 4 | #' @param boundary_df mask for the pattern rendering 5 | #' @param aspect_ratio a aspect ratio of the plotting area. 6 | #' @param legend is the pattern being created in the legend? default FALSE. 7 | #' Use this flag if you want different pattern drawing behviour for the legend. 8 | #' 9 | #' @return grid grob objects. 10 | #' @noRd 11 | create_pattern_fill <- function(params, boundary_df, aspect_ratio, 12 | legend = FALSE) { 13 | alpha <- ifelse(is.na(params$pattern_alpha), 1, params$pattern_alpha) 14 | fill <- update_alpha(params$pattern_fill, alpha) 15 | gp <- grid::gpar(col = NA_character_, fill = fill) 16 | 17 | convert_polygon_df_to_polygon_grob(boundary_df, gp = gp) 18 | } 19 | 20 | #' Grobs with a simple fill pattern 21 | #' 22 | #' `grid.pattern_fill()` draws a simple fill pattern onto the graphics device. 23 | #' 24 | #' @inheritParams grid.pattern_circle 25 | #' @param ... Currently ignored 26 | #' @return A grid grob object invisibly. If `draw` is `TRUE` then also draws to the graphic device as a side effect. 27 | #' @examples 28 | #' x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 29 | #' y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 30 | #' grid.pattern_fill(x_hex, y_hex, fill = "blue") 31 | #' 32 | #' if (guess_has_R4.1_features("patterns")) { 33 | #' grid::grid.newpage() 34 | #' stripe_fill <- patternFill("stripe", fill = c("red", "blue")) 35 | #' grid.pattern_fill(x_hex, y_hex, fill = stripe_fill) 36 | #' } 37 | #' @seealso [grid::grid.polygon()] 38 | #' @export 39 | grid.pattern_fill <- function(x = c(0, 0, 1, 1), y = c(1, 0, 0, 1), id = 1L, ..., 40 | fill = gp$fill %||% "grey80", 41 | alpha = gp$alpha %||% NA_real_, 42 | default.units = "npc", name = NULL, gp = gpar(), draw = TRUE, vp = NULL) { 43 | grid.pattern("fill", x, y, id, 44 | fill = fill, alpha = alpha, 45 | default.units = default.units, name = name, gp = gp , draw = draw, vp = vp) 46 | } 47 | -------------------------------------------------------------------------------- /R/pattern-geometry-none.R: -------------------------------------------------------------------------------- 1 | #' Create grob objects for the pattern elements within a boundary 2 | #' 3 | #' @param params params/coords for a single element. named list or single row data.frame 4 | #' @param boundary_df mask for the pattern rendering 5 | #' @param aspect_ratio a aspect ratio of the plotting area. 6 | #' @param legend is the pattern being created in the legend? default FALSE. 7 | #' Use this flag if you want different pattern drawing behviour for the legend. 8 | #' 9 | #' @return grid grob objects. 10 | #' @noRd 11 | create_pattern_none <- function(params, boundary_df, aspect_ratio, 12 | legend = FALSE) { 13 | grid::nullGrob() 14 | } 15 | 16 | #' Grobs without any pattern 17 | #' 18 | #' `grid.pattern_none()` draws nothing onto the graphic device. 19 | #' 20 | #' @inheritParams grid.pattern 21 | #' @param ... Currently ignored 22 | #' @return A grid grob object invisibly. If `draw` is `TRUE` then also draws to the graphic device as a side effect. 23 | #' @examples 24 | #' x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 25 | #' y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 26 | #' grid.pattern_none(x_hex, y_hex) 27 | #' @seealso [grid::grid.null()] 28 | #' @export 29 | grid.pattern_none <- function(x = c(0, 0, 1, 1), y = c(1, 0, 0, 1), id = 1L, ..., 30 | default.units = "npc", name = NULL, gp = gpar(), draw = TRUE, vp = NULL) { 31 | grid.pattern("none", x, y, id, 32 | default.units = default.units, name = name, gp = gp , draw = draw, vp = vp) 33 | } 34 | -------------------------------------------------------------------------------- /R/pattern-geometry-stripe.R: -------------------------------------------------------------------------------- 1 | #' Stripe patterned grobs 2 | #' 3 | #' `grid.pattern_stripe()` draws a stripe pattern onto the graphic device. 4 | #' 5 | #' @inheritParams grid.pattern_circle 6 | #' @return A grid grob object invisibly. If `draw` is `TRUE` then also draws to the graphic device as a side effect. 7 | #' @examples 8 | #' x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 9 | #' y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 10 | #' grid.pattern_stripe(x_hex, y_hex, colour = "black", 11 | #' fill = c("red", "blue"), density = 0.4) 12 | #' 13 | #' # Can alternatively use "gpar()" to specify colour and line attributes 14 | #' grid::grid.newpage() 15 | #' grid.pattern_stripe(x_hex, y_hex, density = 0.3, 16 | #' gp = grid::gpar(col = "blue", fill = "yellow")) 17 | #' @seealso `[grid.pattern_crosshatch()]` and `[grid.pattern_weave()]` for overlaying stripes. 18 | #' @export 19 | grid.pattern_stripe <- function(x = c(0, 0, 1, 1), y = c(1, 0, 0, 1), id = 1L, ..., 20 | colour = gp$col %||% "grey20", fill = gp$fill %||% "grey80", angle = 30, 21 | density = 0.2, spacing = 0.05, xoffset = 0, yoffset = 0, units = "snpc", 22 | alpha = gp$alpha %||% NA_real_, 23 | linetype = gp$lty %||% 1, 24 | linewidth = size %||% gp$lwd %||% 1, 25 | size = NULL, 26 | grid = "square", 27 | default.units = "npc", name = NULL, gp = gpar(), draw = TRUE, vp = NULL) { 28 | if (missing(colour) && hasName(l <- list(...), "color")) colour <- l$color 29 | grid.pattern("stripe", x, y, id, 30 | colour = colour, fill = fill, angle = angle, 31 | density = density, spacing = spacing, xoffset = xoffset, yoffset = yoffset, units = units, 32 | alpha = alpha, linetype = linetype, linewidth = linewidth, 33 | grid = grid, 34 | default.units = default.units, name = name, gp = gp , draw = draw, vp = vp) 35 | } 36 | 37 | create_pattern_stripes_via_sf <- function(params, boundary_df, aspect_ratio, 38 | legend = FALSE) { 39 | create_crosshatch_via_sf_helper(params, boundary_df, add_top_hatch = FALSE) 40 | } 41 | -------------------------------------------------------------------------------- /R/pattern-pattern-aRtsy.R: -------------------------------------------------------------------------------- 1 | #' Create grob objects for the pattern elements within a boundary 2 | #' 3 | #' @param params params/coords for a single element. named list or single row data.frame 4 | #' @param boundary_df mask for the pattern rendering 5 | #' @param aspect_ratio a aspect ratio of the plotting area. 6 | #' @param legend is the pattern being created in the legend? default FALSE. 7 | #' Use this flag if you want different pattern drawing behviour for the legend. 8 | #' 9 | #' @return grid grob objects. 10 | #' @noRd 11 | create_pattern_aRtsy <- function(params, boundary_df, aspect_ratio, 12 | legend = FALSE) { 13 | assert_suggested("aRtsy", "aRtsy") 14 | requireNamespace("aRtsy", quietly = TRUE) 15 | stopifnot(guess_has_R4.1_features("patterns")) 16 | alpha <- ifelse(is.na(params$pattern_alpha), 1, params$pattern_alpha) 17 | colors <- update_alpha(params$pattern_fill, alpha) 18 | fn_name <- paste0("canvas_", params$pattern_type) 19 | fn <- utils::getFromNamespace(fn_name, "aRtsy") 20 | args <- list() 21 | nformals <- names(formals(fn)) 22 | if ("color" %in% nformals) { # e.g. `canvas_maze()` 23 | args$color <- colors 24 | } 25 | if ("colors" %in% nformals) { # e.g. most canvas functions 26 | args$colors <- colors 27 | } 28 | pat <- ggplot2pat(do.call(fn, args)) 29 | gp <- grid::gpar(col = NA_character_, fill = pat) 30 | convert_polygon_df_to_polygon_grob(boundary_df, gp = gp) 31 | } 32 | 33 | #' Grobs with patterns powered by the aRtsy package 34 | #' 35 | #' `grid.pattern_aRtsy()` draws patterns powered by the `aRtsy` package. 36 | #' `names_aRtsy()` returns character vector of supported types. 37 | #' 38 | #' @param type Name of pattern. 39 | #' @inheritParams grid.pattern_circle 40 | #' @param fill Passed to the underlying `aRtsy` function's `color` / `colors` argument. 41 | #' @param ... Currently ignored 42 | #' @return A grid grob object invisibly. If `draw` is `TRUE` then also draws to the graphic device as a side effect. 43 | #' @examples 44 | #' if (requireNamespace("aRtsy", quietly = TRUE)) { 45 | #' print(names_aRtsy()) 46 | #' } 47 | #' 48 | #' \donttest{# Make take more than 5 seconds on CRAN servers 49 | #' x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 50 | #' y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 51 | #' if (requireNamespace("aRtsy", quietly = TRUE) && 52 | #' guess_has_R4.1_features("patterns")) { 53 | #' grid::grid.newpage() 54 | #' grid.pattern_aRtsy(x_hex, y_hex, type = "forest", 55 | #' fill = c("black", "white", "grey")) 56 | #' } 57 | #' } 58 | #' @seealso for more information about the `aRtsy` package. 59 | #' @export 60 | grid.pattern_aRtsy <- function(x = c(0, 0, 1, 1), y = c(1, 0, 0, 1), id = 1L, ..., 61 | type = "strokes", 62 | fill = gp$fill %||% "grey80", 63 | alpha = gp$alpha %||% NA_real_, 64 | default.units = "npc", name = NULL, gp = gpar(), draw = TRUE, vp = NULL) { 65 | grid.pattern("aRtsy", x, y, id, 66 | type = type, fill = fill, alpha = alpha, 67 | default.units = default.units, name = name, gp = gp , draw = draw, vp = vp) 68 | } 69 | 70 | #' @rdname grid.pattern_aRtsy 71 | #' @export 72 | names_aRtsy <- function() { 73 | assert_suggested("aRtsy", "aRtsy") 74 | requireNamespace("aRtsy", quietly = TRUE) 75 | fns <- grep("^canvas", getNamespaceExports("aRtsy"), value = TRUE) 76 | gsub("^canvas_", "", fns) 77 | } 78 | -------------------------------------------------------------------------------- /R/reset_image_cache.R: -------------------------------------------------------------------------------- 1 | #' Reset 'gridpattern' image cache 2 | #' 3 | #' [grid.pattern_image()] and [grid.pattern_placeholder()] store images in a cache 4 | #' (so we won't download image URLs over and over). 5 | #' `reset_image_cache()` resets this cache. 6 | #' @export 7 | reset_image_cache <- function() { 8 | memoise::forget(img_read_memoised) 9 | } 10 | -------------------------------------------------------------------------------- /R/standalone-update_alpha.R: -------------------------------------------------------------------------------- 1 | # --- 2 | # repo: trevorld/gridpattern 3 | # file: standalone-update_alpha.R 4 | # last-updated: 2024-04-18 5 | # license: https://spdx.org/licenses/MIT.html 6 | # imports: [grDevices, grid, rlang] 7 | # --- 8 | # 9 | # nocov start 10 | # 11 | # You may copy this source into your own R package 12 | # by either using `usethis::use_standalone("trevorld/gridpattern", "standalone-update_alpha.R")` 13 | # or simply copying this file into your `R` directory and adding `grDevices`, `grid`, and `rlang` to 14 | # the `Imports` of your `DESCRIPTION` file. 15 | 16 | # The MIT License (MIT) 17 | # ===================== 18 | # 19 | # Copyright © 2024 Trevor L. Davis 20 | # Copyright © 2020 mikefc@coolbutuseless.com 21 | # Copyright © 2023 ggplot2 authors 22 | # 23 | # Permission is hereby granted, free of charge, to any person 24 | # obtaining a copy of this software and associated documentation 25 | # files (the “Software”), to deal in the Software without 26 | # restriction, including without limitation the rights to use, 27 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 28 | # copies of the Software, and to permit persons to whom the 29 | # Software is furnished to do so, subject to the following 30 | # conditions: 31 | # 32 | # The above copyright notice and this permission notice shall be 33 | # included in all copies or substantial portions of the Software. 34 | # 35 | # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 36 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 37 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 38 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 39 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 40 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 41 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 42 | # OTHER DEALINGS IN THE SOFTWARE. 43 | 44 | # Pattern utilities mainly added to ggplot2 by Teun van den Brand 45 | # Tweaked by Trevor L. Davis to remove external dependencies 46 | # and work better for {ggpattern} / {gridpattern} use cases. 47 | update_alpha <- function(fill, alpha) { 48 | if (!is.list(fill)) { 49 | # Happy path of no patterns 50 | update_alpha_col(fill, alpha) 51 | } else if (is_pattern(fill) || any(vapply(fill, is_pattern, logical(1)))) { 52 | # Path with patterns 53 | update_pattern_alpha(fill, alpha) 54 | } else if (is.list(fill) && length(fill) == 1L && !any(vapply(fill, is_pattern, logical(1)))) { 55 | # List of length one of (possibly multiple) colours 56 | update_alpha_col(fill[[1L]], alpha) 57 | } else { 58 | # We are either dealing with faulty fill specification 59 | stop("`fill` must be a vector of colours or list of objects.") 60 | } 61 | } 62 | 63 | # Similar to grid:::is.pattern 64 | is_pattern <- function(x) { 65 | inherits(x, "GridPattern") 66 | } 67 | 68 | # replacement for `scales::alpha()` that only depends on {grDevices} 69 | update_alpha_col <- function(colour, alpha = NA_real_) { 70 | n <- max(lengths(list(colour, alpha))) 71 | colour <- rep_len(colour, n) 72 | alpha <- rep_len(alpha, n) 73 | m <- grDevices::col2rgb(colour, alpha = TRUE) / 255.0 74 | m[4, ] <- ifelse(is.na(alpha), m[4, ], alpha) 75 | apply(m, 2, function(x) grDevices::rgb(x[1], x[2], x[3], x[4])) 76 | } 77 | 78 | #' Modify transparency for patterns 79 | #' 80 | #' This generic allows you to add your own methods for adding transparency to 81 | #' pattern-like objects. 82 | #' 83 | #' @param x Object to be interpreted as pattern. 84 | #' @param alpha A `numeric` vector between 0 and 1. If `NA`, alpha values 85 | #' are preserved. 86 | #' 87 | #' @return `x` with modified transparency 88 | #' @noRd 89 | update_pattern_alpha <- function(x, alpha, ...) { 90 | UseMethod("update_pattern_alpha") 91 | } 92 | 93 | #' @export 94 | update_pattern_alpha.default <- function(x, alpha, ..., name = NULL) { 95 | if (!is.atomic(x)) { 96 | stop("Can't apply `update_pattern_alpha()` to this object.") 97 | } 98 | grid::pattern(grid::rectGrob(name = name), 99 | gp = grid::gpar(fill = update_alpha_col(x, alpha))) 100 | } 101 | 102 | #' @export 103 | update_pattern_alpha.GridPattern <- function(x, alpha, ...) { 104 | x$colours <- update_alpha_col(x$colours, alpha[1]) 105 | x 106 | } 107 | 108 | #' @export 109 | update_pattern_alpha.GridTilingPattern <- function(x, alpha, ...) { 110 | if (all(is.na(alpha) | alpha == 1)) { 111 | return(x) 112 | } 113 | grob <- rlang::env_get(environment(x$f), "grob") 114 | gp <- grid::gpar(fill = update_alpha_col("white", alpha)) 115 | mask <- grid::as.mask(grid::rectGrob(gp = gp)) 116 | if (is.null(grob$vp)) { 117 | grob$vp <- grid::viewport(mask = mask) 118 | } else { 119 | grob$vp <- grid::editViewport(grob$vp, mask = mask) 120 | } 121 | new_env <- new.env(parent = environment(x$f)) 122 | rlang::env_bind(new_env, grob = grob) 123 | environment(x$f) <- new_env 124 | x 125 | } 126 | 127 | #' @export 128 | update_pattern_alpha.list <- function(x, alpha, ...) { 129 | Map(update_pattern_alpha, x = x, alpha = alpha) 130 | } 131 | 132 | # nocov end 133 | -------------------------------------------------------------------------------- /R/star_scale.R: -------------------------------------------------------------------------------- 1 | #' Compute regular star polygon scale or angles 2 | #' 3 | #' `star_scale()` computes star `scale` value given 4 | #' an internal or external angle. `star_angle()` computes 5 | #' star angle (internal or external) given a `scale` value. 6 | #' 7 | #' [grid.pattern_regular_polygon()] parameterizes regular star polygons 8 | #' with the number of its external vertices and a `scale` that equals the 9 | #' fraction of the radius of the circle that circumscribes the interior vertices 10 | #' divided by the radius of the circle that circumscribes the exterior vertices. 11 | #' These helper functions help convert between that parameterization 12 | #' and either the internal or external angle of the regular star polygon. 13 | #' @param n_vertices Number of exterior vertices. 14 | #' @param angle Angle in degrees. 15 | #' @param scale Scale from 0 to 1. 16 | #' @param external If `TRUE` angle should be considered an external angle. 17 | #' @return `star_scale()` returns a numeric value between 0 and 1 intended 18 | #' for use as the `scale` argument in [grid.pattern_regular_polygon()]. 19 | #' `star_angle()` returns a numeric value between 0 and 360 (degrees). 20 | #' @examples 21 | #' # |8/3| star has internal angle 45 degrees and external angle 90 degrees 22 | #' scale <- star_scale(8, 45) 23 | #' scale2 <- star_scale(8, 90, external = TRUE) 24 | #' all.equal(scale, scale2) 25 | #' star_angle(8, scale) 26 | #' star_angle(8, scale, external = TRUE) 27 | #' 28 | #' grid.pattern_regular_polygon(shape = "star8", scale = scale, angle = 0, 29 | #' spacing = 0.2, density = 0.8) 30 | #' @export 31 | star_scale <- function(n_vertices, angle, external = FALSE) { 32 | if (external) 33 | angle <- external_to_internal(n_vertices, angle) 34 | if (n_vertices == 2) 35 | return(star_scale2(angle)) 36 | stopifnot(angle >= 0, angle <= 180 * (1 - 2/n_vertices)) 37 | # we'll work with external degree 38 | angle <- internal_to_external(n_vertices, angle) 39 | t <- 360 / n_vertices 40 | xy1 <- list(x = 1, y = 0) 41 | xy2 <- list(x = to_x(t, 1), y = to_y(t, 1)) 42 | xyc <- list(x = mean(c(xy1$x, xy2$x)), y = mean(c(xy1$y, xy2$y))) 43 | xyf <- list(x = to_x(t/2, 1), y = to_y(t/2, 1)) 44 | dist_f <- dist(xyf, xyc) 45 | a2 <- dist(xy1, xyc) 46 | beta <- (180 - angle) / 2 47 | b <- a2 * sin(to_radians(beta)) / sin(to_radians(angle/2)) 48 | r <- 1 - b - dist_f 49 | stopifnot(r >= 0) 50 | r 51 | } 52 | 53 | star_scale2 <- function(angle) { 54 | stopifnot(angle >= 0, angle <= 90) 55 | a1 <- angle / 2 56 | a2 <- 180 - 90 - a1 57 | r <- sin(to_radians(a1)) / sin(to_radians(a2)) 58 | stopifnot(r >= 0) 59 | r 60 | } 61 | 62 | #' @rdname star_scale 63 | #' @export 64 | star_angle <- function(n_vertices, scale, external = FALSE) { 65 | stopifnot(scale >= 0, scale <= 1) 66 | if (n_vertices == 2) 67 | return(star_angle2(scale, external)) 68 | t <- 360 / n_vertices 69 | xy1 <- list(x = 1, y = 0) 70 | xy2 <- list(x = to_x(t, 1), y = to_y(t, 1)) 71 | xyv <- list(x = to_x(t/2, scale), y = to_y(t/2, scale)) 72 | xyc <- list(x = mean(c(xy1$x, xy2$x)), y = mean(c(xy1$y, xy2$y))) 73 | a2 <- dist(xy1, xyc) 74 | c <- dist(xyv, xy1) 75 | d <- to_degrees(2 * asin(a2 / c)) 76 | if (!external) 77 | d <- external_to_internal(n_vertices, d) 78 | d 79 | } 80 | 81 | star_angle2 <- function(scale, external = FALSE) { 82 | d <- sqrt(1 + scale^2) 83 | d <- 2 * to_degrees(asin(scale / d)) 84 | if (external) 85 | d <- internal_to_external(2, d) 86 | d 87 | } 88 | 89 | external_to_internal <- function(n_vertices, external) { 90 | n <- 2 * n_vertices # exterior plus interior vertices 91 | total <- (n - 2) * 180 92 | inverse <- 360 - external 93 | internal <- (total - n_vertices * inverse) / n_vertices 94 | internal 95 | } 96 | 97 | internal_to_external <- function(n_vertices, internal) { 98 | n <- 2 * n_vertices # exterior plus interior vertices 99 | total <- (n - 2) * 180 100 | inverse <- (total - n_vertices * internal) / n_vertices 101 | external <- 360 - inverse 102 | external 103 | } 104 | 105 | dist <- function(p1, p2) sqrt((p2$x - p1$x)^2 + (p2$y - p1$y)^2) 106 | -------------------------------------------------------------------------------- /R/utils-geometry.R: -------------------------------------------------------------------------------- 1 | # radians <-> degrees 2 | to_radians <- function(t) pi * t / 180 3 | to_degrees <- function(t) 180 * t / pi 4 | 5 | # polar coordinates <-> cartesian coordinates 6 | to_x <- function(t, r) { 7 | r * cos(to_radians(t)) 8 | } 9 | to_y <- function(t, r) { 10 | r * sin(to_radians(t)) 11 | } 12 | to_theta <- function(x, y) { 13 | to_degrees(atan2(y, x)) 14 | } 15 | to_radius <- function(x, y) { 16 | sqrt(x^2 + y^2) 17 | } 18 | 19 | # rotate (x,y) `t` degrees centered around (x0, y0) 20 | rotate_xy <- function(x, y, theta = 0, x0 = NULL, y0 = NULL) { 21 | x0 <- x0 %||% mean(x) 22 | y0 <- y0 %||% mean(y) 23 | xc <- x - x0 24 | yc <- y - y0 25 | theta <- to_theta(xc, yc) + theta 26 | radius <- to_radius(xc, yc) 27 | x1 <- to_x(theta, radius) + x0 28 | y1 <- to_y(theta, radius) + y0 29 | list(x = x1, y = y1) 30 | } 31 | 32 | # (x,y) coordinates of convex regular polygon centered at (0, 0) 33 | convex_xy <- function(n_vertices, theta = 90, radius_outer = 0.5) { 34 | t <- theta + seq(0, 360, length.out = n_vertices + 1) 35 | x <- to_x(t, radius_outer) 36 | y <- to_y(t, radius_outer) 37 | list(x = head(x, -1), 38 | y = head(y, -1)) 39 | } 40 | 41 | # (x,y)coordinates of rhombus quadrilateral 42 | rhombus_xy <- function(theta = 90, radius_outer = 0.5) { 43 | t <- theta + c(0, -60, 0, 60) 44 | r <- c(0, rep(radius_outer, 3)) 45 | x <- to_x(t, r) 46 | y <- to_y(t, r) 47 | list(x = x, y = y) 48 | } 49 | 50 | # (x,y) coordinates of "left" Tetrakis triangle 51 | tetrakis_left_xy <- function(theta = 90, radius_outer = 0.5) { 52 | t <- c(90, 135) 53 | r <- c(1e-6, radius_outer) 54 | 55 | x <- to_x(t, r) 56 | y <- to_y(t, r) 57 | x <- c(x, x[1]) 58 | y <- c(y, y[2]) 59 | rotate_xy(x, y, theta - 135, 0, 0) 60 | } 61 | 62 | # (x,y) coordinates of "right" Tetrakis triangle 63 | tetrakis_right_xy <- function(theta = 90, radius_outer = 0.5) { 64 | t <- c(90, 45) 65 | r <- c(1e-6, radius_outer) 66 | 67 | x <- to_x(t, r) 68 | y <- to_y(t, r) 69 | x <- c(x, x[1]) 70 | y <- c(y, y[2]) 71 | rotate_xy(x, y, theta - 135, 0, 0) 72 | } 73 | 74 | # (x,y) coordinates of concave (star) regular polygon centered at (0, 0) 75 | concave_xy <- function(n_vertices, theta = 90, radius_outer = 0.5, 76 | radius_inner = 0.5 * radius_outer) { 77 | t_outer <- theta + seq(0, 360, length.out = n_vertices + 1) 78 | n_degrees <- 360 / n_vertices / 2 79 | t_inner <- theta + seq(n_degrees, 360 - n_degrees, length.out = n_vertices) 80 | x_outer <- to_x(t_outer, radius_outer) 81 | x_inner <- to_x(t_inner, radius_inner) 82 | y_outer <- to_y(t_outer, radius_outer) 83 | y_inner <- to_y(t_inner, radius_inner) 84 | x <- splice(x_outer, x_inner) 85 | y <- splice(y_outer, y_inner) 86 | list(x = head(x, -1), 87 | y = head(y, -1)) 88 | } 89 | 90 | splice <- function(x0, x1) { 91 | vec <- as.numeric() 92 | for (ii in seq_along(x1)) { 93 | vec <- append(vec, x0[ii]) 94 | vec <- append(vec, x1[ii]) 95 | } 96 | append(vec, x0[ii+1]) 97 | } 98 | 99 | get_n_vertices <- function(shape) { 100 | as.numeric(gsub("convex|concave|star", "", shape)) 101 | } 102 | 103 | # returns numeric(0) if 'from' greater than 'to' 104 | seq_robust <- function(from = 1, to = 1, by = ((to - from)/(length.out - 1)), length.out = NULL) { 105 | if (from > to) { 106 | numeric(0) 107 | } else { 108 | if (is.null(length.out)) 109 | seq(from, to, by) 110 | else 111 | seq(from, to, by, length.out) 112 | } 113 | } 114 | 115 | # cycle_elements(1:5, -2) = c(4, 5, 1, 2, 3) 116 | # cycle_elements(1:5, -1) = c(5, 1, 2, 3, 4) 117 | # cycle_elements(1:5, 0) = c(1, 2, 3, 4, 5) 118 | # cycle_elements(1:5, 1) = c(2, 3, 4, 5, 1) 119 | # cycle_elements(1:5, 2) = c(3, 4, 5, 1, 2) 120 | cycle_elements <- function(x, n = 1) { 121 | l <- length(x) 122 | if (l < 2 || n == l || n == 0 || n == -l) 123 | return(x) 124 | if (n > 0) { 125 | if (n < l) { 126 | c(x[(n+1):l], x[1:n]) 127 | } else { 128 | cycle_elements(x, n-l) 129 | } 130 | } else { 131 | if (-l < n) { 132 | c(x[(l+n+1):l], x[1:(l+n)]) 133 | } else { 134 | cycle_elements(x, n+l) 135 | } 136 | } 137 | } 138 | 139 | nigh <- function(x, y) abs(x - y) < .Machine$double.eps^0.5 140 | -------------------------------------------------------------------------------- /R/utils-ggpattern.R: -------------------------------------------------------------------------------- 1 | #' Sanity check an argument value 2 | #' 3 | #' This is a milder, more explicit version of \code{match.arg} which gives a warning 4 | #' and returns a good default. match.arg() would throw errors which makes 5 | #' geom/pattern development a bit trickier. 6 | #' 7 | #' @param x argument value 8 | #' @param options valid options this value could take. If this is not NULL, then 9 | #' x is checked to be a member of this set. Default: NULL. 10 | #' @param default the default value to use if the argument fails the checks. 11 | #' If default is not NULL, then use it as the fallback value. 12 | #' If default is NULL and options is not NULL, then use the first value 13 | #' in \code{options}. 14 | #' @param type NULL, 'num' or 'char' 15 | #' @param prefix prefix of warning message. 16 | #' 17 | #' @return original \code{x} value if there are no issues, otherwise the \code{default} 18 | #' if given, otherwise the first element in \code{options}. 19 | #' @noRd 20 | check_default <- function(x, options = NULL, default = NULL, type = NULL, prefix = "") { 21 | 22 | stopifnot(is.null(options) || is.atomic(options)) 23 | 24 | default <- default %||% (options[1]) 25 | if (is.null(default) || length(default) != 1) { 26 | abort("check_default(): Must specify 'default' or 'options'") 27 | } 28 | 29 | if (length(x) != 1) { 30 | res <- default 31 | } else if (!is.null(options) && !x %in% options) { 32 | res <- default 33 | } else { 34 | res <- x 35 | } 36 | 37 | if (!is.null(type)) { 38 | res <- switch( 39 | type, 40 | numeric =, 41 | number =, 42 | float =, 43 | num = ifelse(is.numeric (res), res, default), 44 | character = , 45 | chr = , 46 | char = ifelse(is.character(res), res, default), 47 | { 48 | abort(paste0("check_default(): Don't know how to check for type: ", type)) 49 | } 50 | ) 51 | } 52 | 53 | res 54 | } 55 | 56 | #' abind clone for adding a matrix to an array 57 | #' 58 | #' A very cut-down version of \code{abind::abind()} that will only stack a 59 | #' matrix onto an array. 60 | #' 61 | #' @param arr,mat array and matrix to be stacked 62 | #' 63 | #' @return new array with matrix added as a new plane at the end of the array 64 | #' @noRd 65 | my_abind <- function(arr, mat) { 66 | 67 | stopifnot(is.array(arr)) 68 | stopifnot(is.matrix(mat)) 69 | if (!identical(utils::head(dim(arr), -1), dim(mat))) { 70 | abort(glue("Dimension missmatch. Array: {deparse(dim(arr))} Matrix: {deparse(dim(mat))}")) 71 | } 72 | 73 | new_dim <- dim(arr) 74 | new_dim[3] <- new_dim[3] + 1 75 | 76 | array(c(arr, mat), dim = new_dim) 77 | } 78 | -------------------------------------------------------------------------------- /R/utils-ggplot2.R: -------------------------------------------------------------------------------- 1 | # Added to ggplot2 by Thomas Lin Pedersen 2 | # Fast data.frame constructor and indexing 3 | # No checking, recycling etc. unless asked for 4 | new_data_frame <- function(x = list(), n = NULL) { 5 | if (length(x) != 0 && is.null(names(x))) { 6 | abort("Elements must be named") 7 | } 8 | lengths <- vapply(x, length, integer(1)) 9 | if (is.null(n)) { 10 | n <- if (length(x) == 0 || min(lengths) == 0) 0 else max(lengths) 11 | } 12 | for (i in seq_along(x)) { 13 | if (lengths[i] == n) next 14 | if (lengths[i] != 1) { 15 | abort("Elements must equal the number of rows or 1") 16 | } 17 | x[[i]] <- rep(x[[i]], n) 18 | } 19 | 20 | class(x) <- "data.frame" 21 | 22 | attr(x, "row.names") <- .set_row_names(n) 23 | x 24 | } 25 | data_frame <- function(...) { 26 | new_data_frame(list(...)) 27 | } 28 | .pt <- 2.845276 # ggplot2 constant 29 | 30 | ggplot2pat <- function(gg) { 31 | stopifnot(getRversion() >= "4.1.0", 32 | requireNamespace("ggplot2", quietly = TRUE), 33 | requireNamespace("gtable", quietly = TRUE)) 34 | gg <- suppressMessages(gg + 35 | ggplot2::scale_x_continuous(expand=c(0, 0)) + 36 | ggplot2::scale_y_continuous(expand=c(0, 0))) 37 | grob <- gtable::gtable_filter(ggplot2::ggplotGrob(gg), "panel") 38 | pat <- grid::pattern(grob) 39 | pat 40 | } 41 | -------------------------------------------------------------------------------- /R/utils-grid.R: -------------------------------------------------------------------------------- 1 | # c() and append() don't directly work with grid::gList() lists 2 | append_gList <- function(gl, grob) { 3 | gl[[length(gl) + 1L]] <- grob 4 | gl 5 | } 6 | 7 | rep_len_fill <- function(x, length.out) { 8 | if (inherits(x, "GridPattern")) 9 | rep_len(list(x), length.out) 10 | else 11 | rep_len(x, length.out) 12 | } 13 | 14 | # get width, height, length, and center cooordinates of the viewport in `units` units 15 | get_vp_measurements <- function(units = "bigpts") { 16 | width <- convertWidth(unit(1, "npc"), units, valueOnly = TRUE) 17 | height <- convertHeight(unit(1, "npc"), units, valueOnly = TRUE) 18 | length <- max(width, height) 19 | x <- convertX(unit(0.5, "npc"), units, valueOnly = TRUE) 20 | y <- convertY(unit(0.5, "npc"), units, valueOnly = TRUE) 21 | list(width = width, height = height, length = length, x = x, y = y) 22 | } 23 | -------------------------------------------------------------------------------- /R/utils-magick-misc.R: -------------------------------------------------------------------------------- 1 | #' Convert an R colour to a magick colour 2 | #' 3 | #' @param col may be a built in colour, like 'tomato' or a hex colour 4 | #' 5 | #' @return always returns a hex colour, except if col is NA when it returns a special 6 | #' magick colour 'none', which means transparent 7 | #' 8 | #' @noRd 9 | convert_r_colour_to_magick_colour <- function(col) { 10 | if (is.null(col) || is.na(col) || length(col) == 0 || col == "transparent") { 11 | return('none') 12 | } 13 | col_rgb <- col2rgb(col, alpha = TRUE) 14 | rgb(col_rgb[1,], col_rgb[2,], col_rgb[3,], col_rgb[4,], maxColorValue = 255) 15 | } 16 | 17 | #' Convert a magick image to an RGBA array. 18 | #' 19 | #' This will promote gray or RGB images to RGBA arrays. 20 | #' 21 | #' @param img magick image 22 | #' 23 | #' @return RGBA array with all values in range [0, 1] 24 | #' 25 | #' @noRd 26 | convert_img_to_array <- function(img) { 27 | 28 | stopifnot(inherits(img, 'magick-image')) 29 | 30 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 31 | # extract the RGB array from that image 32 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 | arr <- as.numeric(magick::image_data(img)) 34 | 35 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 36 | # If this is a grey image (i.e. a 2d matrix), then promote it 37 | # to a 3d array by copying the grey into R,G and B planes 38 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 39 | if (length(dim(arr)) == 2) { 40 | arr <- array(c(arr, arr, arr), dim = c(dim(arr), 3)) 41 | } 42 | 43 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 44 | # Add an alpha channel if there isn't one already 45 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 46 | if (dim(arr)[3] == 3) { 47 | alpha_matrix <- matrix(1, nrow=dim(arr)[1], ncol = dim(arr)[2]) 48 | arr <- my_abind(arr, alpha_matrix) 49 | } 50 | 51 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52 | # Sanity check: Assert everything image is RGBA 53 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54 | stopifnot(dim(arr)[3] == 4) 55 | 56 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | # Transpose the image if requested. 58 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 59 | # if (transpose) { 60 | # arr <- aperm(arr, c(2, 1, 3)) 61 | # } 62 | 63 | arr 64 | } 65 | -------------------------------------------------------------------------------- /R/utils-magick-pattern.R: -------------------------------------------------------------------------------- 1 | #' Create one of imagemagick's internal patterns 2 | #' 3 | #' These are all 2-colour pixel patterns - the 'white' part will be made transparent. 4 | #' 5 | #' @param width,height image dimensions 6 | #' @param type name of the imagemagick pattern. See \url{http://www.imagemagick.org/script/formats.php} 7 | #' for more information. See \link{names_magick} for a list of all 8 | #' supported imagemagick patterns. 9 | #' @param colour colour used to draw the pattern 10 | #' 11 | #' @noRd 12 | create_magick_pattern_img <- function(width=100, height=100, type = 'hexagons', 13 | colour = 'black') { 14 | 15 | type <- check_default(tolower(type), names_magick, default = 'checkerboard') 16 | colour <- convert_r_colour_to_magick_colour(colour) 17 | 18 | if (width == 0 || height == 0) { 19 | warn("create_magick_pattern_img(): zero size") 20 | return(magick::image_blank(10, 10)) 21 | } 22 | 23 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 | # Create a pattern image of the required size 25 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 26 | pseudo <- paste0("pattern:", type) 27 | img <- magick::image_blank(width, height, pseudo_image = pseudo) 28 | 29 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 30 | # The checkerboard is the only(?) pattern which isn't pure black and white. 31 | # for the sake of consistency it will be thresholded from its original 32 | # two-level gray colours into pure black and white. 33 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 34 | if (type %in% 'checkerboard') { 35 | img <- magick::image_threshold(img, type = 'black') 36 | img <- magick::image_threshold(img, type = 'white') 37 | } 38 | 39 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 40 | # Make the white transparent 41 | # Colourie the black pixels into the desired colour 42 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 43 | img <- magick::image_transparent(img, 'white') 44 | img <- magick::image_colorize(img, opacity = 100, colour) 45 | 46 | img 47 | } 48 | 49 | #' Create a scaled version one of imagemagick's internal patterns 50 | #' 51 | #' These are all 2-colour pixel patterns - the 'white' part will be made transparent. 52 | #' 53 | #' @inheritParams create_magick_pattern_img 54 | #' @param scale pattern scaling factor defualt: 1 55 | #' @param filter filter to apply when sacling pattern. default: 'box' for crisp 56 | #' edges to the pixel. See \code{magick::filter_types()} for a full list 57 | #' of filters. 58 | #' 59 | #' @noRd 60 | create_magick_pattern_img_scaled <- function(width = 100, 61 | height = 100, 62 | type = 'hexagons', 63 | colour = 'black', 64 | scale = 1, 65 | filter = 'box') { 66 | 67 | scale <- check_default(scale, default = 1, type = 'numeric') 68 | 69 | if (scale < 0.01 || scale > 100) { 70 | scale <- 1 71 | } 72 | 73 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 74 | # Create a scaled version of the pattern 75 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 76 | new_width <- width /scale 77 | new_height <- height/scale 78 | 79 | img <- create_magick_pattern_img(new_width, new_height, type = type, colour = colour) 80 | 81 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 82 | # Which we'll scale back down to the original size 83 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 84 | img <- fill_area_with_img_squish(img, width, height, filter = filter) 85 | 86 | img 87 | } 88 | -------------------------------------------------------------------------------- /R/utils-magick-read.R: -------------------------------------------------------------------------------- 1 | #' Fetch a given path or URL as a magick image 2 | #' 3 | #' @param filename filename or URL 4 | #' 5 | #' @return magick image 6 | #' @noRd 7 | img_read <- function(filename) { 8 | if (identical(filename, '')) { 9 | return(magick::image_blank(100, 100, color = 'none')) 10 | } 11 | if (is.null(filename) || length(filename)== 0 || is.na(filename) || filename == '') { 12 | abort(paste0("bad filename: ", deparse(filename))) 13 | } 14 | 15 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 16 | # Fetch the URL as an image 17 | #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 18 | img <- tryCatch( 19 | {magick::image_read(filename)}, 20 | error = function(cond) { 21 | msg <- c(glue("couldn't read {shQuote(filename)}"), 22 | i = cond$message) 23 | abort(msg) 24 | } 25 | ) 26 | img 27 | } 28 | 29 | #' Fetch a given path or URL as a 3D RGB array of values 30 | #' 31 | #' @param filename filename or URL 32 | #' @param width,height if specified scale the image to these dimensions before 33 | #' converting to an array 34 | #' @param fill_type how to fill the image area. 'none', 'fit', 35 | #' 'squish', 'expand', 'tile' 36 | #' @param gravity imagemagick gravity option on how to position an image during 37 | #' a resize/fill 38 | #' @param scale scale image prior to tiling. Only for fill_type == 'tile' 39 | #' @param filter filter for scaling. default: lanczos. only for fill_type = 'tile' 40 | #' 41 | #' @return 3D array. If the image was pure gray, then it will be promoted to 42 | #' be an unsaturated RGB image. 43 | #' 44 | #' @noRd 45 | img_read_as_array <- function(filename, width = NULL, height = NULL, 46 | fill_type = 'squish', gravity = 'Center', 47 | scale = 1, filter = 'lanczos') { 48 | 49 | img <- img_read_memoised(filename) 50 | 51 | if (is.null(img)) { 52 | abort(glue("couldn't read {shQuote(filename)}")) 53 | } 54 | 55 | img <- fill_area_with_img(img, width, height, type = fill_type, gravity = gravity, 56 | filter = filter, scale = scale) 57 | 58 | convert_img_to_array(img) 59 | } 60 | -------------------------------------------------------------------------------- /R/utils-misc.R: -------------------------------------------------------------------------------- 1 | assert_suggested <- function(package, pattern) { 2 | if (!requireNamespace(package, quietly = TRUE)) { 3 | abort(c(glue("The suggested package {{{package}}} must be installed ", 4 | 'in order to use the "{pattern}" pattern.'), 5 | i = glue('Install with the command `install.packages("{package}")`'))) 6 | } 7 | } 8 | 9 | # base R's Cairo/Quartz devices as well as {ragg} / {svglite} / {vdiffr} devices 10 | # should support Unicode without complaint 11 | # Notably `pdf()` is a device that does not... 12 | # Any other devices to add? 13 | device_supports_unicode <- function() { 14 | device <- names(grDevices::dev.cur()) 15 | unicode_devices <- c("agg_capture", "agg_jpeg", "agg_ppm", "agg_png", "agg_record", "agg_tiff", # {ragg} 16 | "devSVG", "devSVG_vdiffr", # {svglite} / {vdiffr} 17 | "quartz", "quartz_off_screen", # Quartz 18 | "cairo_pdf", "cairo_ps", "svg", "X11cairo") # Cairo 19 | if (any(vapply(unicode_devices, function(x) grepl(paste0("^", x), device), 20 | FUN.VALUE = logical(1L)))) { 21 | TRUE 22 | } else if (device %in% c("bmp", "jpeg", "png", "tiff")) { 23 | # on unix non-"cairo" type have different device names from "cairo" type 24 | # but on Windows can't distinguish between `type = "windows"` or `type = "cairo"` 25 | # Windows device doesn't support new patterns feature 26 | if (getRversion() >= "4.2.0") { 27 | "LinearGradient" %in% grDevices::dev.capabilities()$patterns 28 | } else { 29 | .Platform$OS.type == "unix" 30 | } 31 | } else { 32 | FALSE 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /R/utils-sf.R: -------------------------------------------------------------------------------- 1 | sf_multipolygon_to_polygon_grob <- function(multipolygons_sf, gp = gpar(), 2 | default.units = "npc", name = NULL) { 3 | df <- convert_polygon_sf_to_polygon_df(multipolygons_sf) 4 | if (is.null(df)) { 5 | nullGrob() 6 | } else { 7 | polygonGrob(x = df$x, y = df$y, id = df$id, 8 | default.units = default.units, gp = gp, name = name) 9 | } 10 | } 11 | 12 | # build a circle of radius `r` centered on each point in `sf_points` 13 | sf_points_to_circle_grob <- function(sf_points, r, gp = gpar(), 14 | default.units = "npc", name = NULL) { 15 | points_mat <- as.matrix(sf_points) 16 | if (is.null(points_mat) || nrow(points_mat) == 0) { 17 | nullGrob() 18 | } else { 19 | circleGrob(x = points_mat[, 1], y = points_mat[, 2], r = r, 20 | default.units = default.units, gp = gp, name = name) 21 | } 22 | } 23 | 24 | # `xy_polygon` has `x` and `y` elements which will be added to each point in `sf_points` 25 | sf_points_to_polygon_grob <- function(sf_points, xy_polygon, gp = gpar(), 26 | default.units = "npc", name = NULL) { 27 | points_mat <- as.matrix(sf_points) 28 | df_polygon <- as.data.frame(xy_polygon) 29 | l_xy <- lapply(seq(nrow(points_mat)), 30 | function(i_r) { 31 | x0 <- points_mat[i_r, 1] 32 | y0 <- points_mat[i_r, 2] 33 | df <- df_polygon 34 | df$x <- df$x + x0 35 | df$y <- df$y + y0 36 | df 37 | }) 38 | df <- do.call(rbind, l_xy) 39 | if (is.null(df)) { 40 | nullGrob() 41 | } else { 42 | df$id <- rep(seq(nrow(points_mat)), each = nrow(df_polygon)) 43 | polygonGrob(x = df$x, y = df$y, id = df$id, 44 | default.units = default.units, gp = gp, name = name) 45 | } 46 | } 47 | 48 | # `xy_polygon` has `x` and `y` elements which will be added to each point in `sf_points` 49 | sf_points_to_sf_multipolygon <- function(sf_points, xy_polygon) { 50 | points_mat <- as.matrix(sf_points) 51 | df_polygon <- as.data.frame(xy_polygon) 52 | df_polygon <- rbind(df_polygon, df_polygon[1L, ]) 53 | l_xy <- lapply(seq(nrow(points_mat)), 54 | function(i_r) { 55 | x0 <- points_mat[i_r, 1] 56 | y0 <- points_mat[i_r, 2] 57 | df <- df_polygon 58 | df$x <- df$x + x0 59 | df$y <- df$y + y0 60 | list(as.matrix(df)) 61 | }) 62 | sf::st_multipolygon(l_xy) 63 | } 64 | 65 | -------------------------------------------------------------------------------- /R/z_guess_has_R4.1_features_docs.R: -------------------------------------------------------------------------------- 1 | # The code for this function is in `standalone-guess_has_R4.1_features.R` 2 | 3 | #' Guess whether "active" graphics device supports 4 | #' the grid graphics features introduced in R v4.1. 5 | #' 6 | #' `guess_has_R4.1_features()` guesses whether "active" graphics device supports 7 | #' the grid graphics features introduced in R v4.1. If it guesses it does 8 | #' it returns `TRUE` else `FALSE`. 9 | #' 10 | #' @section Usage in other packages: 11 | #' 12 | #' To avoid taking a dependency on `gridpattern` you may copy the source of `guess_has_R4.1_features()` 13 | #' into your own package under the permissive MIT No Attribution (MIT-0) license. Either use 14 | #' `usethis::use_standalone("trevorld/gridpattern", "standalone-guess_has_R4.1_features.R")` 15 | #' or copy the file `standalone-guess_has_R4.1_features.R` into your `R` directory and 16 | #' add `grDevices` and `utils` to the `Imports` of your `DESCRIPTION` file. 17 | #' 18 | #' @param features Character vector of features to guess support for. 19 | #' Will return `TRUE` only if guesses support for all requested features.\describe{ 20 | #' \item{"clippingPaths"}{Supports clipping path feature} 21 | #' \item{"gradients"}{Supports (both linear and radial) gradient feature} 22 | #' \item{"masks"}{Supports (alpha) mask feature} 23 | #' \item{"patterns"}{Supports (tiling) pattern feature} 24 | #' } 25 | #' @seealso \url{https://www.stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/definitions/definitions.html} for more info about the new grid graphics 26 | #' features introduced in R v4.1. 27 | #' @return `TRUE` if we guess all `features` are supported else `FALSE` 28 | #' @examples 29 | #' # If R version (weakly) greater than 4.1 should be TRUE 30 | #' pdf(tempfile(fileext = ".pdf")) 31 | #' print(guess_has_R4.1_features()) 32 | #' invisible(dev.off()) 33 | #' 34 | #' # Should be FALSE 35 | #' postscript(tempfile(fileext = ".ps")) 36 | #' print(guess_has_R4.1_features()) 37 | #' invisible(dev.off()) 38 | #' 39 | #' @export 40 | guess_has_R4.1_features <- guess_has_R4.1_features 41 | -------------------------------------------------------------------------------- /R/z_update_alpha_docs.R: -------------------------------------------------------------------------------- 1 | # The code for this function is in `standalone-update_alpha.R` 2 | 3 | #' Update colour and/or pattern transparency 4 | #' 5 | #' `update_alpha()` modifies the transparency of colours and/or patterns. 6 | #' 7 | #' * This is a fork of pattern utilities mainly added to `{ggplot2}` by Teun van den Brand. 8 | #' * `update_alpha()` does not depend on `{ggplot2}` or `{scales}`. 9 | #' * Like [ggplot2::fill_alpha()] but unlike [scales::alpha()] it also attempts 10 | #' to set the transparency of `` objects. 11 | #' * Unlike [ggplot2::fill_alpha()] it will work on a list of length one 12 | #' containing a vector of color strings. 13 | #' 14 | #' @section Usage in other packages: 15 | #' 16 | #' To avoid taking a dependency on `gridpattern` you may copy the source of `update_alpha()` 17 | #' into your own package under the permissive MIT license. Either use 18 | #' `usethis::use_standalone("trevorld/gridpattern", "standalone-update_alpha.R")` 19 | #' or copy the file `update_alpha.R` into your `R` directory and 20 | #' add `grDevices`, `grid`, and `rlang` to the `Imports` of your `DESCRIPTION` file. 21 | #' 22 | #' @param fill A fill colour given as a `character` or `integer` vector, or as a 23 | #' (list of) `` object(s) and/or colour(s). 24 | #' @param alpha A transparency value between 0 (transparent) and 1 (opaque), 25 | #' parallel to `fill`. 26 | #' @return A `character` vector of colours or list of `` objects. 27 | #' @examples 28 | #' # Typical color input 29 | #' update_alpha("red", 0.5) 30 | #' 31 | #' # Pattern input 32 | #' if (getRversion() >= "4.2" && requireNamespace("grid", quietly = TRUE)) { 33 | #' update_alpha(list(grid::linearGradient()), 0.5) 34 | #' } 35 | #' @export 36 | update_alpha <- update_alpha 37 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | # We use `<<-` below to modify the package's namespace 2 | # in order to prevent a build time dependency on `memoise` 3 | # as recommended in . 4 | # We don't modify the global environment. 5 | # See for further details. 6 | 7 | # Define function at build time 8 | img_read_memoised <- img_read 9 | 10 | # Modify function at load time 11 | .onLoad <- function(libname, pkgname) { 12 | img_read_memoised <<- memoise::memoise(img_read) 13 | } 14 | 15 | #' @import grid 16 | #' @importFrom glue glue 17 | #' @importFrom grDevices col2rgb dev.capture dev.capabilities dev.off png rgb 18 | #' @importFrom rlang %||% abort inform warn 19 | #' @importFrom utils hasName head packageVersion tail 20 | NULL 21 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | desc "Build files for packaging" 2 | task :default do 3 | sh 'Rscript -e "devtools::document()"' 4 | sh 'Rscript -e "knitr::knit(\"README.Rmd\")"' 5 | sh 'pandoc -o README.html README.md' 6 | sh 'Rscript -e "pkgdown::build_site()"' 7 | end 8 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | destination: "../../websites/R/gridpattern/" 2 | url: "https://trevorldavis.com/R/gridpattern" 3 | development: 4 | mode: auto 5 | template: 6 | bootstrap: 5 7 | reference: 8 | - title: "Pattern fills" 9 | desc: "Pattern fill function" 10 | contents: 11 | - patternFill 12 | - title: "Pattern grobs" 13 | desc: "Pattern grob functions" 14 | contents: 15 | - starts_with("grid.pattern") 16 | - title: "Pattern matrices" 17 | - desc: "Pattern matrix functions" 18 | contents: 19 | - starts_with("pattern_") 20 | - title: "Miscellaneous helpers" 21 | desc: "Miscellaneous helper functions" 22 | contents: 23 | - alphaMaskGrob 24 | - clippingPathGrob 25 | - guess_has_R4.1_features 26 | - mean_col 27 | - reset_image_cache 28 | - star_scale 29 | - update_alpha 30 | - title: "Overall package description" 31 | desc: "Overall package description including supported package options" 32 | contents: 33 | - gridpattern-package 34 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | 3 | * local (linux, R 4.4.2) 4 | * win-builder (windows, R devel) 5 | * github actions (linux, R oldrel) 6 | * github actions (linux, R release) 7 | * github actions (linux, R devel) 8 | 9 | ## R CMD check --as-cran results 10 | 11 | OK 12 | -------------------------------------------------------------------------------- /man/alphaMaskGrob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/alphaMaskGrob.R 3 | \name{alphaMaskGrob} 4 | \alias{alphaMaskGrob} 5 | \title{Mask grob using another grob to specify the (alpha) mask} 6 | \usage{ 7 | alphaMaskGrob( 8 | maskee, 9 | masker, 10 | use_R4.1_masks = getOption("ggpattern_use_R4.1_masks", 11 | getOption("ggpattern_use_R4.1_features")), 12 | png_device = NULL, 13 | res = getOption("ggpattern_res", 72), 14 | name = NULL, 15 | gp = gpar(), 16 | vp = NULL 17 | ) 18 | } 19 | \arguments{ 20 | \item{maskee}{Grob to be masked} 21 | 22 | \item{masker}{Grob that defines masking region} 23 | 24 | \item{use_R4.1_masks}{If \code{TRUE} use the grid mask feature introduced in R v4.1.0. 25 | If \code{FALSE} do a \code{rasterGrob} approximation. 26 | If \code{NULL} try to guess an appropriate choice. 27 | Note not all graphic devices support the grid mask feature.} 28 | 29 | \item{png_device}{\dQuote{png} graphics device to save intermediate raster data with if \code{use_R4.1_masks} is \code{FALSE}. 30 | If \code{NULL} and suggested package \code{ragg} is available 31 | and versions are high enough we directly capture masked raster via \code{\link[ragg:agg_capture]{ragg::agg_capture()}}. 32 | Otherwise we will use \code{png_device} 33 | (default \code{\link[ragg:agg_png]{ragg::agg_png()}} if available else \code{\link[grDevices:png]{grDevices::png()}}) and \code{\link[png:readPNG]{png::readPNG()}} 34 | to manually compute a masked raster.} 35 | 36 | \item{res}{Resolution of desired \code{rasterGrob} in pixels per inch if \code{use_R4.1_masks} is \code{FALSE}.} 37 | 38 | \item{name}{ A character identifier. } 39 | 40 | \item{gp}{An object of class \code{"gpar"}, typically the output 41 | from a call to the function \code{\link[grid]{gpar}}. This is basically 42 | a list of graphical parameter settings.} 43 | 44 | \item{vp}{A Grid viewport object (or NULL).} 45 | } 46 | \value{ 47 | A \code{grid} grob 48 | } 49 | \description{ 50 | \code{alphaMaskGrob()} masks a grob using another grob to specify the (alpha) mask. 51 | } 52 | \examples{ 53 | \donttest{# May take more than 5 seconds on CRAN servers 54 | if (capabilities("png") && require("grid")) { 55 | maskee <- patternGrob("circle", gp = gpar(col = "black", fill = "yellow"), 56 | spacing = 0.1, density = 0.5) 57 | angle <- seq(2 * pi / 4, by = 2 * pi / 6, length.out = 7) 58 | x_hex_outer <- 0.5 + 0.5 * cos(angle) 59 | y_hex_outer <- 0.5 + 0.5 * sin(angle) 60 | x_hex_inner <- 0.5 + 0.25 * cos(rev(angle)) 61 | y_hex_inner <- 0.5 + 0.25 * sin(rev(angle)) 62 | gp <- gpar(lwd = 0, col = NA, fill = "white") 63 | masker <- grid::pathGrob(x = c(x_hex_outer, x_hex_inner), 64 | y = c(y_hex_outer, y_hex_inner), 65 | id = rep(1:2, each = 7), 66 | rule = "evenodd", gp = gp) 67 | masked <- alphaMaskGrob(maskee, masker, use_R4.1_masks = FALSE) 68 | grid.draw(masked) 69 | } 70 | if (capabilities("png") && require("grid")) { 71 | maskee_transparent <- rectGrob(gp = gpar(col = NA, fill = "blue")) 72 | gp <- gpar(lwd = 20, col = "black", fill = grDevices::rgb(0, 0, 0, 0.5)) 73 | masker_transparent <- editGrob(masker, gp = gp) 74 | masked_transparent <- alphaMaskGrob(maskee_transparent, 75 | masker_transparent, 76 | use_R4.1_masks = FALSE) 77 | grid.newpage() 78 | grid.draw(masked_transparent) 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /man/clippingPathGrob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/clippingPathGrob.R 3 | \name{clippingPathGrob} 4 | \alias{clippingPathGrob} 5 | \title{Clip grob using another grob to specify the clipping path} 6 | \usage{ 7 | clippingPathGrob( 8 | clippee, 9 | clipper, 10 | use_R4.1_clipping = getOption("ggpattern_use_R4.1_clipping", 11 | getOption("ggpattern_use_R4.1_features")), 12 | png_device = NULL, 13 | res = getOption("ggpattern_res", 72), 14 | name = NULL, 15 | gp = gpar(), 16 | vp = NULL 17 | ) 18 | } 19 | \arguments{ 20 | \item{clippee}{Grob to be clipped} 21 | 22 | \item{clipper}{Grob that defines clipping region} 23 | 24 | \item{use_R4.1_clipping}{If \code{TRUE} use the grid clipping path feature introduced in R v4.1.0. 25 | If \code{FALSE} do a \code{rasterGrob} approximation. 26 | If \code{NULL} try to guess an appropriate choice. 27 | Note not all graphic devices support the grid clipping path feature 28 | and the grid clipping path feature does not nest.} 29 | 30 | \item{png_device}{\dQuote{png} graphics device to save intermediate raster data with if \code{use_R4.1_clipping} is \code{FALSE}. 31 | If \code{NULL} and suggested package \code{ragg} is available 32 | and versions are high enough we directly capture clipped raster via \code{\link[ragg:agg_capture]{ragg::agg_capture()}}. 33 | Otherwise we will use \code{png_device} 34 | (default \code{\link[ragg:agg_png]{ragg::agg_png()}} if available else \code{\link[grDevices:png]{grDevices::png()}}) and \code{\link[png:readPNG]{png::readPNG()}} 35 | to manually compute a clipped raster.} 36 | 37 | \item{res}{Resolution of desired \code{rasterGrob} in pixels per inch if \code{use_R4.1_clipping} is \code{FALSE}.} 38 | 39 | \item{name}{ A character identifier. } 40 | 41 | \item{gp}{An object of class \code{"gpar"}, typically the output 42 | from a call to the function \code{\link[grid]{gpar}}. This is basically 43 | a list of graphical parameter settings.} 44 | 45 | \item{vp}{A Grid viewport object (or NULL).} 46 | } 47 | \value{ 48 | A \code{grid} grob 49 | } 50 | \description{ 51 | \code{clippingPathGrob()} clips a grob using another grob to specify the clipping path 52 | } 53 | \examples{ 54 | if (capabilities("png") && require("grid")) { 55 | clippee <- patternGrob("circle", gp = gpar(col = "black", fill = "yellow"), 56 | spacing = 0.1, density = 0.5) 57 | angle <- seq(2 * pi / 4, by = 2 * pi / 6, length.out = 7) 58 | x_hex_outer <- 0.5 + 0.5 * cos(angle) 59 | y_hex_outer <- 0.5 + 0.5 * sin(angle) 60 | x_hex_inner <- 0.5 + 0.25 * cos(rev(angle)) 61 | y_hex_inner <- 0.5 + 0.25 * sin(rev(angle)) 62 | clipper <- grid::pathGrob(x = c(x_hex_outer, x_hex_inner), 63 | y = c(y_hex_outer, y_hex_inner), 64 | id = rep(1:2, each = 7), 65 | rule = "evenodd") 66 | clipped <- clippingPathGrob(clippee, clipper, use_R4.1_clipping = FALSE) 67 | grid.newpage() 68 | grid.draw(clipped) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /man/figures/README-circle-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-circle-1.png -------------------------------------------------------------------------------- /man/figures/README-crosshatch-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-crosshatch-1.png -------------------------------------------------------------------------------- /man/figures/README-ggpattern-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-ggpattern-1.png -------------------------------------------------------------------------------- /man/figures/README-ggplot2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-ggplot2-1.png -------------------------------------------------------------------------------- /man/figures/README-hex_ggpattern-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-hex_ggpattern-1.png -------------------------------------------------------------------------------- /man/figures/README-piecepackr-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-piecepackr-1.png -------------------------------------------------------------------------------- /man/figures/README-regular_hex-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-regular_hex-1.png -------------------------------------------------------------------------------- /man/figures/README-regular_star-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-regular_star-1.png -------------------------------------------------------------------------------- /man/figures/README-rhombitrihexagonal-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-rhombitrihexagonal-1.png -------------------------------------------------------------------------------- /man/figures/README-rose-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-rose-1.png -------------------------------------------------------------------------------- /man/figures/README-text-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-text-1.png -------------------------------------------------------------------------------- /man/figures/README-truncated_hexagonal-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-truncated_hexagonal-1.png -------------------------------------------------------------------------------- /man/figures/README-wave-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-wave-1.png -------------------------------------------------------------------------------- /man/figures/README-weave-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/README-weave-1.png -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/man/figures/logo.png -------------------------------------------------------------------------------- /man/grid.pattern_aRtsy.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-pattern-aRtsy.R 3 | \name{grid.pattern_aRtsy} 4 | \alias{grid.pattern_aRtsy} 5 | \alias{names_aRtsy} 6 | \title{Grobs with patterns powered by the aRtsy package} 7 | \usage{ 8 | grid.pattern_aRtsy( 9 | x = c(0, 0, 1, 1), 10 | y = c(1, 0, 0, 1), 11 | id = 1L, 12 | ..., 13 | type = "strokes", 14 | fill = gp$fill \%||\% "grey80", 15 | alpha = gp$alpha \%||\% NA_real_, 16 | default.units = "npc", 17 | name = NULL, 18 | gp = gpar(), 19 | draw = TRUE, 20 | vp = NULL 21 | ) 22 | 23 | names_aRtsy() 24 | } 25 | \arguments{ 26 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 27 | 28 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 29 | 30 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 31 | All locations within the same \code{id} belong to the same boundary.} 32 | 33 | \item{...}{Currently ignored} 34 | 35 | \item{type}{Name of pattern.} 36 | 37 | \item{fill}{Passed to the underlying \code{aRtsy} function's \code{color} / \code{colors} argument.} 38 | 39 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 40 | 41 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 42 | are only given as numeric vectors.} 43 | 44 | \item{name}{ A character identifier. } 45 | 46 | \item{gp}{An object of class \code{"gpar"}, typically the output 47 | from a call to the function \code{\link[grid]{gpar}}. This is basically 48 | a list of graphical parameter settings.} 49 | 50 | \item{draw}{A logical value indicating whether graphics output 51 | should be produced.} 52 | 53 | \item{vp}{A Grid viewport object (or NULL).} 54 | } 55 | \value{ 56 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 57 | } 58 | \description{ 59 | \code{grid.pattern_aRtsy()} draws patterns powered by the \code{aRtsy} package. 60 | \code{names_aRtsy()} returns character vector of supported types. 61 | } 62 | \examples{ 63 | if (requireNamespace("aRtsy", quietly = TRUE)) { 64 | print(names_aRtsy()) 65 | } 66 | 67 | \donttest{# Make take more than 5 seconds on CRAN servers 68 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 69 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 70 | if (requireNamespace("aRtsy", quietly = TRUE) && 71 | guess_has_R4.1_features("patterns")) { 72 | grid::grid.newpage() 73 | grid.pattern_aRtsy(x_hex, y_hex, type = "forest", 74 | fill = c("black", "white", "grey")) 75 | } 76 | } 77 | } 78 | \seealso{ 79 | \url{https://koenderks.github.io/aRtsy/} for more information about the \code{aRtsy} package. 80 | } 81 | -------------------------------------------------------------------------------- /man/grid.pattern_circle.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-geometry-circle.R 3 | \name{grid.pattern_circle} 4 | \alias{grid.pattern_circle} 5 | \title{Circle patterned grobs} 6 | \usage{ 7 | grid.pattern_circle( 8 | x = c(0, 0, 1, 1), 9 | y = c(1, 0, 0, 1), 10 | id = 1L, 11 | ..., 12 | colour = gp$col \%||\% "grey20", 13 | fill = gp$fill \%||\% "grey80", 14 | angle = 30, 15 | density = 0.2, 16 | spacing = 0.05, 17 | xoffset = 0, 18 | yoffset = 0, 19 | units = "snpc", 20 | alpha = gp$alpha \%||\% NA_real_, 21 | linetype = gp$lty \%||\% 1, 22 | linewidth = size \%||\% gp$lwd \%||\% 1, 23 | size = NULL, 24 | grid = "square", 25 | type = NULL, 26 | subtype = NULL, 27 | default.units = "npc", 28 | name = NULL, 29 | gp = gpar(), 30 | draw = TRUE, 31 | vp = NULL 32 | ) 33 | } 34 | \arguments{ 35 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 36 | 37 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 38 | 39 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 40 | All locations within the same \code{id} belong to the same boundary.} 41 | 42 | \item{...}{Currently ignored.} 43 | 44 | \item{colour}{Stroke colour(s).} 45 | 46 | \item{fill}{Fill colour(s) or \code{\link[grid:patterns]{grid::pattern()}} / gradient object(s).} 47 | 48 | \item{angle}{Rotation angle in degrees.} 49 | 50 | \item{density}{Approx. fraction of area the pattern fills.} 51 | 52 | \item{spacing}{Spacing between repetitions of pattern (in \code{units} units).} 53 | 54 | \item{xoffset}{Shift pattern along x axis (in \code{units} units).} 55 | 56 | \item{yoffset}{Shift pattern along y axis (in \code{units} units).} 57 | 58 | \item{units}{\code{\link[grid:unit]{grid::unit()}} units for \code{spacing}, \code{xoffset}, and \code{yoffset} parameters.} 59 | 60 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 61 | 62 | \item{linetype}{Stroke linetype.} 63 | 64 | \item{linewidth}{Stroke linewidth.} 65 | 66 | \item{size}{For backwards compatibility can be used to set \code{linewidth}.} 67 | 68 | \item{grid}{Adjusts placement and density of certain graphical elements. 69 | \code{"square"} (default) is a square grid. 70 | \code{"hex"} is a hexagonal grid suitable for hexagonal and triangular tiling. 71 | \code{"hex_circle"} is a hexagonal grid suitable for circle packing. 72 | \code{"elongated_triangle"} is a grid used for the "elongated triangle" tiling.} 73 | 74 | \item{type}{Adjusts the repeating of certain aesthetics such as color. 75 | Can use any type in \code{names_hex}, \code{names_square}, or \code{names_weave}. 76 | See for \code{\link[=pattern_hex]{pattern_hex()}}, \code{\link[=pattern_square]{pattern_square()}}, and \code{\link[=pattern_weave]{pattern_weave()}} for 77 | more information about supported \code{type} arguments.} 78 | 79 | \item{subtype}{See for \code{\link[=pattern_hex]{pattern_hex()}}, \code{\link[=pattern_square]{pattern_square()}}, and \code{\link[=pattern_weave]{pattern_weave()}} for 80 | more information about supported \code{subtype} arguments.} 81 | 82 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 83 | are only given as numeric vectors.} 84 | 85 | \item{name}{ A character identifier. } 86 | 87 | \item{gp}{An object of class \code{"gpar"}, typically the output 88 | from a call to the function \code{\link[grid]{gpar}}. This is basically 89 | a list of graphical parameter settings.} 90 | 91 | \item{draw}{A logical value indicating whether graphics output 92 | should be produced.} 93 | 94 | \item{vp}{A Grid viewport object (or NULL).} 95 | } 96 | \value{ 97 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 98 | } 99 | \description{ 100 | \code{grid.pattern_circle()} draws a circle pattern onto the graphic device. 101 | } 102 | \examples{ 103 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 104 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 105 | grid.pattern_circle(x_hex, y_hex, fill = c("blue", "yellow"), density = 0.5) 106 | grid::grid.newpage() 107 | grid.pattern_circle(x_hex, y_hex, density = 0.8, grid = "hex_circle", 108 | gp = grid::gpar(fill = c("blue", "yellow", "red"))) 109 | grid::grid.newpage() 110 | grid.pattern_circle(x_hex, y_hex, density = 1.2, grid = "hex_circle", 111 | gp = grid::gpar(fill = c("blue", "yellow", "red"))) 112 | # using a "twill_zigzag" 'weave' pattern 113 | grid::grid.newpage() 114 | grid.pattern_circle(x_hex, y_hex, fill = "blue", density = 0.5, type = "twill_zigzag") 115 | } 116 | \seealso{ 117 | See \code{\link[=grid.pattern_regular_polygon]{grid.pattern_regular_polygon()}} for a more general case of this pattern. 118 | } 119 | -------------------------------------------------------------------------------- /man/grid.pattern_crosshatch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-geometry-crosshatch.R 3 | \name{grid.pattern_crosshatch} 4 | \alias{grid.pattern_crosshatch} 5 | \title{Crosshatch patterned grobs} 6 | \usage{ 7 | grid.pattern_crosshatch( 8 | x = c(0, 0, 1, 1), 9 | y = c(1, 0, 0, 1), 10 | id = 1L, 11 | ..., 12 | colour = gp$col \%||\% "grey20", 13 | fill = gp$fill \%||\% "grey80", 14 | fill2 = fill, 15 | angle = 30, 16 | density = 0.2, 17 | spacing = 0.05, 18 | xoffset = 0, 19 | yoffset = 0, 20 | units = "snpc", 21 | alpha = gp$alpha \%||\% NA_real_, 22 | linetype = gp$lty \%||\% 1, 23 | linewidth = size \%||\% gp$lwd \%||\% 1, 24 | size = NULL, 25 | grid = "square", 26 | default.units = "npc", 27 | name = NULL, 28 | gp = gpar(), 29 | draw = TRUE, 30 | vp = NULL 31 | ) 32 | } 33 | \arguments{ 34 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 35 | 36 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 37 | 38 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 39 | All locations within the same \code{id} belong to the same boundary.} 40 | 41 | \item{...}{Currently ignored.} 42 | 43 | \item{colour}{Stroke colour(s).} 44 | 45 | \item{fill}{Fill colour(s) or \code{\link[grid:patterns]{grid::pattern()}} / gradient object(s).} 46 | 47 | \item{fill2}{The fill colour for the \dQuote{top} crosshatch lines.} 48 | 49 | \item{angle}{Rotation angle in degrees.} 50 | 51 | \item{density}{Approx. fraction of area the pattern fills.} 52 | 53 | \item{spacing}{Spacing between repetitions of pattern (in \code{units} units).} 54 | 55 | \item{xoffset}{Shift pattern along x axis (in \code{units} units).} 56 | 57 | \item{yoffset}{Shift pattern along y axis (in \code{units} units).} 58 | 59 | \item{units}{\code{\link[grid:unit]{grid::unit()}} units for \code{spacing}, \code{xoffset}, and \code{yoffset} parameters.} 60 | 61 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 62 | 63 | \item{linetype}{Stroke linetype.} 64 | 65 | \item{linewidth}{Stroke linewidth.} 66 | 67 | \item{size}{For backwards compatibility can be used to set \code{linewidth}.} 68 | 69 | \item{grid}{Adjusts placement and density of certain graphical elements. 70 | \code{"square"} (default) is a square grid. 71 | \code{"hex"} is a hexagonal grid suitable for hexagonal and triangular tiling. 72 | \code{"hex_circle"} is a hexagonal grid suitable for circle packing. 73 | \code{"elongated_triangle"} is a grid used for the "elongated triangle" tiling.} 74 | 75 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 76 | are only given as numeric vectors.} 77 | 78 | \item{name}{ A character identifier. } 79 | 80 | \item{gp}{An object of class \code{"gpar"}, typically the output 81 | from a call to the function \code{\link[grid]{gpar}}. This is basically 82 | a list of graphical parameter settings.} 83 | 84 | \item{draw}{A logical value indicating whether graphics output 85 | should be produced.} 86 | 87 | \item{vp}{A Grid viewport object (or NULL).} 88 | } 89 | \value{ 90 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 91 | } 92 | \description{ 93 | \code{grid.pattern_crosshatch()} draws a crosshatch pattern onto the graphic device. 94 | } 95 | \examples{ 96 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 97 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 98 | grid.pattern_crosshatch(x_hex, y_hex, colour = "black", fill = "blue", 99 | fill2 = "yellow", density = 0.5) 100 | grid::grid.newpage() 101 | grid.pattern_crosshatch(x_hex, y_hex, density = 0.3, 102 | gp = grid::gpar(col = "blue", fill = "yellow")) 103 | } 104 | \seealso{ 105 | \code{\link[=grid.pattern_weave]{grid.pattern_weave()}} which interweaves two sets of lines. 106 | For a single set of lines use \code{\link[=grid.pattern_stripe]{grid.pattern_stripe()}}. 107 | } 108 | -------------------------------------------------------------------------------- /man/grid.pattern_fill.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-geometry-fill.R 3 | \name{grid.pattern_fill} 4 | \alias{grid.pattern_fill} 5 | \title{Grobs with a simple fill pattern} 6 | \usage{ 7 | grid.pattern_fill( 8 | x = c(0, 0, 1, 1), 9 | y = c(1, 0, 0, 1), 10 | id = 1L, 11 | ..., 12 | fill = gp$fill \%||\% "grey80", 13 | alpha = gp$alpha \%||\% NA_real_, 14 | default.units = "npc", 15 | name = NULL, 16 | gp = gpar(), 17 | draw = TRUE, 18 | vp = NULL 19 | ) 20 | } 21 | \arguments{ 22 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 23 | 24 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 25 | 26 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 27 | All locations within the same \code{id} belong to the same boundary.} 28 | 29 | \item{...}{Currently ignored} 30 | 31 | \item{fill}{Fill colour(s) or \code{\link[grid:patterns]{grid::pattern()}} / gradient object(s).} 32 | 33 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 34 | 35 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 36 | are only given as numeric vectors.} 37 | 38 | \item{name}{ A character identifier. } 39 | 40 | \item{gp}{An object of class \code{"gpar"}, typically the output 41 | from a call to the function \code{\link[grid]{gpar}}. This is basically 42 | a list of graphical parameter settings.} 43 | 44 | \item{draw}{A logical value indicating whether graphics output 45 | should be produced.} 46 | 47 | \item{vp}{A Grid viewport object (or NULL).} 48 | } 49 | \value{ 50 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 51 | } 52 | \description{ 53 | \code{grid.pattern_fill()} draws a simple fill pattern onto the graphics device. 54 | } 55 | \examples{ 56 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 57 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 58 | grid.pattern_fill(x_hex, y_hex, fill = "blue") 59 | 60 | if (guess_has_R4.1_features("patterns")) { 61 | grid::grid.newpage() 62 | stripe_fill <- patternFill("stripe", fill = c("red", "blue")) 63 | grid.pattern_fill(x_hex, y_hex, fill = stripe_fill) 64 | } 65 | } 66 | \seealso{ 67 | \code{\link[grid:grid.polygon]{grid::grid.polygon()}} 68 | } 69 | -------------------------------------------------------------------------------- /man/grid.pattern_gradient.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-both-gradient.R 3 | \name{grid.pattern_gradient} 4 | \alias{grid.pattern_gradient} 5 | \title{Gradient patterned grobs} 6 | \usage{ 7 | grid.pattern_gradient( 8 | x = c(0, 0, 1, 1), 9 | y = c(1, 0, 0, 1), 10 | id = 1L, 11 | ..., 12 | fill = gp$fill \%||\% "grey80", 13 | fill2 = "#4169E1", 14 | orientation = "vertical", 15 | alpha = gp$alpha \%||\% NA_real_, 16 | use_R4.1_gradients = getOption("ggpattern_use_R4.1_gradients", 17 | getOption("ggpattern_use_R4.1_features")), 18 | aspect_ratio = 1, 19 | key_scale_factor = 1, 20 | res = getOption("ggpattern_res", 72), 21 | default.units = "npc", 22 | name = NULL, 23 | gp = gpar(), 24 | draw = TRUE, 25 | vp = NULL 26 | ) 27 | } 28 | \arguments{ 29 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 30 | 31 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 32 | 33 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 34 | All locations within the same \code{id} belong to the same boundary.} 35 | 36 | \item{...}{Currently ignored.} 37 | 38 | \item{fill}{Colour.} 39 | 40 | \item{fill2}{Second colour.} 41 | 42 | \item{orientation}{vertical, horizontal, or radial.} 43 | 44 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 45 | 46 | \item{use_R4.1_gradients}{Whether to use the gradient feature introduced in R v4.1 47 | or use a \code{rasterGrob} approximation. 48 | Note not all graphic devices support the grid gradient feature.} 49 | 50 | \item{aspect_ratio}{Override aspect ratio.} 51 | 52 | \item{key_scale_factor}{Additional scale factor for legend.} 53 | 54 | \item{res}{Assumed resolution (in pixels per graphic device inch) to use when creating array pattern.} 55 | 56 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 57 | are only given as numeric vectors.} 58 | 59 | \item{name}{ A character identifier. } 60 | 61 | \item{gp}{An object of class \code{"gpar"}, typically the output 62 | from a call to the function \code{\link[grid]{gpar}}. This is basically 63 | a list of graphical parameter settings.} 64 | 65 | \item{draw}{A logical value indicating whether graphics output 66 | should be produced.} 67 | 68 | \item{vp}{A Grid viewport object (or NULL).} 69 | } 70 | \value{ 71 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 72 | } 73 | \description{ 74 | \code{grid.pattern_gradient()} draws a gradient pattern onto the graphic device. 75 | } 76 | \examples{ 77 | if (requireNamespace("magick") && capabilities("png")) { 78 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 79 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 80 | grid.pattern_gradient(x_hex, y_hex, fill = "green") 81 | } 82 | if (requireNamespace("magick") && capabilities("png")) { 83 | grid::grid.newpage() 84 | grid.pattern_gradient(x_hex, y_hex, fill = "green", orientation = "radial") 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /man/grid.pattern_image.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-array-image.R 3 | \name{grid.pattern_image} 4 | \alias{grid.pattern_image} 5 | \title{Image patterned grobs} 6 | \usage{ 7 | grid.pattern_image( 8 | x = c(0, 0, 1, 1), 9 | y = c(1, 0, 0, 1), 10 | id = 1L, 11 | ..., 12 | filename = "", 13 | type = "fit", 14 | scale = 1, 15 | gravity = switch(type, tile = "southwest", "center"), 16 | filter = "lanczos", 17 | alpha = gp$alpha \%||\% NA_real_, 18 | aspect_ratio = 1, 19 | key_scale_factor = 1, 20 | res = getOption("ggpattern_res", 72), 21 | default.units = "npc", 22 | name = NULL, 23 | gp = gpar(), 24 | draw = TRUE, 25 | vp = NULL 26 | ) 27 | } 28 | \arguments{ 29 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 30 | 31 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 32 | 33 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 34 | All locations within the same \code{id} belong to the same boundary.} 35 | 36 | \item{...}{Currently ignored.} 37 | 38 | \item{filename}{Image of filename or URL} 39 | 40 | \item{type}{Image scaling type} 41 | 42 | \item{scale}{Extra scaling} 43 | 44 | \item{gravity}{Position of image within area. \code{magick::gravity_types()} returns a vector of supported values.} 45 | 46 | \item{filter}{Filter to use when scaling. \code{magick::filter_types()} returns a vector of supported values.} 47 | 48 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 49 | 50 | \item{aspect_ratio}{Override aspect ratio.} 51 | 52 | \item{key_scale_factor}{Additional scale factor for legend.} 53 | 54 | \item{res}{Assumed resolution (in pixels per graphic device inch) to use when creating array pattern.} 55 | 56 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 57 | are only given as numeric vectors.} 58 | 59 | \item{name}{ A character identifier. } 60 | 61 | \item{gp}{An object of class \code{"gpar"}, typically the output 62 | from a call to the function \code{\link[grid]{gpar}}. This is basically 63 | a list of graphical parameter settings.} 64 | 65 | \item{draw}{A logical value indicating whether graphics output 66 | should be produced.} 67 | 68 | \item{vp}{A Grid viewport object (or NULL).} 69 | } 70 | \value{ 71 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 72 | } 73 | \description{ 74 | \code{grid.pattern_image()} draws an image pattern onto the graphic device. 75 | } 76 | \details{ 77 | Here is a description of the \code{type} arguments: 78 | \describe{ 79 | \item{expand}{Scale the image beyond the bounding box and crop it such that 80 | the image fully covers the width and the height of the region.} 81 | \item{fit}{Scale the image such that either the width or the height of the image fits in the bounding box. 82 | Affected by \code{gravity}} 83 | \item{none}{Position a single image in the region without attempting to scale to the bounding box size. 84 | Affected by \code{scale} and \code{gravity}.} 85 | \item{squish}{Distort the image to cover the bounding box of the region.} 86 | \item{tile}{Repeat the image to cover the bounding box. Affected by \code{tile}.} 87 | } 88 | } 89 | \examples{ 90 | \donttest{# May emit a "CPU time > 2.5 times elapsed time" NOTE in a CRAN check 91 | if (requireNamespace("magick")) { 92 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 93 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 94 | logo_filename <- system.file("img", "Rlogo.png" , package = "png") 95 | grid.pattern_image(x_hex, y_hex, filename = logo_filename, type = "fit") 96 | } 97 | if (requireNamespace("magick")) { 98 | # "tile" `type` image pattern depends on `magick` functionality 99 | # which is not reliable across platforms 100 | grid::grid.newpage() 101 | try(grid.pattern_image(x_hex, y_hex, filename = logo_filename, 102 | type = "tile")) 103 | } 104 | } 105 | } 106 | \seealso{ 107 | \code{\link[=grid.pattern_placeholder]{grid.pattern_placeholder()}} is an image pattern that uses images 108 | downloaded from the internet. 109 | \code{\link[=reset_image_cache]{reset_image_cache()}} resets the image cache used by \code{grid.pattern_image()} 110 | and \code{\link[=grid.pattern_placeholder]{grid.pattern_placeholder()}}. 111 | } 112 | -------------------------------------------------------------------------------- /man/grid.pattern_magick.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-array-magick.R 3 | \docType{data} 4 | \name{grid.pattern_magick} 5 | \alias{grid.pattern_magick} 6 | \alias{names_magick} 7 | \alias{names_magick_intensity} 8 | \alias{names_magick_stripe} 9 | \title{Magick patterned grobs} 10 | \format{ 11 | An object of class \code{character} of length 54. 12 | 13 | An object of class \code{character} of length 21. 14 | 15 | An object of class \code{character} of length 19. 16 | } 17 | \usage{ 18 | grid.pattern_magick( 19 | x = c(0, 0, 1, 1), 20 | y = c(1, 0, 0, 1), 21 | id = 1L, 22 | ..., 23 | type = "hexagons", 24 | fill = "grey20", 25 | scale = 1, 26 | filter = "box", 27 | alpha = gp$alpha \%||\% NA_real_, 28 | aspect_ratio = 1, 29 | key_scale_factor = 1, 30 | res = getOption("ggpattern_res", 72), 31 | default.units = "npc", 32 | name = NULL, 33 | gp = gpar(), 34 | draw = TRUE, 35 | vp = NULL 36 | ) 37 | 38 | names_magick 39 | 40 | names_magick_intensity 41 | 42 | names_magick_stripe 43 | } 44 | \arguments{ 45 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 46 | 47 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 48 | 49 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 50 | All locations within the same \code{id} belong to the same boundary.} 51 | 52 | \item{...}{Currently ignored.} 53 | 54 | \item{type}{Magick pattern types. \code{names_magick}, \code{names_magick_intensity}, and 55 | \code{names_magick_stripe} are character vectors of supported \code{type} values 56 | plus subsets for shaded intensity and stripes.} 57 | 58 | \item{fill}{Fill colour} 59 | 60 | \item{scale}{Extra scaling} 61 | 62 | \item{filter}{Filter to use when scaling. \code{magick::filter_types()} returns a vector of supported values.} 63 | 64 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 65 | 66 | \item{aspect_ratio}{Override aspect ratio.} 67 | 68 | \item{key_scale_factor}{Additional scale factor for legend.} 69 | 70 | \item{res}{Assumed resolution (in pixels per graphic device inch) to use when creating array pattern.} 71 | 72 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 73 | are only given as numeric vectors.} 74 | 75 | \item{name}{ A character identifier. } 76 | 77 | \item{gp}{An object of class \code{"gpar"}, typically the output 78 | from a call to the function \code{\link[grid]{gpar}}. This is basically 79 | a list of graphical parameter settings.} 80 | 81 | \item{draw}{A logical value indicating whether graphics output 82 | should be produced.} 83 | 84 | \item{vp}{A Grid viewport object (or NULL).} 85 | } 86 | \value{ 87 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 88 | } 89 | \description{ 90 | \code{grid.pattern_magick()} draws a \code{imagemagick} pattern onto the graphic device. 91 | \code{names_magick}, \code{names_magick_intensity}, and 92 | \code{names_magick_stripe} are character vectors of supported \code{type} values 93 | plus subsets for shaded intensity and stripes. 94 | } 95 | \examples{ 96 | if (requireNamespace("magick")) { 97 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 98 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 99 | grid.pattern_magick(x_hex, y_hex, type="octagons", fill="blue", scale=2) 100 | } 101 | 102 | # supported magick pattern names 103 | print(names_magick) 104 | } 105 | \seealso{ 106 | The \code{imagemagick} documentation \url{http://www.imagemagick.org/script/formats.php} for more information. 107 | } 108 | \keyword{datasets} 109 | -------------------------------------------------------------------------------- /man/grid.pattern_none.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-geometry-none.R 3 | \name{grid.pattern_none} 4 | \alias{grid.pattern_none} 5 | \title{Grobs without any pattern} 6 | \usage{ 7 | grid.pattern_none( 8 | x = c(0, 0, 1, 1), 9 | y = c(1, 0, 0, 1), 10 | id = 1L, 11 | ..., 12 | default.units = "npc", 13 | name = NULL, 14 | gp = gpar(), 15 | draw = TRUE, 16 | vp = NULL 17 | ) 18 | } 19 | \arguments{ 20 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 21 | 22 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 23 | 24 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 25 | All locations within the same \code{id} belong to the same boundary.} 26 | 27 | \item{...}{Currently ignored} 28 | 29 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 30 | are only given as numeric vectors.} 31 | 32 | \item{name}{ A character identifier. } 33 | 34 | \item{gp}{An object of class \code{"gpar"}, typically the output 35 | from a call to the function \code{\link[grid]{gpar}}. This is basically 36 | a list of graphical parameter settings.} 37 | 38 | \item{draw}{A logical value indicating whether graphics output 39 | should be produced.} 40 | 41 | \item{vp}{A Grid viewport object (or NULL).} 42 | } 43 | \value{ 44 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 45 | } 46 | \description{ 47 | \code{grid.pattern_none()} draws nothing onto the graphic device. 48 | } 49 | \examples{ 50 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 51 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 52 | grid.pattern_none(x_hex, y_hex) 53 | } 54 | \seealso{ 55 | \code{\link[grid:grid.null]{grid::grid.null()}} 56 | } 57 | -------------------------------------------------------------------------------- /man/grid.pattern_placeholder.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-array-placeholder.R 3 | \docType{data} 4 | \name{grid.pattern_placeholder} 5 | \alias{grid.pattern_placeholder} 6 | \alias{names_placeholder} 7 | \title{Placeholder image patterned grobs} 8 | \format{ 9 | An object of class \code{character} of length 22. 10 | } 11 | \usage{ 12 | grid.pattern_placeholder( 13 | x = c(0, 0, 1, 1), 14 | y = c(1, 0, 0, 1), 15 | id = 1L, 16 | ..., 17 | type = "bear", 18 | alpha = gp$alpha \%||\% NA_real_, 19 | aspect_ratio = 1, 20 | key_scale_factor = 1, 21 | res = getOption("ggpattern_res", 72), 22 | default.units = "npc", 23 | name = NULL, 24 | gp = gpar(), 25 | draw = TRUE, 26 | vp = NULL 27 | ) 28 | 29 | names_placeholder 30 | } 31 | \arguments{ 32 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 33 | 34 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 35 | 36 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 37 | All locations within the same \code{id} belong to the same boundary.} 38 | 39 | \item{...}{Currently ignored.} 40 | 41 | \item{type}{Image source. \code{names_placeholder} is a vector of supported values. 42 | If you would like only greyscale images append \code{bw} to the name.} 43 | 44 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 45 | 46 | \item{aspect_ratio}{Override aspect ratio.} 47 | 48 | \item{key_scale_factor}{Additional scale factor for legend.} 49 | 50 | \item{res}{Assumed resolution (in pixels per graphic device inch) to use when creating array pattern.} 51 | 52 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 53 | are only given as numeric vectors.} 54 | 55 | \item{name}{ A character identifier. } 56 | 57 | \item{gp}{An object of class \code{"gpar"}, typically the output 58 | from a call to the function \code{\link[grid]{gpar}}. This is basically 59 | a list of graphical parameter settings.} 60 | 61 | \item{draw}{A logical value indicating whether graphics output 62 | should be produced.} 63 | 64 | \item{vp}{A Grid viewport object (or NULL).} 65 | } 66 | \value{ 67 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 68 | } 69 | \description{ 70 | \code{grid.pattern_placeholder()} draws a placeholder image pattern onto the graphic device. 71 | \code{names_placeholder} are character vectors of supported placeholder types. 72 | } 73 | \examples{ 74 | if (requireNamespace("magick")) { 75 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 76 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 77 | # requires internet connection to download from placeholder image websites 78 | try(grid.pattern_placeholder(x_hex, y_hex, type="bear")) 79 | } 80 | 81 | print(names_placeholder) 82 | } 83 | \seealso{ 84 | \code{\link[=reset_image_cache]{reset_image_cache()}} resets the image cache used by \code{\link[=grid.pattern_image]{grid.pattern_image()}} and \code{grid.pattern_placeholder()}. 85 | } 86 | \keyword{datasets} 87 | -------------------------------------------------------------------------------- /man/grid.pattern_plasma.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-array-plasma.R 3 | \name{grid.pattern_plasma} 4 | \alias{grid.pattern_plasma} 5 | \title{Plasma patterned grobs} 6 | \usage{ 7 | grid.pattern_plasma( 8 | x = c(0, 0, 1, 1), 9 | y = c(1, 0, 0, 1), 10 | id = 1L, 11 | ..., 12 | fill = gp$fill \%||\% "grey80", 13 | scale = 1, 14 | alpha = gp$alpha \%||\% NA_real_, 15 | aspect_ratio = 1, 16 | key_scale_factor = 1, 17 | res = getOption("ggpattern_res", 72), 18 | default.units = "npc", 19 | name = NULL, 20 | gp = gpar(), 21 | draw = TRUE, 22 | vp = NULL 23 | ) 24 | } 25 | \arguments{ 26 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 27 | 28 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 29 | 30 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 31 | All locations within the same \code{id} belong to the same boundary.} 32 | 33 | \item{...}{Currently ignored.} 34 | 35 | \item{fill}{Colour.} 36 | 37 | \item{scale}{Extra scaling} 38 | 39 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 40 | 41 | \item{aspect_ratio}{Override aspect ratio.} 42 | 43 | \item{key_scale_factor}{Additional scale factor for legend.} 44 | 45 | \item{res}{Assumed resolution (in pixels per graphic device inch) to use when creating array pattern.} 46 | 47 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 48 | are only given as numeric vectors.} 49 | 50 | \item{name}{ A character identifier. } 51 | 52 | \item{gp}{An object of class \code{"gpar"}, typically the output 53 | from a call to the function \code{\link[grid]{gpar}}. This is basically 54 | a list of graphical parameter settings.} 55 | 56 | \item{draw}{A logical value indicating whether graphics output 57 | should be produced.} 58 | 59 | \item{vp}{A Grid viewport object (or NULL).} 60 | } 61 | \value{ 62 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 63 | } 64 | \description{ 65 | \code{grid.pattern_plasma()} draws a plasma pattern onto the graphic device. 66 | } 67 | \examples{ 68 | if (requireNamespace("magick")) { 69 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 70 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 71 | grid.pattern_plasma(x_hex, y_hex, fill = "green") 72 | } 73 | } 74 | \seealso{ 75 | \code{\link[=grid.pattern_ambient]{grid.pattern_ambient()}} provides a noise pattern using the \code{ambient} package. 76 | Pseudorandom seeds for the plasma pattern may be set via \code{\link[magick:config]{magick::magick_set_seed()}}. 77 | } 78 | -------------------------------------------------------------------------------- /man/grid.pattern_stripe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-geometry-stripe.R 3 | \name{grid.pattern_stripe} 4 | \alias{grid.pattern_stripe} 5 | \title{Stripe patterned grobs} 6 | \usage{ 7 | grid.pattern_stripe( 8 | x = c(0, 0, 1, 1), 9 | y = c(1, 0, 0, 1), 10 | id = 1L, 11 | ..., 12 | colour = gp$col \%||\% "grey20", 13 | fill = gp$fill \%||\% "grey80", 14 | angle = 30, 15 | density = 0.2, 16 | spacing = 0.05, 17 | xoffset = 0, 18 | yoffset = 0, 19 | units = "snpc", 20 | alpha = gp$alpha \%||\% NA_real_, 21 | linetype = gp$lty \%||\% 1, 22 | linewidth = size \%||\% gp$lwd \%||\% 1, 23 | size = NULL, 24 | grid = "square", 25 | default.units = "npc", 26 | name = NULL, 27 | gp = gpar(), 28 | draw = TRUE, 29 | vp = NULL 30 | ) 31 | } 32 | \arguments{ 33 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 34 | 35 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 36 | 37 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 38 | All locations within the same \code{id} belong to the same boundary.} 39 | 40 | \item{...}{Currently ignored.} 41 | 42 | \item{colour}{Stroke colour(s).} 43 | 44 | \item{fill}{Fill colour(s) or \code{\link[grid:patterns]{grid::pattern()}} / gradient object(s).} 45 | 46 | \item{angle}{Rotation angle in degrees.} 47 | 48 | \item{density}{Approx. fraction of area the pattern fills.} 49 | 50 | \item{spacing}{Spacing between repetitions of pattern (in \code{units} units).} 51 | 52 | \item{xoffset}{Shift pattern along x axis (in \code{units} units).} 53 | 54 | \item{yoffset}{Shift pattern along y axis (in \code{units} units).} 55 | 56 | \item{units}{\code{\link[grid:unit]{grid::unit()}} units for \code{spacing}, \code{xoffset}, and \code{yoffset} parameters.} 57 | 58 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 59 | 60 | \item{linetype}{Stroke linetype.} 61 | 62 | \item{linewidth}{Stroke linewidth.} 63 | 64 | \item{size}{For backwards compatibility can be used to set \code{linewidth}.} 65 | 66 | \item{grid}{Adjusts placement and density of certain graphical elements. 67 | \code{"square"} (default) is a square grid. 68 | \code{"hex"} is a hexagonal grid suitable for hexagonal and triangular tiling. 69 | \code{"hex_circle"} is a hexagonal grid suitable for circle packing. 70 | \code{"elongated_triangle"} is a grid used for the "elongated triangle" tiling.} 71 | 72 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 73 | are only given as numeric vectors.} 74 | 75 | \item{name}{ A character identifier. } 76 | 77 | \item{gp}{An object of class \code{"gpar"}, typically the output 78 | from a call to the function \code{\link[grid]{gpar}}. This is basically 79 | a list of graphical parameter settings.} 80 | 81 | \item{draw}{A logical value indicating whether graphics output 82 | should be produced.} 83 | 84 | \item{vp}{A Grid viewport object (or NULL).} 85 | } 86 | \value{ 87 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 88 | } 89 | \description{ 90 | \code{grid.pattern_stripe()} draws a stripe pattern onto the graphic device. 91 | } 92 | \examples{ 93 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 94 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 95 | grid.pattern_stripe(x_hex, y_hex, colour = "black", 96 | fill = c("red", "blue"), density = 0.4) 97 | 98 | # Can alternatively use "gpar()" to specify colour and line attributes 99 | grid::grid.newpage() 100 | grid.pattern_stripe(x_hex, y_hex, density = 0.3, 101 | gp = grid::gpar(col = "blue", fill = "yellow")) 102 | } 103 | \seealso{ 104 | \verb{[grid.pattern_crosshatch()]} and \verb{[grid.pattern_weave()]} for overlaying stripes. 105 | } 106 | -------------------------------------------------------------------------------- /man/grid.pattern_wave.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-geometry-wave.R 3 | \name{grid.pattern_wave} 4 | \alias{grid.pattern_wave} 5 | \title{Wave patterned grobs} 6 | \usage{ 7 | grid.pattern_wave( 8 | x = c(0, 0, 1, 1), 9 | y = c(1, 0, 0, 1), 10 | id = 1L, 11 | ..., 12 | colour = gp$col \%||\% "grey20", 13 | fill = gp$fill \%||\% "grey80", 14 | angle = 30, 15 | density = 0.2, 16 | spacing = 0.05, 17 | xoffset = 0, 18 | yoffset = 0, 19 | units = "snpc", 20 | amplitude = 0.5 * spacing, 21 | frequency = 1/spacing, 22 | alpha = gp$alpha \%||\% NA_real_, 23 | linetype = gp$lty \%||\% 1, 24 | linewidth = size \%||\% gp$lwd \%||\% 1, 25 | size = NULL, 26 | grid = "square", 27 | type = "triangle", 28 | default.units = "npc", 29 | name = NULL, 30 | gp = gpar(), 31 | draw = TRUE, 32 | vp = NULL 33 | ) 34 | } 35 | \arguments{ 36 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 37 | 38 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 39 | 40 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 41 | All locations within the same \code{id} belong to the same boundary.} 42 | 43 | \item{...}{Currently ignored.} 44 | 45 | \item{colour}{Stroke colour(s).} 46 | 47 | \item{fill}{Fill colour(s) or \code{\link[grid:patterns]{grid::pattern()}} / gradient object(s).} 48 | 49 | \item{angle}{Rotation angle in degrees.} 50 | 51 | \item{density}{Approx. fraction of area the pattern fills.} 52 | 53 | \item{spacing}{Spacing between repetitions of pattern (in \code{units} units).} 54 | 55 | \item{xoffset}{Shift pattern along x axis (in \code{units} units).} 56 | 57 | \item{yoffset}{Shift pattern along y axis (in \code{units} units).} 58 | 59 | \item{units}{\code{\link[grid:unit]{grid::unit()}} units for \code{amplitude}, \code{frequency}, \code{spacing}, \code{xoffset}, and \code{yoffset} parameters.} 60 | 61 | \item{amplitude}{Wave amplitude (in \code{units} units)} 62 | 63 | \item{frequency}{Linear frequency (in inverse \code{units} units)} 64 | 65 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 66 | 67 | \item{linetype}{Stroke linetype.} 68 | 69 | \item{linewidth}{Stroke linewidth.} 70 | 71 | \item{size}{For backwards compatibility can be used to set \code{linewidth}.} 72 | 73 | \item{grid}{Adjusts placement and density of certain graphical elements. 74 | \code{"square"} (default) is a square grid. 75 | \code{"hex"} is a hexagonal grid suitable for hexagonal and triangular tiling. 76 | \code{"hex_circle"} is a hexagonal grid suitable for circle packing. 77 | \code{"elongated_triangle"} is a grid used for the "elongated triangle" tiling.} 78 | 79 | \item{type}{Either \dQuote{sine} or \dQuote{triangle} (default).} 80 | 81 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 82 | are only given as numeric vectors.} 83 | 84 | \item{name}{ A character identifier. } 85 | 86 | \item{gp}{An object of class \code{"gpar"}, typically the output 87 | from a call to the function \code{\link[grid]{gpar}}. This is basically 88 | a list of graphical parameter settings.} 89 | 90 | \item{draw}{A logical value indicating whether graphics output 91 | should be produced.} 92 | 93 | \item{vp}{A Grid viewport object (or NULL).} 94 | } 95 | \value{ 96 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 97 | } 98 | \description{ 99 | \code{grid.pattern_wave()} draws a wave pattern onto the graphic device. 100 | } 101 | \examples{ 102 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 103 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 104 | grid::grid.newpage() 105 | grid.pattern_wave(x_hex, y_hex, colour = "black", type = "sine", 106 | fill = c("red", "blue"), density = 0.4, 107 | spacing = 0.15, angle = 0, 108 | amplitude = 0.05, frequency = 1 / 0.20) 109 | 110 | # zig-zag pattern is a wave of `type` "triangle" 111 | grid::grid.newpage() 112 | grid.pattern_wave(x_hex, y_hex, colour = "black", type = "triangle", 113 | fill = c("red", "blue"), density = 0.4, 114 | spacing = 0.15, angle = 0, amplitude = 0.075) 115 | } 116 | \seealso{ 117 | Use \code{\link[=grid.pattern_stripe]{grid.pattern_stripe()}} for straight lines instead of waves. 118 | } 119 | -------------------------------------------------------------------------------- /man/grid.pattern_weave.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern-geometry-weave.R 3 | \name{grid.pattern_weave} 4 | \alias{grid.pattern_weave} 5 | \title{Weave patterned grobs} 6 | \usage{ 7 | grid.pattern_weave( 8 | x = c(0, 0, 1, 1), 9 | y = c(1, 0, 0, 1), 10 | id = 1L, 11 | ..., 12 | colour = gp$col \%||\% "grey20", 13 | fill = gp$fill \%||\% "grey80", 14 | fill2 = fill, 15 | angle = 30, 16 | density = 0.2, 17 | spacing = 0.05, 18 | xoffset = 0, 19 | yoffset = 0, 20 | units = "snpc", 21 | alpha = gp$alpha \%||\% NA_real_, 22 | linetype = gp$lty \%||\% 1, 23 | linewidth = size \%||\% gp$lwd \%||\% 1, 24 | size = NULL, 25 | grid = "square", 26 | type = "plain", 27 | subtype = NA, 28 | default.units = "npc", 29 | name = NULL, 30 | gp = gpar(), 31 | draw = TRUE, 32 | vp = NULL 33 | ) 34 | } 35 | \arguments{ 36 | \item{x}{A numeric vector or unit object specifying x-locations of the pattern boundary.} 37 | 38 | \item{y}{A numeric vector or unit object specifying y-locations of the pattern boundary.} 39 | 40 | \item{id}{A numeric vector used to separate locations in x, y into multiple boundaries. 41 | All locations within the same \code{id} belong to the same boundary.} 42 | 43 | \item{...}{Currently ignored.} 44 | 45 | \item{colour}{Stroke colour(s).} 46 | 47 | \item{fill}{The fill colour for the horizontal "weft" lines.} 48 | 49 | \item{fill2}{The fill colour for the vertical "warp" lines.} 50 | 51 | \item{angle}{Rotation angle in degrees.} 52 | 53 | \item{density}{Approx. fraction of area the pattern fills.} 54 | 55 | \item{spacing}{Spacing between repetitions of pattern (in \code{units} units).} 56 | 57 | \item{xoffset}{Shift pattern along x axis (in \code{units} units).} 58 | 59 | \item{yoffset}{Shift pattern along y axis (in \code{units} units).} 60 | 61 | \item{units}{\code{\link[grid:unit]{grid::unit()}} units for \code{spacing}, \code{xoffset}, and \code{yoffset} parameters.} 62 | 63 | \item{alpha}{Alpha (between 0 and 1) or \code{NA} (default, preserves colors' alpha value).} 64 | 65 | \item{linetype}{Stroke linetype.} 66 | 67 | \item{linewidth}{Stroke linewidth.} 68 | 69 | \item{size}{For backwards compatibility can be used to set \code{linewidth}.} 70 | 71 | \item{grid}{Adjusts placement and density of certain graphical elements. 72 | \code{"square"} (default) is a square grid. 73 | \code{"hex"} is a hexagonal grid suitable for hexagonal and triangular tiling. 74 | \code{"hex_circle"} is a hexagonal grid suitable for circle packing. 75 | \code{"elongated_triangle"} is a grid used for the "elongated triangle" tiling.} 76 | 77 | \item{type}{The weave type. See \code{\link[=pattern_weave]{pattern_weave()}} for more details.} 78 | 79 | \item{subtype}{The weave subtype. See \code{\link[=pattern_weave]{pattern_weave()}} for more details.} 80 | 81 | \item{default.units}{A string indicating the default units to use if \code{x} or \code{y} 82 | are only given as numeric vectors.} 83 | 84 | \item{name}{ A character identifier. } 85 | 86 | \item{gp}{An object of class \code{"gpar"}, typically the output 87 | from a call to the function \code{\link[grid]{gpar}}. This is basically 88 | a list of graphical parameter settings.} 89 | 90 | \item{draw}{A logical value indicating whether graphics output 91 | should be produced.} 92 | 93 | \item{vp}{A Grid viewport object (or NULL).} 94 | } 95 | \value{ 96 | A grid grob object invisibly. If \code{draw} is \code{TRUE} then also draws to the graphic device as a side effect. 97 | } 98 | \description{ 99 | \code{grid.pattern_weave()} draws a weave pattern onto the graphic device. 100 | } 101 | \examples{ 102 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 103 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 104 | gp <- grid::gpar(colour = "black", fill = "lightblue", lwd=0.5) 105 | 106 | # Plain weave (default weave) 107 | grid.pattern_weave(x_hex, y_hex, fill2 = "yellow", 108 | gp = gp, spacing = 0.1, density = 0.3) 109 | 110 | # Irregular matt weave 111 | grid::grid.newpage() 112 | grid.pattern_weave(x_hex, y_hex, type = "matt_irregular", 113 | fill2 = "yellow", gp = gp, spacing = 0.1, density = 0.3) 114 | 115 | # Twill weave 116 | grid::grid.newpage() 117 | grid.pattern_weave(x_hex, y_hex, type = "twill", 118 | fill2 = "yellow", gp = gp, spacing = 0.1, density = 0.3) 119 | 120 | # Zig-zag twill 121 | grid::grid.newpage() 122 | grid.pattern_weave(x_hex, y_hex, type = "twill_zigzag", 123 | fill2 = "yellow", gp = gp, spacing = 0.05, density = 0.7) 124 | 125 | # Herringbone twill with density 1 126 | grid::grid.newpage() 127 | gp$col <- NA 128 | grid.pattern_weave(x_hex, y_hex, type = "twill_herringbone", 129 | fill2 = "yellow", gp = gp, spacing = 0.05, density = 1.0) 130 | } 131 | \seealso{ 132 | \code{\link[=pattern_weave]{pattern_weave()}} 133 | } 134 | -------------------------------------------------------------------------------- /man/gridpattern-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/gridpattern-package.R 3 | \docType{package} 4 | \name{gridpattern-package} 5 | \alias{gridpattern} 6 | \alias{gridpattern-package} 7 | \title{gridpattern: 'grid' Pattern Grobs} 8 | \description{ 9 | \if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}} 10 | 11 | Provides 'grid' grobs that fill in a user-defined area with various patterns. Includes enhanced versions of the geometric and image-based patterns originally contained in the 'ggpattern' package as well as original 'pch', 'polygon_tiling', 'regular_polygon', 'rose', 'text', 'wave', and 'weave' patterns plus support for custom user-defined patterns. 12 | } 13 | \section{Package options}{ 14 | 15 | The following \code{gridpattern} options may be set globally via \code{\link[base:options]{base::options()}}: 16 | \describe{ 17 | \item{ggpattern_array_funcs}{Set custom \dQuote{array} pattern functions.} 18 | \item{ggpattern_geometry_funcs}{Set custom \dQuote{geometry} pattern functions.} 19 | \item{ggpattern_res}{Set custom raster image resolution (pixels per inch) for certain patterns.} 20 | \item{ggpattern_use_R4.1_clipping}{If \code{TRUE} use the grid clipping path feature introduced in R v4.1.0. 21 | If \code{FALSE} do a \code{rasterGrob} approximation of the clipped pattern. 22 | If \code{NULL} try to guess an appropriate choice.} 23 | \item{ggpattern_use_R4.1_features}{If \code{TRUE} sets the default for all the other 24 | \verb{ggpattern_use_R4.1_*} options arguments to \code{TRUE}. 25 | If \code{FALSE} sets them to \code{FALSE}.} 26 | \item{ggpattern_use_R4.1_gradients}{If \code{TRUE} use the grid gradient feature introduced in R v4.1.0. 27 | If \code{FALSE} do a \code{rasterGrob} approximation of the gradient pattern. 28 | If \code{NULL} try to guess an appropriate choice.} 29 | \item{ggpattern_use_R4.1_masks}{If \code{TRUE} use the grid mask feature introduced in R v4.1.0. 30 | If \code{FALSE} do a \code{rasterGrob} approximation of the masked pattern. 31 | If \code{NULL} try to guess an appropriate choice.} 32 | \item{ggpattern_use_R4.1_patterns}{If \code{TRUE} use the grid pattern feature introduced in R v4.1.0. 33 | Currently only used by a couple of examples.} 34 | } 35 | Note to use the R v4.1.0 features one needs R be (at least) version 4.1 and not all graphic devices 36 | support any/all these features. See \url{https://www.stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/definitions/definitions.html} for more information on these features. 37 | } 38 | 39 | \seealso{ 40 | Useful links: 41 | \itemize{ 42 | \item \url{https://trevorldavis.com/R/gridpattern/} 43 | \item \url{https://github.com/trevorld/gridpattern} 44 | \item Report bugs at \url{https://github.com/trevorld/gridpattern/issues} 45 | } 46 | 47 | } 48 | \author{ 49 | \strong{Maintainer}: Trevor L. Davis \email{trevor.l.davis@gmail.com} (\href{https://orcid.org/0000-0001-6341-4639}{ORCID}) 50 | 51 | Authors: 52 | \itemize{ 53 | \item Mike FC (Code/docs adapted from ggpattern) 54 | } 55 | 56 | Other contributors: 57 | \itemize{ 58 | \item ggplot2 authors (some utility functions copied from ggplot2) [contributor] 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /man/guess_has_R4.1_features.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/z_guess_has_R4.1_features_docs.R 3 | \name{guess_has_R4.1_features} 4 | \alias{guess_has_R4.1_features} 5 | \title{Guess whether "active" graphics device supports 6 | the grid graphics features introduced in R v4.1.} 7 | \usage{ 8 | guess_has_R4.1_features( 9 | features = c("clippingPaths", "gradients", "masks", "patterns") 10 | ) 11 | } 12 | \arguments{ 13 | \item{features}{Character vector of features to guess support for. 14 | Will return \code{TRUE} only if guesses support for all requested features.\describe{ 15 | \item{"clippingPaths"}{Supports clipping path feature} 16 | \item{"gradients"}{Supports (both linear and radial) gradient feature} 17 | \item{"masks"}{Supports (alpha) mask feature} 18 | \item{"patterns"}{Supports (tiling) pattern feature} 19 | }} 20 | } 21 | \value{ 22 | \code{TRUE} if we guess all \code{features} are supported else \code{FALSE} 23 | } 24 | \description{ 25 | \code{guess_has_R4.1_features()} guesses whether "active" graphics device supports 26 | the grid graphics features introduced in R v4.1. If it guesses it does 27 | it returns \code{TRUE} else \code{FALSE}. 28 | } 29 | \section{Usage in other packages}{ 30 | 31 | 32 | To avoid taking a dependency on \code{gridpattern} you may copy the source of \code{guess_has_R4.1_features()} 33 | into your own package under the permissive MIT No Attribution (MIT-0) license. Either use 34 | \code{usethis::use_standalone("trevorld/gridpattern", "standalone-guess_has_R4.1_features.R")} 35 | or copy the file \code{standalone-guess_has_R4.1_features.R} into your \code{R} directory and 36 | add \code{grDevices} and \code{utils} to the \code{Imports} of your \code{DESCRIPTION} file. 37 | } 38 | 39 | \examples{ 40 | # If R version (weakly) greater than 4.1 should be TRUE 41 | pdf(tempfile(fileext = ".pdf")) 42 | print(guess_has_R4.1_features()) 43 | invisible(dev.off()) 44 | 45 | # Should be FALSE 46 | postscript(tempfile(fileext = ".ps")) 47 | print(guess_has_R4.1_features()) 48 | invisible(dev.off()) 49 | 50 | } 51 | \seealso{ 52 | \url{https://www.stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/definitions/definitions.html} for more info about the new grid graphics 53 | features introduced in R v4.1. 54 | } 55 | -------------------------------------------------------------------------------- /man/mean_col.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mean_col.R 3 | \name{mean_col} 4 | \alias{mean_col} 5 | \title{Compute average color} 6 | \usage{ 7 | mean_col(...) 8 | } 9 | \arguments{ 10 | \item{...}{Colors to average} 11 | } 12 | \value{ 13 | A color string of 9 characters: \code{"#"} followed by the 14 | red, blue, green, and alpha values in hexadecimal. 15 | } 16 | \description{ 17 | \code{mean_col()} computes an average color. 18 | } 19 | \details{ 20 | We currently compute an average color 21 | by using the quadratic mean of the colors' RGBA values. 22 | } 23 | \examples{ 24 | mean_col("black", "white") 25 | mean_col(c("black", "white")) 26 | mean_col("red", "blue") 27 | } 28 | -------------------------------------------------------------------------------- /man/patternFill.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/grid-pattern-fill.R 3 | \name{patternFill} 4 | \alias{patternFill} 5 | \title{Create patterned fills by pattern name} 6 | \usage{ 7 | patternFill( 8 | ..., 9 | x = 0.5, 10 | y = 0.5, 11 | width = 1, 12 | height = 1, 13 | default.units = "npc", 14 | just = "centre", 15 | hjust = NULL, 16 | vjust = NULL, 17 | group = TRUE 18 | ) 19 | } 20 | \arguments{ 21 | \item{...}{Passed to \code{\link[=patternGrob]{patternGrob()}}.} 22 | 23 | \item{x, y, width, height}{The size of the \code{\link[grid:patterns]{grid::pattern()}} tile.} 24 | 25 | \item{default.units}{The default \code{\link[grid:unit]{grid::unit()}} unit to use for \code{x}, \code{y}, \code{width}, and \code{height}.} 26 | 27 | \item{just, hjust, vjust}{The justification of the tile relative to its location.} 28 | 29 | \item{group}{A logical indicating whether the pattern is relative to the bounding box of the grob or whether it is relative to individual shapes within the grob. Ignored if R is less than version 4.2.} 30 | } 31 | \value{ 32 | A \code{\link[grid:patterns]{grid::pattern()}} fill object. 33 | } 34 | \description{ 35 | \code{patternFill()} returns \code{\link[grid:patterns]{grid::pattern()}} fill objects. 36 | It is a wrapper around \code{\link[=patternGrob]{patternGrob()}}. 37 | } 38 | \examples{ 39 | if (guess_has_R4.1_features("patterns") && 40 | require("grid", quietly = TRUE)) { 41 | grid.newpage() 42 | stripe_fill <- patternFill("stripe", fill = c("red", "blue")) 43 | grid.circle(gp = gpar(fill = stripe_fill)) 44 | } 45 | 46 | if (guess_has_R4.1_features("patterns") && 47 | require("ggplot2", quietly = TRUE) && 48 | (getRversion() >= "4.2")) { 49 | grid.newpage() 50 | weave_fill <- patternFill("weave", fill = "red", fill2 = "blue", 51 | colour = "transparent") 52 | hex_fill <- patternFill("polygon_tiling", type = "hexagonal", 53 | fill = c("black", "white", "grey"), 54 | colour = "transparent") 55 | df <- data.frame(trt = c("a", "b"), outcome = c(1.9, 3.2)) 56 | gg <- ggplot(df, aes(trt, outcome)) + 57 | geom_col(fill = list(weave_fill, hex_fill)) 58 | plot(gg) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /man/pattern_hex.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern_hex.R 3 | \docType{data} 4 | \name{pattern_hex} 5 | \alias{pattern_hex} 6 | \alias{names_hex} 7 | \title{Hex pattern matrix} 8 | \format{ 9 | An object of class \code{character} of length 5. 10 | } 11 | \usage{ 12 | pattern_hex(type = "hex", subtype = NULL, nrow = 5L, ncol = 5L) 13 | 14 | names_hex 15 | } 16 | \arguments{ 17 | \item{type}{Currently just supports "hex".} 18 | 19 | \item{subtype}{An integer indicating number of colors (or other graphical elements).} 20 | 21 | \item{nrow}{Number of rows (height).} 22 | 23 | \item{ncol}{Number of columns (width).} 24 | } 25 | \value{ 26 | A matrix of integer values indicating where the each color 27 | or other graphical elements should be drawn on a horizontal hex grid 28 | (i.e. hexagons are assumed to be pointy side up). 29 | Indices \verb{[1,1]} of the matrix corresponds to the bottom-left of the grid 30 | while indices \verb{[1,ncol]} corresponds to the bottom-right of the grid. 31 | The even rows are assumed to be on the \strong{left} of the ones on the odd rows 32 | (for those in the same column in the matrix). 33 | This matrix has a "pattern_hex" subclass which supports a special \code{print()} method. 34 | } 35 | \description{ 36 | \code{pattern_hex()} returns an integer matrix indicating where each 37 | color (or other graphical element) should be drawn on a (horizontal) hex grid 38 | for a specified hex pattern type and subtype. 39 | \code{names_hex} lists the currently supported hex \code{type}s. 40 | } 41 | \details{ 42 | \describe{ 43 | \item{"hex"}{Attempts to use a uniform coloring if it exists. 44 | For subtype \code{1L}, \code{2L}, and \code{3L} we use the "hex1" pattern. 45 | For subtype \code{4L} we use the "hex2" pattern. 46 | For subtype \code{7L} we use the "hex3" pattern. 47 | Else a uniform coloring does not exist and we use the "hex_skew" pattern.} 48 | \item{"hex1"}{Provides the 1-uniform colorings of a hexagonal tiling. Only exists for \code{subtype} \code{1L}, \code{2L}, or \code{3L}.} 49 | \item{"hex2"}{Provides the 2-uniform colorings of a hexagonal tiling. Only exists for \code{subtype} \code{2L} or \code{4L}.} 50 | \item{"hex3"}{Provides the 3-uniform colorings of a hexagonal tiling. Only exists for \code{subtype} \code{2L} or \code{7L}.} 51 | \item{"hex_skew"}{For the "hex_skew" \code{type} we cycle through \code{subtype} elements on the horizontal line and "main" diagonal line. 52 | For some \code{subtype} numbers this may lead to noticeable color repeats on the "skew" diagonal line. 53 | If \code{subtype} is strictly greater than \code{2L} then a hexagon should never touch another hexagon of the same color.} 54 | } 55 | } 56 | \examples{ 57 | # supported hex names 58 | print(names_hex) 59 | 60 | # 1-uniform 3-color 61 | hex_3color <- pattern_hex("hex1", 3L, nrow = 7L, ncol = 9L) 62 | print(hex_3color) 63 | 64 | # 2-uniform 4-color 65 | hex_4color <- pattern_hex("hex2", 4L, nrow = 7L, ncol = 9L) 66 | print(hex_4color) 67 | 68 | } 69 | \seealso{ 70 | \code{\link[=grid.pattern_regular_polygon]{grid.pattern_regular_polygon()}} for drawing to a graphics device 71 | hexagons, triangles, circles, etc. in hexagon patterns. 72 | The tiling vignette features several examples of regular polygon tiling using 73 | this both the "hex" and "hex_circle" types \code{vignette("tiling", package = "gridpattern")}. 74 | For more information on uniform colorings of a hexagonal tiling see 75 | \url{https://en.wikipedia.org/wiki/Hexagonal_tiling#Uniform_colorings}. 76 | } 77 | \keyword{datasets} 78 | -------------------------------------------------------------------------------- /man/pattern_square.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pattern_square.R 3 | \docType{data} 4 | \name{pattern_square} 5 | \alias{pattern_square} 6 | \alias{names_square} 7 | \title{Square pattern matrix} 8 | \format{ 9 | An object of class \code{character} of length 6. 10 | } 11 | \usage{ 12 | pattern_square(type = "diagonal", subtype = NULL, nrow = 5L, ncol = 5L) 13 | 14 | names_square 15 | } 16 | \arguments{ 17 | \item{type}{Either "diagonal" (default), "diagonal_skew", "horizontal", "vertical", 18 | or any \code{type} in \code{names_weave}. See Details.} 19 | 20 | \item{subtype}{See Details. For "diagonal", "diagonal_skew", "horizontal", or "vertical" 21 | an integer of the desired number of colors (or other graphical elements).} 22 | 23 | \item{nrow}{Number of rows (height).} 24 | 25 | \item{ncol}{Number of columns (width).} 26 | } 27 | \value{ 28 | A matrix of integer values indicating where the each color 29 | (or other graphical element) should be drawn on a rectangular grid. 30 | Indices \verb{[1,1]} of the matrix corresponds to the bottom-left of the grid 31 | while indices \verb{[1,ncol]} corresponds to the bottom-right of the grid. 32 | This matrix has a "pattern_square" subclass which supports a special \code{print()} method. 33 | } 34 | \description{ 35 | \code{pattern_square()} returns an integer matrix indicating where each 36 | color (or other graphical element) should be drawn on a rectangular grid 37 | for a specified square pattern type and subtype. 38 | \code{names_square} lists the currently supported square \code{type}s (excluding those in \code{names_weave}). 39 | } 40 | \details{ 41 | \describe{ 42 | \item{"horizontal", "vertical"}{"horizontal" and "vertical" simply cycle through the colors 43 | either horizontally or vertically. 44 | Use \code{subtype} to indicate the (integer) number of colors (or other graphical elements). 45 | "horizontal" will produce horizontal stripes of color whereas "vertical" will produce vertical stripes.} 46 | \item{"diagonal", "diagonal_skew"}{"diagonal" and "diagonal_skew" simply cycle through the colors 47 | both horizontally and vertically. 48 | Use \code{subtype} to indicate the (integer) number of colors (or other graphical elements). 49 | If two colors are requested this provides the standard two-color checkerboard pattern. 50 | If there are more than three colors than "diagonal" will have colored diagonals 51 | going from top left to bottom right while "diagonal_skew" will have them 52 | going form bottom left to top right.} 53 | \item{"square"}{"square" attempts a uniform coloring using "square_tiling" before falling 54 | falling back on "diagonal". If \code{subtype} is \code{1L}, \code{2L}, \code{3L}, or \code{4L} uses "square_tiling" 55 | else uses "diagonal".} 56 | \item{"square_tiling"}{"square_tiling" supports 57 | uniform coloring for (non-staggered) square tilings. 58 | Use \code{subtype} to either indicate the (integer) number of colors 59 | or a string with four integers such as \code{"1231"} 60 | (will fill in a 2x2 matrix by row which will then be tiled). 61 | Supports up to a max of four colors.} 62 | \item{any pattern from \code{names_weave}}{ 63 | We simply convert the logical matrix returned by \code{\link[=pattern_weave]{pattern_weave()}} into an 64 | integer matrix by having any \code{TRUE} set to \code{1L} and \code{FALSE} set to \code{2L}. 65 | Hence the various weave patterns only support (up to) two-color patterns. 66 | See \code{\link[=pattern_weave]{pattern_weave()}} for more details about supported \code{type} and \code{subtype}.} 67 | } 68 | } 69 | \examples{ 70 | # supported square names 71 | print(names_square) 72 | 73 | # (main) diagonal has colors going from top left to bottom right 74 | diagonal <- pattern_square("diagonal", 4L, nrow = 7L, ncol = 9L) 75 | print(diagonal) 76 | 77 | # skew diagonal has colors going from bottom left to top right 78 | skew <- pattern_square("diagonal_skew", 4L, nrow = 7L, ncol = 9L) 79 | print(skew) 80 | 81 | horizontal <- pattern_square("horizontal", 4L, nrow = 8L, ncol = 8L) 82 | print(horizontal) 83 | 84 | vertical <- pattern_square("vertical", 4L, nrow = 8L, ncol = 8L) 85 | print(vertical) 86 | 87 | # uniform coloring using 4 colors 88 | color4 <- pattern_square("square_tiling", 4L, nrow = 7L, ncol = 9L) 89 | print(color4) 90 | 91 | # uniform coloring using 3 colors 92 | color3 <- pattern_square("square_tiling", 3L, nrow = 7L, ncol = 9L) 93 | print(color3) 94 | 95 | # also supports the various 'weave' patterns 96 | zigzag <- pattern_square("twill_zigzag", nrow = 15L, ncol = 9L) 97 | print(zigzag) 98 | 99 | } 100 | \seealso{ 101 | \code{\link[=grid.pattern_regular_polygon]{grid.pattern_regular_polygon()}} for drawing to a graphics device 102 | polygons in multiple color/size/shape patterns. 103 | \code{\link[=pattern_weave]{pattern_weave()}} for more information on "weave" patterns. 104 | } 105 | \keyword{datasets} 106 | -------------------------------------------------------------------------------- /man/reset_image_cache.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/reset_image_cache.R 3 | \name{reset_image_cache} 4 | \alias{reset_image_cache} 5 | \title{Reset 'gridpattern' image cache} 6 | \usage{ 7 | reset_image_cache() 8 | } 9 | \description{ 10 | \code{\link[=grid.pattern_image]{grid.pattern_image()}} and \code{\link[=grid.pattern_placeholder]{grid.pattern_placeholder()}} store images in a cache 11 | (so we won't download image URLs over and over). 12 | \code{reset_image_cache()} resets this cache. 13 | } 14 | -------------------------------------------------------------------------------- /man/star_scale.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/star_scale.R 3 | \name{star_scale} 4 | \alias{star_scale} 5 | \alias{star_angle} 6 | \title{Compute regular star polygon scale or angles} 7 | \usage{ 8 | star_scale(n_vertices, angle, external = FALSE) 9 | 10 | star_angle(n_vertices, scale, external = FALSE) 11 | } 12 | \arguments{ 13 | \item{n_vertices}{Number of exterior vertices.} 14 | 15 | \item{angle}{Angle in degrees.} 16 | 17 | \item{external}{If \code{TRUE} angle should be considered an external angle.} 18 | 19 | \item{scale}{Scale from 0 to 1.} 20 | } 21 | \value{ 22 | \code{star_scale()} returns a numeric value between 0 and 1 intended 23 | for use as the \code{scale} argument in \code{\link[=grid.pattern_regular_polygon]{grid.pattern_regular_polygon()}}. 24 | \code{star_angle()} returns a numeric value between 0 and 360 (degrees). 25 | } 26 | \description{ 27 | \code{star_scale()} computes star \code{scale} value given 28 | an internal or external angle. \code{star_angle()} computes 29 | star angle (internal or external) given a \code{scale} value. 30 | } 31 | \details{ 32 | \code{\link[=grid.pattern_regular_polygon]{grid.pattern_regular_polygon()}} parameterizes regular star polygons 33 | with the number of its external vertices and a \code{scale} that equals the 34 | fraction of the radius of the circle that circumscribes the interior vertices 35 | divided by the radius of the circle that circumscribes the exterior vertices. 36 | These helper functions help convert between that parameterization 37 | and either the internal or external angle of the regular star polygon. 38 | } 39 | \examples{ 40 | # |8/3| star has internal angle 45 degrees and external angle 90 degrees 41 | scale <- star_scale(8, 45) 42 | scale2 <- star_scale(8, 90, external = TRUE) 43 | all.equal(scale, scale2) 44 | star_angle(8, scale) 45 | star_angle(8, scale, external = TRUE) 46 | 47 | grid.pattern_regular_polygon(shape = "star8", scale = scale, angle = 0, 48 | spacing = 0.2, density = 0.8) 49 | } 50 | -------------------------------------------------------------------------------- /man/update_alpha.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/z_update_alpha_docs.R 3 | \name{update_alpha} 4 | \alias{update_alpha} 5 | \title{Update colour and/or pattern transparency} 6 | \usage{ 7 | update_alpha(fill, alpha) 8 | } 9 | \arguments{ 10 | \item{fill}{A fill colour given as a \code{character} or \code{integer} vector, or as a 11 | (list of) \verb{} object(s) and/or colour(s).} 12 | 13 | \item{alpha}{A transparency value between 0 (transparent) and 1 (opaque), 14 | parallel to \code{fill}.} 15 | } 16 | \value{ 17 | A \code{character} vector of colours or list of \verb{} objects. 18 | } 19 | \description{ 20 | \code{update_alpha()} modifies the transparency of colours and/or patterns. 21 | } 22 | \details{ 23 | \itemize{ 24 | \item This is a fork of pattern utilities mainly added to \code{{ggplot2}} by Teun van den Brand. 25 | \item \code{update_alpha()} does not depend on \code{{ggplot2}} or \code{{scales}}. 26 | \item Like \code{\link[ggplot2:fill_alpha]{ggplot2::fill_alpha()}} but unlike \code{\link[scales:alpha]{scales::alpha()}} it also attempts 27 | to set the transparency of \verb{} objects. 28 | \item Unlike \code{\link[ggplot2:fill_alpha]{ggplot2::fill_alpha()}} it will work on a list of length one 29 | containing a vector of color strings. 30 | } 31 | } 32 | \section{Usage in other packages}{ 33 | 34 | 35 | To avoid taking a dependency on \code{gridpattern} you may copy the source of \code{update_alpha()} 36 | into your own package under the permissive MIT license. Either use 37 | \code{usethis::use_standalone("trevorld/gridpattern", "standalone-update_alpha.R")} 38 | or copy the file \code{update_alpha.R} into your \code{R} directory and 39 | add \code{grDevices}, \code{grid}, and \code{rlang} to the \code{Imports} of your \code{DESCRIPTION} file. 40 | } 41 | 42 | \examples{ 43 | # Typical color input 44 | update_alpha("red", 0.5) 45 | 46 | # Pattern input 47 | if (getRversion() >= "4.2" && requireNamespace("grid", quietly = TRUE)) { 48 | update_alpha(list(grid::linearGradient()), 0.5) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /raw-data/logo.R: -------------------------------------------------------------------------------- 1 | library("grid") 2 | library("gridpattern") 3 | library("piecepackr") 4 | library("polyclip") 5 | 6 | draw_logo <- function(bleed = FALSE, cut = FALSE) { 7 | x_hex <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 8 | y_hex <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 9 | 10 | hex_xy <- list(x = x_hex, y = y_hex) 11 | bot_xy <- list(x = c(0, 0, 1, 1), y = 0/4 + c(0, 1/4, 1/4, 0)) 12 | low_xy <- list(x = c(0, 0, 1, 1), y = 1/4 + c(0, 1/4, 1/4, 0)) 13 | hih_xy <- list(x = c(0, 0, 1, 1), y = 2/4 + c(0, 1/4, 1/4, 0)) 14 | top_xy <- list(x = c(0, 0, 1, 1), y = 3/4 + c(0, 1/4, 1/4, 0)) 15 | if (bleed) { 16 | bot_xy$y <- bot_xy$y + c(0, 1, 1, 0) / 8 17 | top_xy$y <- top_xy$y - c(1, 0, 0, 1) / 8 18 | } 19 | 20 | bd_bot <- polyclip(hex_xy, bot_xy, "intersection")[[1]] 21 | bd_low <- polyclip(hex_xy, low_xy, "intersection")[[1]] 22 | bd_hih <- polyclip(hex_xy, hih_xy, "intersection")[[1]] 23 | bd_top <- polyclip(hex_xy, top_xy, "intersection")[[1]] 24 | 25 | # colorblind accessible scheme https://jfly.uni-koeln.de/color/ 26 | blue <- grDevices::rgb(0.35, 0.70, 0.90) 27 | yellow <- grDevices::rgb(0.95, 0.90, 0.25) 28 | red <- grDevices::rgb(0.80, 0.40, 0.00) 29 | green <- grDevices::rgb(0.00, 0.60, 0.50) 30 | orange <- grDevices::rgb(0.90, 0.60, 0.00) 31 | 32 | w <- 4.5 33 | 34 | grid.newpage() 35 | gp <- gpar(fill = yellow, col = "black") 36 | # grid.polygon(bd_bot$x, bd_bot$y, gp = gpar(fill = "white", col = NA)) 37 | grid.pattern_weave(bd_bot$x, bd_bot$y, fill2 = blue, 38 | type = "satin", density=0.3, angle = 45, gp=gp) 39 | gp <- gpar(fill = c(yellow, orange, red), col = "black") 40 | grid.pattern_regular_polygon(bd_top$x, bd_top$y, shape = "convex3", density = 1.33, 41 | grid = "hex_circle", gp = gp, 42 | spacing = 0.05, rot = 30, angle = 0) 43 | pushViewport(viewport(height = unit(w, "inches"))) 44 | gp <- gpar(fill = c(yellow, blue), col = "black") 45 | grid.pattern_regular_polygon(bd_low$x, bd_low$y, shape = "square", 46 | density = 1, angle = 0, spacing=0.125, gp = gp) 47 | gp <- gpar(fill = c(yellow, orange, red), col = "black") 48 | grid.pattern_regular_polygon(bd_hih$x, bd_hih$y, shape = "convex6", 49 | density = 1, angle = 0, grid = "hex", spacing=0.175, gp = gp, 50 | yoffset = -0.03, xoffset = -0.01) 51 | # grid.polygon(bd_top$x, bd_top$y, gp = gpar(fill = "white", col = NA)) 52 | popViewport() 53 | 54 | pushViewport(viewport(width=unit(w, "inches"), height = unit(w, "inches"))) 55 | gp = gpar(col = "black", fontsize = 50, fontfamily = "sans", fontface = "bold") 56 | yoffset <- 0.002 57 | grid.text("g", x=0.23, y=0.625 + yoffset, gp = gp) 58 | grid.text("r", x=0.40, y=0.625 + yoffset, gp = gp) 59 | grid.text("i", x=0.58, y=0.625 + yoffset, gp = gp) 60 | grid.text("d", x=0.75, y=0.625 + yoffset, gp = gp) 61 | 62 | xr <- range(x_hex) 63 | step <- (xr[2] - xr[1]) / 7 64 | x <- seq(xr[1] + step / 2, by = step, length.out = 7) 65 | yoffset <- -0.001 66 | gp = gpar(col = "black", fontsize = 48, fontfamily = "sans", fontface = "bold") 67 | grid.text("p", x=x[1], y=0.375 + yoffset, gp = gp) 68 | grid.text("a", x=x[2], y=0.375 + yoffset, gp = gp) 69 | grid.text("t", x=x[3], y=0.375 + yoffset, gp = gp) 70 | grid.text("t", x=x[4], y=0.375 + yoffset, gp = gp) 71 | grid.text("e", x=x[5], y=0.375 + yoffset, gp = gp) 72 | grid.text("r", x=x[6], y=0.375 + yoffset, gp = gp) 73 | grid.text("n", x=x[7], y=0.375 + yoffset, gp = gp) 74 | popViewport() 75 | 76 | if (!isTRUE(bleed) || isTRUE(cut)) { 77 | pushViewport(viewport(width=unit(w, "inches"), height = unit(w, "inches"))) 78 | hex <- pp_shape("convex6") 79 | grid.draw(hex$shape(gp = gpar(fill = NA, col = "white", lwd=4))) 80 | if(!isTRUE(bleed)) { 81 | grid.draw(hex$mat(mat_width = 0.01, gp = gpar(fill = "black", col = NA))) 82 | } 83 | popViewport() 84 | if (isTRUE(bleed)) { 85 | pushViewport(viewport(width=unit(5/6, "npc"), height=unit(5/6, "npc"))) 86 | grid.draw(hex$shape(gp = gpar(fill="transparent", col="orange"))) 87 | popViewport() 88 | } 89 | } 90 | } 91 | 92 | # svg("man/figures/logo.svg", width = w, height = w, bg = "transparent") 93 | # draw_logo() 94 | # dev.off() 95 | # 96 | # png("man/figures/logo.png", width = w, height = w, units = "in", res = 72, bg = "transparent") 97 | # draw_logo() 98 | # dev.off() 99 | 100 | png("raw-data/sticker_with_cutline.png", width = 5.125, height = 5.125, units = "in", res = 150, bg = "white") 101 | draw_logo(bleed = TRUE, cut = TRUE) 102 | dev.off() 103 | 104 | png("raw-data/sticker.png", width = 5.125, height = 5.125, units = "in", res = 150, bg = "white") 105 | draw_logo(bleed = TRUE, cut = FALSE) 106 | dev.off() 107 | -------------------------------------------------------------------------------- /tests/figs/array/alphaMaskGrob_cairo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/alphaMaskGrob_cairo.png -------------------------------------------------------------------------------- /tests/figs/array/alphaMaskGrob_feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/alphaMaskGrob_feature.png -------------------------------------------------------------------------------- /tests/figs/array/alphaMaskGrob_manual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/alphaMaskGrob_manual.png -------------------------------------------------------------------------------- /tests/figs/array/alphaMaskGrob_ragg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/alphaMaskGrob_ragg.png -------------------------------------------------------------------------------- /tests/figs/array/ambient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/ambient.png -------------------------------------------------------------------------------- /tests/figs/array/ambient_worley.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/ambient_worley.png -------------------------------------------------------------------------------- /tests/figs/array/clipGrob_cairo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/clipGrob_cairo.png -------------------------------------------------------------------------------- /tests/figs/array/clipGrob_feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/clipGrob_feature.png -------------------------------------------------------------------------------- /tests/figs/array/clipGrob_manual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/clipGrob_manual.png -------------------------------------------------------------------------------- /tests/figs/array/clipGrob_ragg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/clipGrob_ragg.png -------------------------------------------------------------------------------- /tests/figs/array/gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/gradient.png -------------------------------------------------------------------------------- /tests/figs/array/gradient_horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/gradient_horizontal.png -------------------------------------------------------------------------------- /tests/figs/array/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/image.png -------------------------------------------------------------------------------- /tests/figs/array/image_expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/image_expand.png -------------------------------------------------------------------------------- /tests/figs/array/image_none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/image_none.png -------------------------------------------------------------------------------- /tests/figs/array/image_squish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/image_squish.png -------------------------------------------------------------------------------- /tests/figs/array/image_tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/image_tile.png -------------------------------------------------------------------------------- /tests/figs/array/magick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/magick.png -------------------------------------------------------------------------------- /tests/figs/array/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/placeholder.png -------------------------------------------------------------------------------- /tests/figs/array/plasma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/plasma.png -------------------------------------------------------------------------------- /tests/figs/array/plasma_zero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/plasma_zero.png -------------------------------------------------------------------------------- /tests/figs/array/rose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/rose.png -------------------------------------------------------------------------------- /tests/figs/array/simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/simple.png -------------------------------------------------------------------------------- /tests/figs/array/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trevorld/gridpattern/cba7c50432cbd75fe5d5d605b135e4864273c857/tests/figs/array/text.png -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library("testthat") 2 | library("gridpattern") 3 | 4 | test_check("gridpattern") 5 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/geometry/centroid.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/geometry/fill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/geometry/none.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/geometry/stripe-gpar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/geometry/stripe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/pch/fill-fill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /tests/testthat/test_aRtsy.R: -------------------------------------------------------------------------------- 1 | test_that("aRtsy patterns works as expected", { 2 | skip_on_ci() 3 | skip_on_cran() 4 | skip_if_not_installed("aRtsy") 5 | skip_if_not(getRversion() >= "4.3.0") 6 | skip_if_not(isTRUE(all(capabilities(c("cairo", "png"))))) 7 | 8 | f <- tempfile(fileext = ".png") 9 | png(f, type = "cairo") 10 | grid.pattern_aRtsy(type = "maze") 11 | dev.off() 12 | expect_true(file.size(f) > 0) 13 | unlink(f) 14 | 15 | f <- tempfile(fileext = ".png") 16 | png(f, type = "cairo") 17 | grid.pattern_aRtsy(type = "strokes") 18 | dev.off() 19 | expect_true(file.size(f) > 0) 20 | unlink(f) 21 | 22 | expect_true(length(names_aRtsy()) >= 34L) 23 | }) 24 | -------------------------------------------------------------------------------- /tests/testthat/test_geometry.R: -------------------------------------------------------------------------------- 1 | context("geometry") 2 | test_that("geometry helpers work as expected", { 3 | xy <- rotate_xy(c(0, 1), c(0, 1), 90) 4 | expect_equal(xy$x, c(1, 0)) 5 | expect_equal(xy$y, c(0, 1)) 6 | }) 7 | test_that("geometry patterns work as expected", { 8 | 9 | png_file <- tempfile(fileext = ".png") 10 | png(png_file) 11 | expect_error(grid.pattern_crosshatch(x, y, density = 1.1)) 12 | expect_error(grid.pattern_stripe(x, y, density = 1.1)) 13 | dev.off() 14 | unlink(png_file) 15 | 16 | skip_if_not_installed("vdiffr") 17 | skip_on_ci() 18 | library("vdiffr") 19 | 20 | expect_doppelganger("default", grid.pattern) 21 | 22 | x <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 23 | y <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 24 | expect_doppelganger("circle", function() 25 | grid.pattern_circle(x, y, color="blue", fill="yellow", size = 2, density = 0.5)) 26 | 27 | expect_doppelganger("crosshatch", function() 28 | grid.pattern_crosshatch(x, y, color="black", fill="blue", fill2="yellow", density = 0.5)) 29 | 30 | expect_doppelganger("fill", function() 31 | grid.pattern_fill(x, y, fill = "blue", alpha = 0.5)) 32 | 33 | expect_doppelganger("none", function() 34 | grid.pattern_none(x, y)) 35 | 36 | expect_error(assert_rp_shape(1), "Unknown shape 1") 37 | expect_null(assert_rp_shape(c("square", "convex4"))) 38 | expect_null(assert_rp_shape(c("star5", "circle", "null"))) 39 | expect_doppelganger("regular_polygon", function() 40 | grid.pattern_regular_polygon(x, y, color = "black", fill = "blue", density = 0.5)) 41 | 42 | expect_doppelganger("hexagon", function() 43 | grid.pattern_regular_polygon(x, y, color = "transparent", fill = c("white", "grey", "black"), 44 | density = 1.0, shape = "convex6", grid = "hex")) 45 | 46 | expect_doppelganger("square", function() 47 | grid.pattern_regular_polygon(x, y, color = "black", fill = c("white", "grey"), 48 | density = 1.0, shape = "square")) 49 | 50 | expect_doppelganger("eight_sided_star", function() 51 | grid.pattern_regular_polygon(x, y, colour = "black", fill = c("blue", "yellow"), 52 | density = 1.0, spacing = 0.1, shape = "star8")) 53 | expect_doppelganger("stripe", function() 54 | grid.pattern_stripe(x, y, color="black", fill=c("yellow", "blue"), density = 0.5)) 55 | 56 | expect_doppelganger("stripe_gpar", function() { 57 | x <- c(0.1, 0.6, 0.8, 0.3) 58 | y <- c(0.2, 0.3, 0.8, 0.5) 59 | grid.pattern("stripe", x, y, gp = gpar(col="blue", fill="red", lwd=2)) 60 | }) 61 | 62 | expect_doppelganger("wave_sine", function() 63 | grid.pattern_wave(x, y, colour = "black", type = "sine", 64 | fill = c("red", "blue"), density = 0.4, 65 | spacing = 0.15, angle = 0, 66 | amplitude = 0.05, frequency = 1 / 0.15)) 67 | 68 | expect_doppelganger("wave_triangle", function() 69 | grid.pattern_wave(x, y, color="black", fill="yellow", 70 | type = "triangle", density = 0.5, spacing = 0.15)) 71 | 72 | expect_doppelganger("weave", function() 73 | grid.pattern_weave(x, y, color="black", fill="yellow", fill2="blue", 74 | type = "twill", density = 0.5)) 75 | 76 | centroid_dot_pattern <- function(params, boundary_df, aspect_ratio, legend) { 77 | boundary_sf <- convert_polygon_df_to_polygon_sf(boundary_df) 78 | centroid <- sf::st_centroid(boundary_sf) 79 | grid::pointsGrob(x = centroid[1], 80 | y = centroid[2], 81 | pch = params$pattern_shape, 82 | size = unit(params$pattern_size, 'char'), 83 | default.units = "npc", 84 | gp = grid::gpar(col = update_alpha(params$pattern_fill, params$pattern_alpha)) 85 | ) 86 | } 87 | options(ggpattern_geometry_funcs = list(centroid = centroid_dot_pattern)) 88 | x <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 89 | y <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 90 | expect_doppelganger("centroid", function() 91 | grid.pattern("centroid", x, y, fill="blue", size = 5)) 92 | 93 | x <- c(0, 0, 0.5, 0.5, 0.5, 0.5, 1, 1) 94 | y <- c(0, 0.5, 0.5, 0, 0.5, 1, 1, 0.5) 95 | id <- rep(1:2, each = 4L) 96 | expect_doppelganger("two_id", function() 97 | grid.pattern(x = x, y = y, id = id)) 98 | }) 99 | -------------------------------------------------------------------------------- /tests/testthat/test_hex.R: -------------------------------------------------------------------------------- 1 | test_that("hex patterns work as expected", { 2 | phh <- function(...) print.pattern_hex(pattern_hex(...)) 3 | 4 | verify_output("../text_diagrams/hex.txt", phh("hex_skew", 3L, nrow = 7, ncol = 9)) 5 | verify_output("../text_diagrams/hex1_1.txt", phh("hex", 1L, nrow = 7, ncol = 9)) 6 | verify_output("../text_diagrams/hex1_2.txt", phh("hex", NULL, nrow = 7, ncol = 9)) 7 | verify_output("../text_diagrams/hex2_2.txt", phh("hex2", 2L, nrow = 7, ncol = 9)) 8 | verify_output("../text_diagrams/hex2_4.txt", phh("hex", 4L, nrow = 9, ncol = 9)) 9 | verify_output("../text_diagrams/hex3_2.txt", phh("hex3", 2L, nrow = 9, ncol = 9)) 10 | verify_output("../text_diagrams/hex3_7.txt", phh("hex", 7L, nrow = 9, ncol = 9)) 11 | verify_output("../text_diagrams/hex_skew_5.txt", phh("hex", 5L, nrow = 9, ncol = 9)) 12 | }) 13 | -------------------------------------------------------------------------------- /tests/testthat/test_pch.R: -------------------------------------------------------------------------------- 1 | context("pch") 2 | test_that("pch patterns work as expected", { 3 | 4 | skip_if_not_installed("vdiffr") 5 | skip_on_ci() 6 | library("vdiffr") 7 | 8 | x <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 9 | y <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 10 | gp <- gpar(fill = "yellow", col = "black") 11 | g.pp <- function(shape, ...) { 12 | grid.pattern_pch(x, y, shape = shape, angle = 0, spacing = 0.15, gp = gp) 13 | } 14 | 15 | expect_doppelganger("simple", function() g.pp(0:6)) 16 | expect_doppelganger("compound", function() g.pp(7:14)) 17 | expect_doppelganger("col_fill", function() g.pp(15:20)) 18 | expect_doppelganger("fill_fill", function() g.pp(21:25)) 19 | }) 20 | -------------------------------------------------------------------------------- /tests/testthat/test_square.R: -------------------------------------------------------------------------------- 1 | test_that("square patterns work as expected", { 2 | 3 | pss <- function(...) print.pattern_square(pattern_square(...)) 4 | 5 | expect_error(pattern_square("foobar"), "Don't recognize square pattern type foobar") 6 | 7 | verify_output("../text_diagrams/diagonal.txt", pss("diagonal", nrow = 7, ncol = 9)) 8 | verify_output("../text_diagrams/diagonal_1.txt", pss("diagonal", 1L, nrow = 7, ncol = 9)) 9 | verify_output("../text_diagrams/diagonal_skew.txt", pss("diagonal_skew", nrow = 7, ncol = 9)) 10 | verify_output("../text_diagrams/horizontal.txt", pss("horizontal", nrow = 7, ncol = 9)) 11 | verify_output("../text_diagrams/square_twill.txt", pss("twill", nrow = 7, ncol = 9)) 12 | verify_output("../text_diagrams/vertical.txt", pss("vertical", nrow = 7, ncol = 9)) 13 | verify_output("../text_diagrams/square_1122.txt", pss("square_tiling", "1122", nrow = 7, ncol = 9)) 14 | verify_output("../text_diagrams/square_3.txt", pss("square", NULL, nrow = 7, ncol = 9)) 15 | verify_output("../text_diagrams/square_tiling_3.txt", pss("square_tiling", NULL, nrow = 7, ncol = 9)) 16 | verify_output("../text_diagrams/square_4.txt", pss("square", 4L, nrow = 7, ncol = 9)) 17 | verify_output("../text_diagrams/square_5.txt", pss("square", 5L, nrow = 7, ncol = 9)) 18 | }) 19 | -------------------------------------------------------------------------------- /tests/testthat/test_tiling.R: -------------------------------------------------------------------------------- 1 | context("tiling") 2 | test_that("tiling patterns work as expected", { 3 | 4 | skip_if_not_installed("vdiffr") 5 | skip_on_ci() 6 | library("vdiffr") 7 | 8 | x <- 0.5 + 0.5 * cos(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 9 | y <- 0.5 + 0.5 * sin(seq(2 * pi / 4, by = 2 * pi / 6, length.out = 6)) 10 | g.ppt <- function(type, ...) { 11 | grid.pattern_polygon_tiling(x, y, angle = 0, type = type, 12 | spacing = 0.15, ...) 13 | } 14 | gp1 <- gpar(fill = "yellow", col = "black") 15 | gp2 <- gpar(fill = c("yellow", "red"), col = "black") 16 | gp3 <- gpar(fill = c("yellow", "red", "blue"), col = "black") 17 | 18 | expect_doppelganger("elongated_triangular", function() 19 | g.ppt("elongated_triangular", gp = gp2)) 20 | expect_doppelganger("herringbone", function() 21 | g.ppt("herringbone", gp = gp2)) 22 | expect_doppelganger("hexagonal_tiling", function() 23 | g.ppt("hexagonal", gp = gp2)) 24 | expect_doppelganger("pythagorean", function() 25 | g.ppt("pythagorean", gp = gp2)) 26 | expect_doppelganger("rhombitrihexagonal_tiling", function() 27 | g.ppt("rhombitrihexagonal", gp = gp3)) 28 | expect_doppelganger("rhombille", function() 29 | g.ppt("rhombille", gp = gp3)) 30 | expect_doppelganger("snub_square_tiling", function() 31 | g.ppt("snub_square", gp = gp3)) 32 | expect_doppelganger("snub_trihex_tiling", function() 33 | g.ppt("snub_trihexagonal", gp = gp3)) 34 | expect_doppelganger("square_tiling", function() 35 | g.ppt("square", gp = gp2)) 36 | expect_doppelganger("tetrakis_square", function() 37 | g.ppt("tetrakis_square", gp = gp3)) 38 | expect_doppelganger("triangular_tiling", function() 39 | g.ppt("triangular", gp = gp2)) 40 | expect_doppelganger("trihexagonal_tiling", function() 41 | g.ppt("trihexagonal", gp = gp2)) 42 | expect_doppelganger("trunc_hex_tiling", function() 43 | g.ppt("truncated_hexagonal", gp = gp3)) 44 | expect_doppelganger("trunc_trihex_tiling", function() 45 | g.ppt("truncated_trihexagonal", gp = gp2)) 46 | expect_doppelganger("trunc_square_tiling", function() 47 | g.ppt("truncated_square", gp = gp3)) 48 | expect_doppelganger("2*.2**.2*.2**", function() 49 | g.ppt("2*.2**.2*.2**", gp = gp3)) 50 | expect_doppelganger("2**.3**.12*", function() 51 | g.ppt("2**.3**.12*", gp = gp3)) 52 | expect_doppelganger("3.3.3.3_alt", function() 53 | g.ppt("3.3.3.3**", gp = gp2)) 54 | expect_doppelganger("3.3*.3.3**", function() 55 | g.ppt("3.3*.3.3**", gp = gp2)) 56 | expect_doppelganger("3.3.3.12*.3.3.12*", function() 57 | g.ppt("3.3.3.12*.3.3.12*", gp = gp3)) 58 | expect_doppelganger("3.3.8*.3.4.3.8*", function() 59 | g.ppt("3.3.8*.3.4.3.8*", gp = gp3)) 60 | expect_doppelganger("3.3.8*.4**.8*", function() 61 | g.ppt("3.3.8*.4**.8*", gp = gp3)) 62 | expect_doppelganger("3.4.6.3.12*", function() 63 | g.ppt("3.4.6.3.12*", gp = gp3)) 64 | expect_doppelganger("3.4.8.3.8*", function() 65 | g.ppt("3.4.8.3.8*", gp = gp3)) 66 | expect_doppelganger("3.6*.6**", function() 67 | g.ppt("3.6*.6**", gp = gp3)) 68 | expect_doppelganger("4.2*.4.2**", function() 69 | g.ppt("4.2*.4.2**", gp = gp3)) 70 | expect_doppelganger("4.4*.4**", function() 71 | g.ppt("4.4*.4**", gp = gp2)) 72 | expect_doppelganger("4.6.4*.6", function() 73 | g.ppt("4.6.4*.6", gp = gp3)) 74 | expect_doppelganger("4.6*.4.6*.4.6*", function() 75 | g.ppt("4.6*.4.6*.4.6*", gp = gp2)) 76 | expect_doppelganger("4.8*.4**.8*", function() 77 | g.ppt("4.8*.4**.8*", gp = gp2)) 78 | expect_doppelganger("6.6*.6.6*", function() 79 | g.ppt("6.6*.6.6*", gp = gp2)) 80 | expect_doppelganger("8.4*.8.4*", function() 81 | g.ppt("8.4*.8.4*", gp = gp2)) 82 | expect_doppelganger("9.3.9.3*", function() 83 | g.ppt("9.3.9.3*", gp = gp3)) 84 | expect_doppelganger("12.3*.12.3*", function() 85 | g.ppt("12.3*.12.3*", gp = gp2)) 86 | expect_doppelganger("12.12.4*", function() 87 | g.ppt("12.12.4*", gp = gp2)) 88 | expect_doppelganger("18.18.3*", function() 89 | g.ppt("18.18.3*", gp = gp2)) 90 | }) 91 | -------------------------------------------------------------------------------- /tests/testthat/test_utils.R: -------------------------------------------------------------------------------- 1 | test_that("`update_alpha()` works as expected", { 2 | expect_equal(update_alpha("blue", 0.5), "#0000FF80") 3 | expect_equal(update_alpha(list(c("blue", "red")), NA), c("#0000FFFF", "#FF0000FF")) 4 | expect_equal(update_alpha("#00FF0080", NA), "#00FF0080") 5 | expect_equal(update_alpha("#FF000080", 0.25), "#FF000040") 6 | 7 | expect_error(update_alpha(list("blue", "red"), NA)) 8 | skip_if_not(getRversion() >= "4.1.0") 9 | expect_equal(update_pattern_alpha("red", 0.5, name = "nonrandom"), 10 | pattern(rectGrob(name = "nonrandom"), gp = gpar(fill = "#FF000080"))) 11 | expect_equal(update_pattern_alpha(linearGradient(c("black", "white")), 0.5), 12 | linearGradient(c("#00000080", "#FFFFFF80"))) 13 | }) 14 | 15 | test_that("`mean_col()` works as expected", { 16 | expect_equal(mean_col("black", "white"), "#B4B4B4FF") 17 | expect_equal(mean_col(c("black", "white")), "#B4B4B4FF") 18 | expect_equal(mean_col("red", "blue"), "#B400B4FF") 19 | }) 20 | 21 | test_that("`get_params()` works as expected", { 22 | params <- get_params() 23 | expect_equal(params$pattern_colour, "grey20") 24 | expect_equal(params$pattern_fill, "grey80") 25 | expect_equal(params$pattern_angle, 30) 26 | expect_equal(params$pattern_density, 0.2) 27 | expect_equal(params$pattern_spacing, 0.05) 28 | expect_equal(params$pattern_xoffset, 0) 29 | expect_equal(params$pattern_yoffset, 0) 30 | expect_equal(params$pattern_alpha, NA_real_) 31 | expect_equal(params$pattern_linetype, 1) 32 | expect_equal(params$pattern_linewidth, 1) 33 | 34 | params <- get_params(alpha = 0.5, spacing = 0.1) 35 | expect_equal(params$pattern_alpha, 0.5) 36 | expect_equal(params$pattern_spacing, 0.1) 37 | 38 | gp <- gpar(col = "blue", lty = 2) 39 | params <- get_params(gp = gp) 40 | expect_equal(params$pattern_colour, "blue") 41 | expect_equal(params$pattern_linetype, 2) 42 | }) 43 | 44 | test_that("`star_scale()` works as expected", { 45 | # |8/3| star has internal angle 45 degrees and external angle 90 degrees 46 | scale <- star_scale(8, 45) 47 | scale2 <- star_scale(8, 90, external = TRUE) 48 | expect_equal(scale, scale2) 49 | expect_equal(star_angle(8, scale), 45) 50 | expect_equal(star_angle(8, scale, external = TRUE), 90) 51 | expect_equal(star_angle(2, star_scale(2, 30)), 30) 52 | expect_equal(star_angle(2, star_scale(2, 210, TRUE), TRUE), 210) 53 | }) 54 | 55 | test_that("`assert_patterns_unique()` works as expected", { 56 | expect_null(assert_patterns_unique(list(), list())) 57 | expect_null(assert_patterns_unique(list(custom1 = 2), list(custom2 = 2))) 58 | expect_error(assert_patterns_unique(list(custom = 2, custom = 3), list()), 59 | 'There are multiple custom "geometry" patterns named "custom"') 60 | expect_error(assert_patterns_unique(list(), list(custom = 2, custom = 3)), 61 | 'There are multiple custom "array" patterns named "custom"') 62 | expect_error(assert_patterns_unique(list(custom = 2), list(custom = 2)), 63 | 'There is a custom "geometry" pattern and custom "array" pattern both named "custom"') 64 | expect_error(assert_patterns_unique(list(circle = 2), list()), 65 | 'There is a custom "geometry" pattern and builtin \\{gridpattern\\} pattern both named "circle"') 66 | expect_error(assert_patterns_unique(list(), list(image = 2)), 67 | 'There is a custom "array" pattern and builtin \\{gridpattern\\} pattern both named "image"') 68 | }) 69 | 70 | test_that("`assert_suggested()` works as expected", { 71 | expect_error(assert_suggested("doesnotexist", "blueberry"), 72 | "The suggested package \\{doesnotexist\\} must be installed") 73 | }) 74 | -------------------------------------------------------------------------------- /tests/testthat/test_weave.R: -------------------------------------------------------------------------------- 1 | test_that("weaves work as expected", { 2 | 3 | pww <- function(...) print.pattern_weave(pattern_weave(...)) 4 | 5 | expect_error(pattern_weave("foobar"), "Don't know weave type foobar") 6 | 7 | # irregular mat 8 | verify_output("../text_diagrams/plain.txt", pww("plain", nrow = 7, ncol = 9)) 9 | verify_output("../text_diagrams/basket.txt", pww("basket", nrow = 7, ncol = 9)) 10 | verify_output("../text_diagrams/matt.txt", pww("matt", 3, nrow = 7, ncol = 9)) 11 | verify_output("../text_diagrams/matt_21.txt", pww("matt", "2/1", nrow = 7, ncol = 9)) 12 | verify_output("../text_diagrams/matt3221.txt", pww("matt", "3/2*2/1", nrow = 15, ncol = 9)) 13 | verify_output("../text_diagrams/matt_irregular.txt", 14 | pww("matt_irregular", "3/2(4+2)", nrow = 7, ncol = 9)) 15 | verify_output("../text_diagrams/rib_warp", 16 | pww("rib_warp", "2/1", nrow = 7, ncol = 9)) 17 | verify_output("../text_diagrams/rib_warp.txt", pww("rib_warp", "2", nrow = 7, ncol = 9)) 18 | 19 | # elongated twill 20 | verify_output("../text_diagrams/satin_5.txt", pww("satin", "5", nrow = 7, ncol = 9)) 21 | verify_output("../text_diagrams/twill_3.txt", pww("twill", 3L, nrow = 7, ncol = 9)) 22 | verify_output("../text_diagrams/twill_212.txt", pww("twill_elongated", "2/1(2)", nrow = 7, ncol = 9)) 23 | verify_output("../text_diagrams/twill_22.txt", pww("twill", "2/2", nrow = 7, ncol = 9)) 24 | verify_output("../text_diagrams/twill_13.txt", pww("twill", "1/3", nrow = 7, ncol = 9)) 25 | verify_output("../text_diagrams/twill_22_zigzag.txt", 26 | pww("twill_zigzag", "2/2", nrow = 15, ncol = 9)) 27 | verify_output("../text_diagrams/twill_13_herringbone.txt", 28 | pww("twill_herringbone", "1/3", nrow = 15, ncol = 9)) 29 | verify_output("../text_diagrams/twill3221.txt", pww("twill", "3/2*2/1", nrow = 15, ncol = 9)) 30 | }) 31 | -------------------------------------------------------------------------------- /tests/text_diagrams/basket.txt: -------------------------------------------------------------------------------- 1 | > pww("basket", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X | 4 | | X X X X X | 5 | | X X X X X | 6 | | X X X X | 7 | | X X X X | 8 | | X X X X X | 9 | | X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/diagonal.txt: -------------------------------------------------------------------------------- 1 | > pss("diagonal", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 1 2 3 1 2 3 1 2 3 | 4 | | 3 1 2 3 1 2 3 1 2 | 5 | | 2 3 1 2 3 1 2 3 1 | 6 | | 1 2 3 1 2 3 1 2 3 | 7 | | 3 1 2 3 1 2 3 1 2 | 8 | | 2 3 1 2 3 1 2 3 1 | 9 | | 1 2 3 1 2 3 1 2 3 | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/diagonal_1.txt: -------------------------------------------------------------------------------- 1 | > pss("diagonal", 1L, nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 1 1 1 1 1 1 1 1 1 | 4 | | 1 1 1 1 1 1 1 1 1 | 5 | | 1 1 1 1 1 1 1 1 1 | 6 | | 1 1 1 1 1 1 1 1 1 | 7 | | 1 1 1 1 1 1 1 1 1 | 8 | | 1 1 1 1 1 1 1 1 1 | 9 | | 1 1 1 1 1 1 1 1 1 | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/diagonal_skew.txt: -------------------------------------------------------------------------------- 1 | > pss("diagonal_skew", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 1 2 3 1 2 3 1 2 3 | 4 | | 2 3 1 2 3 1 2 3 1 | 5 | | 3 1 2 3 1 2 3 1 2 | 6 | | 1 2 3 1 2 3 1 2 3 | 7 | | 2 3 1 2 3 1 2 3 1 | 8 | | 3 1 2 3 1 2 3 1 2 | 9 | | 1 2 3 1 2 3 1 2 3 | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/hex.txt: -------------------------------------------------------------------------------- 1 | > phh("hex_skew", 3L, nrow = 7, ncol = 9) 2 | /------------------\ 3 | | 1 2 3 1 2 3 1 2 3| 4 | |2 3 1 2 3 1 2 3 1 | 5 | | 1 2 3 1 2 3 1 2 3| 6 | |2 3 1 2 3 1 2 3 1 | 7 | | 1 2 3 1 2 3 1 2 3| 8 | |2 3 1 2 3 1 2 3 1 | 9 | | 1 2 3 1 2 3 1 2 3| 10 | \------------------/ 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/hex1_1.txt: -------------------------------------------------------------------------------- 1 | > phh("hex", 1L, nrow = 7, ncol = 9) 2 | /------------------\ 3 | | 1 1 1 1 1 1 1 1 1| 4 | |1 1 1 1 1 1 1 1 1 | 5 | | 1 1 1 1 1 1 1 1 1| 6 | |1 1 1 1 1 1 1 1 1 | 7 | | 1 1 1 1 1 1 1 1 1| 8 | |1 1 1 1 1 1 1 1 1 | 9 | | 1 1 1 1 1 1 1 1 1| 10 | \------------------/ 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/hex1_2.txt: -------------------------------------------------------------------------------- 1 | > phh("hex", NULL, nrow = 7, ncol = 9) 2 | /------------------\ 3 | | 1 2 2 1 2 2 1 2 2| 4 | |2 2 1 2 2 1 2 2 1 | 5 | | 1 2 2 1 2 2 1 2 2| 6 | |2 2 1 2 2 1 2 2 1 | 7 | | 1 2 2 1 2 2 1 2 2| 8 | |2 2 1 2 2 1 2 2 1 | 9 | | 1 2 2 1 2 2 1 2 2| 10 | \------------------/ 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/hex2_2.txt: -------------------------------------------------------------------------------- 1 | > phh("hex2", 2L, nrow = 7, ncol = 9) 2 | /------------------\ 3 | | 2 1 2 1 2 1 2 1 2| 4 | |2 2 2 2 2 2 2 2 2 | 5 | | 1 2 1 2 1 2 1 2 1| 6 | |2 2 2 2 2 2 2 2 2 | 7 | | 2 1 2 1 2 1 2 1 2| 8 | |2 2 2 2 2 2 2 2 2 | 9 | | 1 2 1 2 1 2 1 2 1| 10 | \------------------/ 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/hex2_4.txt: -------------------------------------------------------------------------------- 1 | > phh("hex", 4L, nrow = 9, ncol = 9) 2 | /------------------\ 3 | | 1 2 1 2 1 2 1 2 1| 4 | |4 3 4 3 4 3 4 3 4 | 5 | | 2 1 2 1 2 1 2 1 2| 6 | |3 4 3 4 3 4 3 4 3 | 7 | | 1 2 1 2 1 2 1 2 1| 8 | |4 3 4 3 4 3 4 3 4 | 9 | | 2 1 2 1 2 1 2 1 2| 10 | |3 4 3 4 3 4 3 4 3 | 11 | | 1 2 1 2 1 2 1 2 1| 12 | \------------------/ 13 | 14 | -------------------------------------------------------------------------------- /tests/text_diagrams/hex3_2.txt: -------------------------------------------------------------------------------- 1 | > phh("hex3", 2L, nrow = 9, ncol = 9) 2 | /------------------\ 3 | | 2 2 2 2 2 2 1 2 2| 4 | |2 2 2 2 1 2 2 2 2 | 5 | | 2 1 2 2 2 2 2 2 1| 6 | |2 2 2 2 2 2 1 2 2 | 7 | | 2 2 2 1 2 2 2 2 2| 8 | |2 1 2 2 2 2 2 2 1 | 9 | | 2 2 2 2 2 1 2 2 2| 10 | |2 2 2 1 2 2 2 2 2 | 11 | | 1 2 2 2 2 2 2 1 2| 12 | \------------------/ 13 | 14 | -------------------------------------------------------------------------------- /tests/text_diagrams/hex3_7.txt: -------------------------------------------------------------------------------- 1 | > phh("hex", 7L, nrow = 9, ncol = 9) 2 | /------------------\ 3 | | 2 3 4 5 6 7 1 2 3| 4 | |4 5 6 7 1 2 3 4 5 | 5 | | 7 1 2 3 4 5 6 7 1| 6 | |2 3 4 5 6 7 1 2 3 | 7 | | 5 6 7 1 2 3 4 5 6| 8 | |7 1 2 3 4 5 6 7 1 | 9 | | 3 4 5 6 7 1 2 3 4| 10 | |5 6 7 1 2 3 4 5 6 | 11 | | 1 2 3 4 5 6 7 1 2| 12 | \------------------/ 13 | 14 | -------------------------------------------------------------------------------- /tests/text_diagrams/hex_skew_5.txt: -------------------------------------------------------------------------------- 1 | > phh("hex", 5L, nrow = 9, ncol = 9) 2 | /------------------\ 3 | | 3 4 5 1 2 3 4 5 1| 4 | |1 2 3 4 5 1 2 3 4 | 5 | | 5 1 2 3 4 5 1 2 3| 6 | |3 4 5 1 2 3 4 5 1 | 7 | | 2 3 4 5 1 2 3 4 5| 8 | |5 1 2 3 4 5 1 2 3 | 9 | | 4 5 1 2 3 4 5 1 2| 10 | |2 3 4 5 1 2 3 4 5 | 11 | | 1 2 3 4 5 1 2 3 4| 12 | \------------------/ 13 | 14 | -------------------------------------------------------------------------------- /tests/text_diagrams/horizontal.txt: -------------------------------------------------------------------------------- 1 | > pss("horizontal", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 1 1 1 1 1 1 1 1 1 | 4 | | 3 3 3 3 3 3 3 3 3 | 5 | | 2 2 2 2 2 2 2 2 2 | 6 | | 1 1 1 1 1 1 1 1 1 | 7 | | 3 3 3 3 3 3 3 3 3 | 8 | | 2 2 2 2 2 2 2 2 2 | 9 | | 1 1 1 1 1 1 1 1 1 | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/matt.txt: -------------------------------------------------------------------------------- 1 | > pww("matt", 3, nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X X | 4 | | X X X | 5 | | X X X | 6 | | X X X | 7 | | X X X X X X | 8 | | X X X X X X | 9 | | X X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/matt3221.txt: -------------------------------------------------------------------------------- 1 | > pww("matt", "3/2*2/1", nrow = 15, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X X | 4 | | X X X X X X | 5 | | X X X | 6 | | X X X | 7 | | X X X X X X | 8 | | X X X X X X | 9 | | X X X X X X | 10 | | X X X | 11 | | X X X X X X | 12 | | X X X X X X | 13 | | X X X | 14 | | X X X | 15 | | X X X X X X | 16 | | X X X X X X | 17 | | X X X X X X | 18 | \ - - - - - - - - - / 19 | 20 | -------------------------------------------------------------------------------- /tests/text_diagrams/matt_21.txt: -------------------------------------------------------------------------------- 1 | > pww("matt", "2/1", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X X | 4 | | X X X | 5 | | X X X X X X | 6 | | X X X X X X | 7 | | X X X | 8 | | X X X X X X | 9 | | X X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/matt_irregular.txt: -------------------------------------------------------------------------------- 1 | > pww("matt_irregular", "3/2(4+2)", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X X X | 4 | | X X X X X X X | 5 | | X X | 6 | | X X | 7 | | X X X X X X X | 8 | | X X X X X X X | 9 | | X X X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/plain.txt: -------------------------------------------------------------------------------- 1 | > pww("plain", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X | 4 | | X X X X | 5 | | X X X X X | 6 | | X X X X | 7 | | X X X X X | 8 | | X X X X | 9 | | X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/rib_warp: -------------------------------------------------------------------------------- 1 | > pww("rib_warp", "2/1", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X | 4 | | X X X X | 5 | | X X X X X | 6 | | X X X X X | 7 | | X X X X | 8 | | X X X X X | 9 | | X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/rib_warp.txt: -------------------------------------------------------------------------------- 1 | > pww("rib_warp", "2", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X | 4 | | X X X X X | 5 | | X X X X X | 6 | | X X X X | 7 | | X X X X | 8 | | X X X X X | 9 | | X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/rib_warp_irregular.txt: -------------------------------------------------------------------------------- 1 | > ppww("rib_warp", "2/1", warp = 7, weft = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X | 4 | | X X X X | 5 | | X X X X X | 6 | | X X X X X | 7 | | X X X X | 8 | | X X X X X | 9 | | X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/satin_5.txt: -------------------------------------------------------------------------------- 1 | > pww("satin", "5", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X X X | 4 | | X X X X X X X | 5 | | X X X X X X X | 6 | | X X X X X X X | 7 | | X X X X X X X X | 8 | | X X X X X X X | 9 | | X X X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/square_1122.txt: -------------------------------------------------------------------------------- 1 | > pss("square_tiling", "1122", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 2 2 2 2 2 2 2 2 2 | 4 | | 1 1 1 1 1 1 1 1 1 | 5 | | 2 2 2 2 2 2 2 2 2 | 6 | | 1 1 1 1 1 1 1 1 1 | 7 | | 2 2 2 2 2 2 2 2 2 | 8 | | 1 1 1 1 1 1 1 1 1 | 9 | | 2 2 2 2 2 2 2 2 2 | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/square_3.txt: -------------------------------------------------------------------------------- 1 | > pss("square", NULL, nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 3 1 3 1 3 1 3 1 3 | 4 | | 1 2 1 2 1 2 1 2 1 | 5 | | 3 1 3 1 3 1 3 1 3 | 6 | | 1 2 1 2 1 2 1 2 1 | 7 | | 3 1 3 1 3 1 3 1 3 | 8 | | 1 2 1 2 1 2 1 2 1 | 9 | | 3 1 3 1 3 1 3 1 3 | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/square_4.txt: -------------------------------------------------------------------------------- 1 | > pss("square", 4L, nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 3 4 3 4 3 4 3 4 3 | 4 | | 1 2 1 2 1 2 1 2 1 | 5 | | 3 4 3 4 3 4 3 4 3 | 6 | | 1 2 1 2 1 2 1 2 1 | 7 | | 3 4 3 4 3 4 3 4 3 | 8 | | 1 2 1 2 1 2 1 2 1 | 9 | | 3 4 3 4 3 4 3 4 3 | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/square_5.txt: -------------------------------------------------------------------------------- 1 | > pss("square", 5L, nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 2 3 4 5 1 2 3 4 5 | 4 | | 1 2 3 4 5 1 2 3 4 | 5 | | 5 1 2 3 4 5 1 2 3 | 6 | | 4 5 1 2 3 4 5 1 2 | 7 | | 3 4 5 1 2 3 4 5 1 | 8 | | 2 3 4 5 1 2 3 4 5 | 9 | | 1 2 3 4 5 1 2 3 4 | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/square_tiling_3.txt: -------------------------------------------------------------------------------- 1 | > pss("square_tiling", NULL, nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 3 1 3 1 3 1 3 1 3 | 4 | | 1 2 1 2 1 2 1 2 1 | 5 | | 3 1 3 1 3 1 3 1 3 | 6 | | 1 2 1 2 1 2 1 2 1 | 7 | | 3 1 3 1 3 1 3 1 3 | 8 | | 1 2 1 2 1 2 1 2 1 | 9 | | 3 1 3 1 3 1 3 1 3 | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/square_twill.txt: -------------------------------------------------------------------------------- 1 | > pss("twill", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 1 2 1 1 2 1 1 2 1 | 4 | | 2 1 1 2 1 1 2 1 1 | 5 | | 1 1 2 1 1 2 1 1 2 | 6 | | 1 2 1 1 2 1 1 2 1 | 7 | | 2 1 1 2 1 1 2 1 1 | 8 | | 1 1 2 1 1 2 1 1 2 | 9 | | 1 2 1 1 2 1 1 2 1 | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/twill3221.txt: -------------------------------------------------------------------------------- 1 | > pww("twill", "3/2*2/1", nrow = 15, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X X | 4 | | X X X X X X | 5 | | X X X X X | 6 | | X X X X X | 7 | | X X X X X X | 8 | | X X X X X X | 9 | | X X X X X X | 10 | | X X X X X | 11 | | X X X X X X | 12 | | X X X X X X | 13 | | X X X X X | 14 | | X X X X X | 15 | | X X X X X X | 16 | | X X X X X X | 17 | | X X X X X X | 18 | \ - - - - - - - - - / 19 | 20 | -------------------------------------------------------------------------------- /tests/text_diagrams/twill_13.txt: -------------------------------------------------------------------------------- 1 | > pww("twill", "1/3", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X | 4 | | X X | 5 | | X X X | 6 | | X X | 7 | | X X | 8 | | X X | 9 | | X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/twill_13_herringbone.txt: -------------------------------------------------------------------------------- 1 | > pww("twill_herringbone", "1/3", nrow = 15, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X X X | 4 | | X X X X X X X | 5 | | X X X X X X X | 6 | | X X | 7 | | X X | 8 | | X X | 9 | | X X X | 10 | | X X X X X X | 11 | | X X X X X X X | 12 | | X X X X X X X | 13 | | X X X X X X X | 14 | | X X | 15 | | X X | 16 | | X X | 17 | | X X X | 18 | \ - - - - - - - - - / 19 | 20 | -------------------------------------------------------------------------------- /tests/text_diagrams/twill_21.txt: -------------------------------------------------------------------------------- 1 | > ppww("twill", "2/1", warp = 7, weft = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X X | 4 | | X X X X X X | 5 | | X X X X X X | 6 | | X X X X X X | 7 | | X X X X X X | 8 | | X X X X X X | 9 | | X X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/twill_212.txt: -------------------------------------------------------------------------------- 1 | > pww("twill_elongated", "2/1(2)", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X X | 4 | | X X X X X X | 5 | | X X X X X X | 6 | | X X X X X X | 7 | | X X X X X X | 8 | | X X X X X X | 9 | | X X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/twill_22.txt: -------------------------------------------------------------------------------- 1 | > pww("twill", "2/2", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X | 4 | | X X X X X | 5 | | X X X X X | 6 | | X X X X | 7 | | X X X X | 8 | | X X X X X | 9 | | X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/twill_22_zigzag.txt: -------------------------------------------------------------------------------- 1 | > pww("twill_zigzag", "2/2", nrow = 15, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X | 4 | | X X X X X | 5 | | X X X X | 6 | | X X X X | 7 | | X X X X | 8 | | X X X X X | 9 | | X X X X X | 10 | | X X X X | 11 | | X X X X X | 12 | | X X X X X | 13 | | X X X X | 14 | | X X X X | 15 | | X X X X | 16 | | X X X X X | 17 | | X X X X X | 18 | \ - - - - - - - - - / 19 | 20 | -------------------------------------------------------------------------------- /tests/text_diagrams/twill_3.txt: -------------------------------------------------------------------------------- 1 | > pww("twill", 3L, nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | X X X X X X | 4 | | X X X X X X | 5 | | X X X X X X | 6 | | X X X X X X | 7 | | X X X X X X | 8 | | X X X X X X | 9 | | X X X X X X | 10 | \ - - - - - - - - - / 11 | 12 | -------------------------------------------------------------------------------- /tests/text_diagrams/vertical.txt: -------------------------------------------------------------------------------- 1 | > pss("vertical", nrow = 7, ncol = 9) 2 | / - - - - - - - - - \ 3 | | 3 1 2 3 1 2 3 1 2 | 4 | | 3 1 2 3 1 2 3 1 2 | 5 | | 3 1 2 3 1 2 3 1 2 | 6 | | 3 1 2 3 1 2 3 1 2 | 7 | | 3 1 2 3 1 2 3 1 2 | 8 | | 3 1 2 3 1 2 3 1 2 | 9 | | 3 1 2 3 1 2 3 1 2 | 10 | \ - - - - - - - - - / 11 | 12 | --------------------------------------------------------------------------------