├── .Rbuildignore
├── .github
├── .gitignore
└── workflows
│ ├── R-CMD-check.yaml
│ ├── pkgdown.yaml
│ ├── pr-commands.yaml
│ └── test-coverage.yaml
├── .gitignore
├── CRAN-SUBMISSION
├── DESCRIPTION
├── LICENSE
├── LICENSE.md
├── NAMESPACE
├── NEWS.md
├── R
├── guide_colormeter.R
└── unexported-ggforce.R
├── README.Rmd
├── README.md
├── _pkgdown.yml
├── codecov.yml
├── cran-comments.md
├── ggcolormeter.Rproj
└── man
├── figures
├── README-arc-radius-1.png
├── README-arc-theme-1.png
├── README-simple-usage-1.png
├── README-unnamed-chunk-10-1.png
├── README-unnamed-chunk-11-1.png
├── README-unnamed-chunk-12-1.png
├── README-unnamed-chunk-13-1.png
├── README-unnamed-chunk-14-1.png
├── README-unnamed-chunk-15-1.png
├── README-unnamed-chunk-16-1.png
├── README-unnamed-chunk-17-1.png
├── README-unnamed-chunk-18-1.png
├── README-unnamed-chunk-19-1.png
├── README-unnamed-chunk-2-1.png
├── README-unnamed-chunk-3-1.png
├── README-unnamed-chunk-4-1.png
├── README-unnamed-chunk-5-1.png
├── README-unnamed-chunk-6-1.png
├── README-unnamed-chunk-7-1.png
├── README-unnamed-chunk-8-1.png
└── README-unnamed-chunk-9-1.png
├── guide_colormeter.Rd
└── legend-coords.Rd
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^LICENSE\.md$
4 | ^README\.Rmd$
5 | ^_pkgdown\.yml$
6 | ^docs$
7 | ^pkgdown$
8 | ^\.github$
9 | ^codecov\.yml$
10 | ^cran-comments\.md$
11 | ^CRAN-SUBMISSION$
12 |
--------------------------------------------------------------------------------
/.github/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
--------------------------------------------------------------------------------
/.github/workflows/R-CMD-check.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | #
4 | # NOTE: This workflow is overkill for most R packages and
5 | # check-standard.yaml is likely a better choice.
6 | # usethis::use_github_action("check-standard") will install it.
7 | on:
8 | push:
9 | branches: [main, master]
10 | pull_request:
11 | branches: [main, master]
12 |
13 | name: R-CMD-check
14 |
15 | jobs:
16 | R-CMD-check:
17 | runs-on: ${{ matrix.config.os }}
18 |
19 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
20 |
21 | strategy:
22 | fail-fast: false
23 | matrix:
24 | config:
25 | - {os: macos-latest, r: 'release'}
26 | - {os: windows-latest, r: 'release'}
27 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
28 | - {os: ubuntu-latest, r: 'release'}
29 | - {os: ubuntu-latest, r: 'oldrel-1'}
30 | - {os: ubuntu-latest, r: 'oldrel-2'}
31 |
32 | env:
33 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
34 | R_KEEP_PKG_SOURCE: yes
35 |
36 | steps:
37 | - uses: actions/checkout@v3
38 |
39 | - uses: r-lib/actions/setup-pandoc@v2
40 |
41 | - uses: r-lib/actions/setup-r@v2
42 | with:
43 | r-version: ${{ matrix.config.r }}
44 | http-user-agent: ${{ matrix.config.http-user-agent }}
45 | use-public-rspm: true
46 |
47 | - uses: r-lib/actions/setup-r-dependencies@v2
48 | with:
49 | extra-packages: any::rcmdcheck
50 | needs: check
51 |
52 | - uses: r-lib/actions/check-r-package@v2
53 | with:
54 | upload-snapshots: true
55 |
--------------------------------------------------------------------------------
/.github/workflows/pkgdown.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/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 | release:
9 | types: [published]
10 | workflow_dispatch:
11 |
12 | name: pkgdown
13 |
14 | jobs:
15 | pkgdown:
16 | runs-on: ubuntu-latest
17 | # Only restrict concurrency for non-PR jobs
18 | concurrency:
19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
20 | env:
21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
22 | permissions:
23 | contents: write
24 | steps:
25 | - uses: actions/checkout@v3
26 |
27 | - uses: r-lib/actions/setup-pandoc@v2
28 |
29 | - uses: r-lib/actions/setup-r@v2
30 | with:
31 | use-public-rspm: true
32 |
33 | - uses: r-lib/actions/setup-r-dependencies@v2
34 | with:
35 | extra-packages: any::pkgdown, local::.
36 | needs: website
37 |
38 | - name: Build site
39 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
40 | shell: Rscript {0}
41 |
42 | - name: Deploy to GitHub pages 🚀
43 | if: github.event_name != 'pull_request'
44 | uses: JamesIves/github-pages-deploy-action@v4.4.1
45 | with:
46 | clean: false
47 | branch: gh-pages
48 | folder: docs
49 |
--------------------------------------------------------------------------------
/.github/workflows/pr-commands.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | issue_comment:
5 | types: [created]
6 |
7 | name: Commands
8 |
9 | jobs:
10 | document:
11 | if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/document') }}
12 | name: document
13 | runs-on: ubuntu-latest
14 | env:
15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
16 | steps:
17 | - uses: actions/checkout@v3
18 |
19 | - uses: r-lib/actions/pr-fetch@v2
20 | with:
21 | repo-token: ${{ secrets.GITHUB_TOKEN }}
22 |
23 | - uses: r-lib/actions/setup-r@v2
24 | with:
25 | use-public-rspm: true
26 |
27 | - uses: r-lib/actions/setup-r-dependencies@v2
28 | with:
29 | extra-packages: any::roxygen2
30 | needs: pr-document
31 |
32 | - name: Document
33 | run: roxygen2::roxygenise()
34 | shell: Rscript {0}
35 |
36 | - name: commit
37 | run: |
38 | git config --local user.name "$GITHUB_ACTOR"
39 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com"
40 | git add man/\* NAMESPACE
41 | git commit -m 'Document'
42 |
43 | - uses: r-lib/actions/pr-push@v2
44 | with:
45 | repo-token: ${{ secrets.GITHUB_TOKEN }}
46 |
47 | style:
48 | if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/style') }}
49 | name: style
50 | runs-on: ubuntu-latest
51 | env:
52 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
53 | steps:
54 | - uses: actions/checkout@v3
55 |
56 | - uses: r-lib/actions/pr-fetch@v2
57 | with:
58 | repo-token: ${{ secrets.GITHUB_TOKEN }}
59 |
60 | - uses: r-lib/actions/setup-r@v2
61 |
62 | - name: Install dependencies
63 | run: install.packages("styler")
64 | shell: Rscript {0}
65 |
66 | - name: Style
67 | run: styler::style_pkg()
68 | shell: Rscript {0}
69 |
70 | - name: commit
71 | run: |
72 | git config --local user.name "$GITHUB_ACTOR"
73 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com"
74 | git add \*.R
75 | git commit -m 'Style'
76 |
77 | - uses: r-lib/actions/pr-push@v2
78 | with:
79 | repo-token: ${{ secrets.GITHUB_TOKEN }}
80 |
--------------------------------------------------------------------------------
/.github/workflows/test-coverage.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/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: test-coverage
10 |
11 | jobs:
12 | test-coverage:
13 | runs-on: ubuntu-latest
14 | env:
15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
16 |
17 | steps:
18 | - uses: actions/checkout@v3
19 |
20 | - uses: r-lib/actions/setup-r@v2
21 | with:
22 | use-public-rspm: true
23 |
24 | - uses: r-lib/actions/setup-r-dependencies@v2
25 | with:
26 | extra-packages: any::covr
27 | needs: coverage
28 |
29 | - name: Test coverage
30 | run: |
31 | covr::codecov(
32 | type = c("tests", "vignettes", "examples"),
33 | quiet = FALSE,
34 | clean = FALSE,
35 | install_path = file.path(Sys.getenv("RUNNER_TEMP"), "package")
36 | )
37 | shell: Rscript {0}
38 |
39 | - name: Show testthat output
40 | if: always()
41 | run: |
42 | ## --------------------------------------------------------------------
43 | find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true
44 | shell: bash
45 |
46 | - name: Upload test results
47 | if: failure()
48 | uses: actions/upload-artifact@v3
49 | with:
50 | name: coverage-test-failures
51 | path: ${{ runner.temp }}/package
52 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 | .Rdata
6 | .httr-oauth
7 | .DS_Store
8 | docs
9 |
--------------------------------------------------------------------------------
/CRAN-SUBMISSION:
--------------------------------------------------------------------------------
1 | Version: 0.2.0
2 | Date: 2024-01-22 14:22:38 UTC
3 | SHA: 2101920d6ccc9cf4269eda993a0b99b00733fd1b
4 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Type: Package
2 | Package: ggcolormeter
3 | Title: Colormeter Guide Extension
4 | Version: 0.2.0
5 | Authors@R:
6 | person("June", "Choe", , "jchoe001@gmail.com", role = c("aut", "cre", "cph"),
7 | comment = c(ORCID = "0000-0002-0701-921X"))
8 | Description: A 'ggplot2' guide extension for fill and color scales in the
9 | style of a dashboard meter. The dashboard legend maps onto continuous
10 | aesthetics and can be customized for its dimensions and the style of its
11 | various components including the labels and frames. Fine-grained control
12 | over the positioning of dashboard components is possible via an option to
13 | expose the legend-internal coordinate system.
14 | License: MIT + file LICENSE
15 | URL: https://github.com/yjunechoe/ggcolormeter, https://github.com/yjunechoe/ggcolormeter/issues, https://yjunechoe.github.io/ggcolormeter/
16 | BugReports: https://github.com/yjunechoe/ggcolormeter/issues
17 | Depends:
18 | ggplot2,
19 | R (>= 4.1)
20 | Imports:
21 | grid (>= 4.1),
22 | gtable,
23 | polyclip
24 | Suggests:
25 | ggtext,
26 | scales
27 | Encoding: UTF-8
28 | LazyData: true
29 | Roxygen: list(markdown = TRUE)
30 | RoxygenNote: 7.2.3
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2022
2 | COPYRIGHT HOLDER: ggcolormeter authors
3 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2022 ggcolormeter authors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | S3method(guide_gengrob,colormeter)
4 | S3method(makeContent,shape)
5 | export(guide_colormeter)
6 | importFrom(ggplot2,guide_gengrob)
7 | importFrom(grid,convertWidth)
8 | importFrom(grid,convertX)
9 | importFrom(grid,convertY)
10 | importFrom(grid,gpar)
11 | importFrom(grid,grob)
12 | importFrom(grid,is.unit)
13 | importFrom(grid,makeContent)
14 | importFrom(grid,nullGrob)
15 | importFrom(grid,polygonGrob)
16 | importFrom(grid,unit)
17 | importFrom(polyclip,polylineoffset)
18 | importFrom(polyclip,polyoffset)
19 |
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | # ggcolormeter 0.2.0
2 |
3 | * Initial CRAN submission.
4 |
--------------------------------------------------------------------------------
/R/guide_colormeter.R:
--------------------------------------------------------------------------------
1 | #' Colormeter legend coordinate system
2 | #'
3 | #' @description Due to the peculiar nature of the colormeter legend (e.g., dynamic size and positioning
4 | #' of color bars/arcs depending on the number of breaks), many parts of the legend are drawn in a
5 | #' mini isolated coordinate space. You can inspect this coordinate space with `debug = TRUE`.
6 | #'
7 | #' The coordinate space defaults to the x-y range of the legend "data", which considers the
8 | #' polar-transformed positioning of the color arcs/bars, the labels, and the dashboard circle.
9 | #'
10 | #' @keywords internal
11 | #' @name legend-coords
12 | #'
13 | #' @examples
14 | #' library(ggplot2)
15 | #' # A standard plot
16 | #' p <- ggplot(mtcars, aes(drat, hp)) +
17 | #' geom_point(aes(color = mpg))
18 | #' # Colormeter guide for color scale
19 | #' p +
20 | #' scale_color_viridis_c(
21 | #' option = "inferno",
22 | #' breaks = scales::breaks_pretty(10),
23 | #' guide = guide_colormeter(debug = TRUE)
24 | #' )
25 | NULL
26 |
27 | #' A color legend in the style of a dashboard meter
28 | #'
29 | #' @inheritParams ggplot2::guide_colorbar
30 | #' @inheritParams ggplot2::guide_colorsteps
31 | #' @param legend_size Size of the legend box.
32 | #' @param legend_padding Spacing between the color meter and the legend boundary.
33 | #' @param title_position <[`legend-coords`][legend-coords]> 2-length vector for the x/y-position of the legend title.
34 | #' @param arc_range <[`legend-coords`][legend-coords]> 2-length vector for the start and end angles of the color meter.
35 | #' @param arc_radius <[`legend-coords`][legend-coords]> Radius of the color meter.
36 | #' @param arc_width <[`legend-coords`][legend-coords]> Width of the arcs in the color meter.
37 | #' @param arc_gap <[`legend-coords`][legend-coords]> Gap between arcs in the color meter.
38 | #' @param arc_rounding <[`legend-coords`][legend-coords]> Rounding of arcs in the color meter.
39 | #' @param label_radius <[`legend-coords`][legend-coords]> Radius of the labels.
40 | #' @param dashboard_radius <[`legend-coords`][legend-coords]> Radius of the dashboard background.
41 | #' @param dashboard_color Dashboard background color.
42 | #' @param dashboard_fill Dashboard background fill.
43 | #' @param dashboard_linewidth Dashboard background line width.
44 | #' @param dashboard_linetype Dashboard background line type.
45 | #' @param clip_dashboard Whether the dashboard circle should clip to the legend boundary.
46 | #' @param close_dashboard Whether the dashboard should be closed where it meets the legend boundary.
47 | #' @param frame_color Color of the frame drawn around the arcs.
48 | #' @param frame_linewidth Width of the frame drawn around the arcs.
49 | #' @param frame_linetype Line type of the frame drawn around the arcs.
50 | #' @param aspect.ratio Aspect ratio for the legend.
51 | #' @param debug If `TRUE`, axes and origin for <[`legend-coords`][legend-coords]> are drawn over the legend for debugging.
52 | #' @param ... Ignored.
53 | #'
54 | #' @examples
55 | #' library(ggplot2)
56 | #' # A standard plot
57 | #' p <- ggplot(mtcars, aes(drat, hp)) +
58 | #' geom_point(aes(color = mpg))
59 | #' # Colormeter guide for color scale
60 | #' p +
61 | #' scale_color_viridis_c(
62 | #' option = "inferno",
63 | #' breaks = scales::breaks_pretty(10),
64 | #' guide = guide_colormeter()
65 | #' )
66 | #'
67 | #' @export
68 | #' @return A guide object of class 'colormeter'
69 | guide_colormeter <- function(title = ggplot2::waiver(), title.theme = NULL, label.theme = NULL,
70 | legend_size = unit(5, "lines"), legend_padding = unit(c(1.2, 1, 0.3, 1), "lines"),
71 | title_position = c(0, 0), arc_range = c(-4/7 * pi, 4/7 * pi),
72 | arc_radius = 1, arc_width = arc_radius/4, arc_gap = arc_radius/5, arc_rounding = 0,
73 | label_radius = arc_radius * 1.25, dashboard_radius = label_radius * 1.2,
74 | dashboard_color = "black", dashboard_fill = NA,
75 | dashboard_linewidth = 0.5, dashboard_linetype = 1,
76 | clip_dashboard = TRUE, close_dashboard = clip_dashboard,
77 | frame_color = NA, frame_linewidth = 0.5, frame_linetype = 1,
78 | aspect.ratio = 1, show.limits = NULL, debug = FALSE,
79 | reverse = FALSE, available_aes = c("colour", "color", "fill"),
80 | ...) {
81 | guide <- ggplot2::guide_colorsteps(
82 | even.steps = TRUE, ticks = FALSE, show.limits = show.limits,
83 | title = title, title.theme = title.theme, label.theme = label.theme,
84 | frame.colour = frame_color, frame.linewidth = frame_linewidth, frame.linetype = frame_linetype,
85 | reverse = reverse, available_aes = available_aes
86 | )
87 | guide$legend_size <- legend_size
88 | guide$legend_padding <- legend_padding
89 | guide$title_position <- title_position
90 | guide$arc_range <- arc_range
91 | guide$arc_radius <- arc_radius
92 | guide$arc_width <- arc_width
93 | guide$arc_gap <- arc_gap
94 | guide$arc_rounding <- arc_rounding
95 | guide$label_radius <- label_radius
96 | guide$clip_dashboard <- clip_dashboard
97 | guide$close_dashboard <- close_dashboard
98 | guide$dashboard_radius <- dashboard_radius
99 | guide$dashboard_color <- dashboard_color
100 | guide$dashboard_fill <- dashboard_fill
101 | guide$dashboard_linewidth <- dashboard_linewidth
102 | guide$dashboard_linetype <- dashboard_linetype
103 | guide$aspect.ratio <- aspect.ratio
104 | guide$debug <- debug
105 | class(guide) <- c("colormeter", class(guide))
106 | guide
107 | }
108 |
109 | #' @importFrom ggplot2 guide_gengrob
110 | #' @noRd
111 | #' @export
112 | #' @method guide_gengrob colormeter
113 | guide_gengrob.colormeter <- function(guide, theme) {
114 |
115 | n <- nrow(guide$bar)
116 | n_breaks <- n * 2 - 1
117 |
118 | arc_range <- guide$arc_range
119 | arc_gap <- guide$arc_gap
120 |
121 | bar_widths <- rep(pi/n_breaks, n_breaks)
122 | bar_widths[c(FALSE, TRUE)] <- bar_widths[1] * arc_gap
123 | bar_widths <- bar_widths * abs(diff(arc_range))/sum(bar_widths)
124 | bar_breaks <- (arc_range[1] + cumsum(c(0, bar_widths)))
125 |
126 | arcs <- data.frame(
127 | start = bar_breaks[-length(bar_breaks)],
128 | end = bar_breaks[-1],
129 | x0 = 0,
130 | y0 = 0,
131 | r0 = guide$arc_radius - guide$arc_width,
132 | r = guide$arc_radius,
133 | PANEL = 1,
134 | group = 1
135 | )
136 |
137 | arc_data <- arcPaths(arcs, 360)
138 | arc_data$group <- match(arc_data$group, unique(arc_data$group))
139 | arc_data <- arc_data[arc_data$group %% 2 == 1,]
140 |
141 | label <- guide$key$.label
142 | if (any(vapply(label, is.call, logical(1)))) {
143 | label <- lapply(label, function(l) {
144 | if (is.call(l))
145 | substitute(expression(x), list(x = l))
146 | else l
147 | })
148 | label <- do.call(c, label)
149 | }
150 | if (!isTRUE(guide$show.limits)) {
151 | label <- c("", label, "")
152 | }
153 | label_radius <- guide$label_radius
154 | if (!length(label_radius) %in% c(1, length(label))) {
155 | stop("Length of `label_radius` must be 1 or equal to the number of labels")
156 | }
157 | label_data <- radial_transform001(label_radius, seq(arc_range[1], arc_range[2], length.out = length(label)))
158 | label.theme <- guide$label.theme %||% ggplot2::calc_element("legend.text", theme)
159 | label_grob <- grid::textGrob(
160 | label = label,
161 | rot = label.theme$angle,
162 | gp = grid::gpar(
163 | fontsize = label.theme$size,
164 | fontfamily = label.theme$family,
165 | fontface = label.theme$face,
166 | col = label.theme$colour,
167 | lineheight = label.theme$lineheight
168 | ),
169 | x = label_data$x, y = label_data$y,
170 | hjust = label.theme$hjust %||% guide$label.hjust %||% 0.5,
171 | vjust = label.theme$vjust %||% guide$label.vjust %||% 0.5,
172 | default.units = "native",
173 | name = "guide.label"
174 | )
175 |
176 | # TODO: secondary labels at bar midpoints
177 |
178 | # label_grob <- ggplot2:::element_grob(
179 | # element = label.theme, label = c("", label, ""),
180 | # x = grid::unit(label_data$x, "native"),
181 | # y = grid::unit(label_data$y, "native"),
182 | # hjust = label.theme$title.hjust %||% 0.5,
183 | # vjust = label.theme$title.vjust %||% 0.5,
184 | # margin_x = FALSE, margin_y = TRUE
185 | # )
186 |
187 | arc_grob <- shapeGrob(
188 | arc_data$x, arc_data$y,
189 | default.units = 'native',
190 | id = arc_data$group,
191 | expand = 0,
192 | radius = guide$arc_rounding,
193 | gp = grid::gpar(
194 | col = guide$frame.colour,
195 | fill = guide$bar$colour,
196 | lwd = guide$frame.linewidth * ggplot2::.pt,
197 | lty = guide$frame.linetype
198 | )
199 | )
200 |
201 | legend_expansion <- c(0, 0, 0, 0)
202 | # TODO: wrap up legend_expansion is experimental
203 | # legend_expansion <- rep_len(guide$legend_expansion, 4)
204 | xrange <- range(label_data$x) * (legend_expansion[c(4, 2)] + 1) # legend_expansion[c(4, 2)]
205 | yrange <- range(label_data$y) * (legend_expansion[c(3, 1)] + 1) # legend_expansion[c(3, 1)]
206 | size <- guide$legend_size
207 | width <- size * abs(diff(xrange))/2 * sum(legend_expansion[c(2, 4)], 1)
208 | height <- size * abs(diff(yrange))/2 * guide$aspect.ratio * sum(legend_expansion[c(1, 3)], 1)
209 | width <- grid::convertUnit(width, "cm")
210 | height <- grid::convertUnit(height, "cm")
211 |
212 | legend_vp <- grid::viewport(xscale = xrange, yscale = yrange, width = width, height = height,
213 | gp = grid::gpar(lineheight = label.theme$lineheight))
214 |
215 | colormeter_grob <- grid::grobTree(arc_grob, label_grob, vp = legend_vp)
216 |
217 | background_grob <- ggplot2::element_render(theme, "legend.background")
218 |
219 | title.theme <- guide$title.theme %||% ggplot2::calc_element("legend.title", theme)
220 | title.theme$hjust <- title.theme$hjust + 0.5
221 | title.hjust <- guide$title.hjust %||% title.theme$hjust
222 | title.vjust <- guide$title.vjust %||% title.theme$vjust %||% 0.5
223 | title_grob <- ggplot2::element_grob(title.theme, label = guide$title,
224 | hjust = title.hjust, vjust = title.vjust,
225 | margin_x = TRUE, margin_y = TRUE)
226 | title_grob$name <- "guide.title"
227 | title_grob$vp <- legend_vp
228 | title_grob$children[[1]]$x <- grid::unit(guide$title_position[1], "native")
229 | title_grob$children[[1]]$y <- grid::unit(guide$title_position[2], "native")
230 |
231 |
232 | legend_padding <- rep_len(guide$legend_padding, 4)
233 | if (!grid::is.unit(legend_padding)) {legend_padding <- grid::unit(legend_padding, "lines")}
234 |
235 | dashboard_data <- radial_transform001(guide$dashboard_radius, seq(0, 2 * pi, length.out = 360))
236 | dashboard_gp <- grid::gpar(col = guide$dashboard_color, fill = guide$dashboard_fill,
237 | lwd = guide$dashboard_linewidth, lty = guide$dashboard_linetype)
238 | dashboard_grob <- grid::polygonGrob(
239 | x = grid::unit(dashboard_data$x, "native"),
240 | y = grid::unit(dashboard_data$y, "native") * (1 + (guide$aspect.ratio - 1)/2),
241 | gp = dashboard_gp, vp = legend_vp
242 | )
243 |
244 | gt <- gtable::gtable(widths = width, heights = height)
245 | gt <- gtable::gtable_add_padding(gt, padding = legend_padding)
246 |
247 | gt <- gtable::gtable_add_grob(gt, background_grob, name = "background",
248 | clip = "off", t = 1, r = 3, b = 3, l = 1)
249 | gt <- gtable::gtable_add_grob(gt, dashboard_grob, name = "dashboard",
250 | clip = guide$clip_dashboard, t = 1, r = 3, b = 3, l = 1)
251 | gt <- gtable::gtable_add_grob(gt, colormeter_grob, name = "colormeter",
252 | clip = "off", t = 2, r = 2, b = 2, l = 2)
253 | gt <- gtable::gtable_add_grob(gt, title_grob,
254 | name = "title", clip = "off", t = 2, r = 2, b = 2, l = 2)
255 | gt <- gtable::gtable_add_grob(gt, grid::editGrob(background_grob, gp = grid::gpar(fill = NA)), name = "outline",
256 | clip = "off", t = 1, r = 3, b = 3, l = 1)
257 |
258 | if (guide$close_dashboard) {
259 | dashboard_border_gp <- dashboard_gp
260 | dashboard_border_gp$fill <- NA
261 | dashboard_border <- grid::rectGrob(
262 | width = grid::convertUnit(sum(gt$widths), "cm"),
263 | height = grid::convertUnit(sum(gt$heights), "cm"),
264 | gp = dashboard_border_gp,
265 | vp = grid::editViewport(legend_vp, mask = grid::editGrob(dashboard_grob, gp = grid::gpar(fill = "white")))
266 | )
267 | gt <- gtable::gtable_add_grob(gt, dashboard_border, name = "dashboard_close",
268 | clip = "off", t = 1, r = 3, b = 3, l = 1)
269 | }
270 |
271 | if (guide$debug) {
272 | gt <- gtable::gtable_filter(gt, "background", invert = TRUE)
273 | gt$grobs[[which(gt$layout$name == "outline")]]$gp <- grid::gpar(lty = 5, fill = NA, col = "turquoise")
274 | xaxis <- grid::xaxisGrob(vp = legend_vp)
275 | yaxis <- grid::yaxisGrob(vp = legend_vp)
276 | origin <- grid::pointsGrob(0, 0, default.units = "native", vp = legend_vp)
277 | gt <- gtable::gtable_add_grob(gt, grid::grobTree(xaxis, yaxis, origin, gp = grid::gpar(col = "steelblue")),
278 | name = "axes", clip = "off", t = 2, r = 2, b = 2, l = 2)
279 | }
280 |
281 | gt
282 |
283 | }
284 |
--------------------------------------------------------------------------------
/R/unexported-ggforce.R:
--------------------------------------------------------------------------------
1 | # nocov start
2 | `%||%` <- function(lhs, rhs) {
3 | if (!is.null(lhs)) lhs else rhs
4 | }
5 |
6 | #' @importFrom grid is.unit grob gpar polygonGrob unit
7 | shapeGrob <- function(x = c(0, 0.5, 1, 0.5), y = c(0.5, 1, 0.5, 0), id = NULL,
8 | id.lengths = NULL, expand = 0, radius = 0,
9 | default.units = 'npc', name = NULL, gp = gpar(),
10 | vp = NULL) {
11 | if (as.numeric(expand) == 0 && as.numeric(radius) == 0) {
12 | grob <- polygonGrob(
13 | x = x, y = y, id = id, id.lengths = id.lengths,
14 | default.units = default.units, name = name, gp = gp, vp = vp
15 | )
16 | return(grob)
17 | }
18 | if (!is.unit(x)) {
19 | x <- unit(x, default.units)
20 | }
21 | if (!is.unit(y)) {
22 | y <- unit(y, default.units)
23 | }
24 | if (!is.unit(expand)) {
25 | expand <- unit(expand, default.units)
26 | }
27 | if (!is.unit(radius)) {
28 | radius <- unit(radius, default.units)
29 | }
30 | if (as.numeric(radius) < 0) {
31 | stop('radius must be positive', call. = FALSE)
32 | }
33 | if (is.null(id)) {
34 | if (is.null(id.lengths)) {
35 | id <- rep(1, length(x))
36 | } else {
37 | id <- rep(seq_along(id.lengths), id.lengths)
38 | if (length(id) != length(x)) {
39 | stop('id.lengths must sum up to the number of points', call. = FALSE)
40 | }
41 | }
42 | }
43 | x <- x[order(id)]
44 | y <- y[order(id)]
45 | grob(
46 | x = x, y = y, id = id, expand = expand, radius = radius, name = name,
47 | gp = gp, vp = vp, cl = 'shape'
48 | )
49 | }
50 |
51 | #' @importFrom grid makeContent convertX convertY convertWidth gpar polygonGrob nullGrob unit
52 | #' @importFrom polyclip polyoffset polylineoffset
53 | #' @keywords internal
54 | #' @export
55 | #' @method makeContent shape
56 | makeContent.shape <- function(x) {
57 | id.length <- lengths(split(seq_along(x$id), x$id))
58 | type <- ifelse(id.length == 1, 'point',
59 | ifelse(id.length == 2, 'line', 'polygon'))
60 | x_new <- convertX(x$x, 'mm', TRUE)
61 | x_new <- split(x_new, x$id)
62 | y_new <- convertY(x$y, 'mm', TRUE)
63 | y_new <- split(y_new, x$id)
64 | polygons <- Map(list, x = x_new, y = y_new)
65 | poly <- split(polygons, type)
66 | expand <- convertWidth(x$expand, 'mm', TRUE)
67 | radius <- convertWidth(x$radius, 'mm', TRUE)
68 | expand <- expand - radius
69 | if (expand != 0) {
70 | if (!is.null(poly$polygon)) {
71 | poly$polygon <- lapply(poly$polygon, polyoffset, delta = expand,
72 | jointype = 'miter', miterlim = 1000)
73 | }
74 | if (expand > 0) {
75 | if (!is.null(poly$line)) {
76 | poly$line <- lapply(poly$line, polylineoffset, delta = expand,
77 | jointype = 'square', endtype = 'opensquare')
78 | }
79 | poly$point <- pointoffset(poly$point, expand, type = 'square')
80 | }
81 | }
82 | if (radius != 0) {
83 | if (!is.null(poly$polygon)) {
84 | not_empty <- lengths(poly$polygon) != 0
85 | poly$polygon[not_empty] <- lapply(poly$polygon[not_empty], polyoffset,
86 | delta = radius, jointype = 'round')
87 | }
88 | if (expand > 0) {
89 | if (!is.null(poly$line)) {
90 | not_empty <- lengths(poly$line) != 0
91 | poly$line[not_empty] <- lapply(poly$line[not_empty], polyoffset,
92 | delta = radius, jointype = 'round')
93 | }
94 | if (!is.null(poly$point)) {
95 | not_empty <- lengths(poly$point) != 0
96 | poly$point[not_empty] <- lapply(poly$point[not_empty], polyoffset,
97 | delta = radius, jointype = 'round')
98 | }
99 | } else {
100 | if (!is.null(poly$line)) {
101 | poly$line <- lapply(poly$line, polylineoffset, delta = radius,
102 | jointype = 'round', endtype = 'openround')
103 | }
104 | poly$point <- pointoffset(poly$point, radius, type = 'circle')
105 | }
106 | }
107 | polygons[type == 'polygon'] <- lapply(poly$polygon, function(d) if (length(d) == 0) list() else d[[1]])
108 | polygons[type == 'line'] <- lapply(poly$line, function(d) if (length(d) == 0) list() else d[[1]])
109 | polygons[type == 'point'] <- lapply(poly$point, function(d) if (length(d) == 0) list() else d[[1]])
110 | x$id <- rep(seq_along(polygons), sapply(polygons, function(p) length(p$x)))
111 | x_new <- unlist(lapply(polygons, `[[`, 'x'))
112 | y_new <- unlist(lapply(polygons, `[[`, 'y'))
113 | if (length(x_new) == 0) return(nullGrob())
114 | x$x <- unit(x_new, 'mm')
115 | x$y <- unit(y_new, 'mm')
116 | x$cl <- 'polygon'
117 | class(x)[1] <- 'polygon'
118 | x
119 | }
120 |
121 | pointoffset <- function(A, delta, type) {
122 | if (length(A) == 0) return(A)
123 | switch(
124 | type,
125 | square = {
126 | square <- list(x = c(-delta, -delta, delta, delta),
127 | y = c(-delta, delta, delta, -delta))
128 | x <- split(rep(sapply(A, `[[`, 'x'), each = 4) + square$x,
129 | rep(seq_along(A), each = 4))
130 | y <- split(rep(sapply(A, `[[`, 'y'), each = 4) + square$y,
131 | rep(seq_along(A), each = 4))
132 | lapply(Map(list, x = x, y = y), list)
133 | },
134 | circle = {
135 | detail <- 100
136 | radi <- seq(0, 2 * pi, length.out = detail + 1)[-(detail + 1)]
137 | circle <- list(x = cos(radi) * delta, y = sin(radi) * delta)
138 | x <- split(rep(sapply(A, `[[`, 'x'), each = detail) + circle$x,
139 | rep(seq_along(A), each = detail))
140 | y <- split(rep(sapply(A, `[[`, 'y'), each = detail) + circle$y,
141 | rep(seq_along(A), each = detail))
142 | lapply(Map(list, x = x, y = y), list)
143 | }
144 | )
145 | }
146 |
147 | radial_transform001 <- function(r, a) {data.frame(x = r * sin(a), y = r * cos(a))}
148 |
149 | # Modified
150 | arcPaths <- function(data, n) {
151 | data <- data[data$start != data$end, ]
152 | data$nControl <- ceiling(n / (2 * pi) * abs(data$end - data$start))
153 | data$nControl[data$nControl < 3] <- 3
154 | extraData <- !names(data) %in% c('r0', 'r', 'start', 'end', 'group')
155 | data$group <- make.unique(as.character(data$group))
156 | paths <- lapply(seq_len(nrow(data)), function(i) {
157 | path <- data.frame(
158 | a = seq(data$start[i], data$end[i], length.out = data$nControl[i]),
159 | r = data$r[i]
160 | )
161 | if ('r0' %in% names(data)) {
162 | if (data$r0[i] != 0) {
163 | path <- rbind(
164 | path,
165 | data.frame(a = rev(path$a), r = data$r0[i])
166 | )
167 | } else {
168 | path <- rbind(
169 | path,
170 | data.frame(a = data$start[i], r = 0)
171 | )
172 | }
173 | }
174 | path$group <- data$group[i]
175 | path$index <- seq(0, 1, length.out = nrow(path))
176 | path <- cbind(path, data[rep(i, nrow(path)), extraData, drop = FALSE])
177 | })
178 | paths <- do.call(rbind, paths)
179 | paths <- cbind(
180 | paths[, !names(paths) %in% c('r', 'a')],
181 | radial_transform001(paths$r, paths$a)
182 | )
183 | paths$x <- paths$x + paths$x0
184 | paths$y <- paths$y + paths$y0
185 | if ('explode' %in% names(data)) {
186 | exploded <- data$explode != 0
187 | if (any(exploded)) {
188 | exploder <- radial_transform001(
189 | data$explode[exploded],
190 | data$start[exploded] + (data$end[exploded] - data$start[exploded]) / 2
191 | )
192 | explodedPaths <- paths$group %in% which(exploded)
193 | exploderInd <- as.integer(factor(paths$group[explodedPaths]))
194 | paths$x[explodedPaths] <-
195 | paths$x[explodedPaths] + exploder$x[exploderInd]
196 | paths$y[explodedPaths] <-
197 | paths$y[explodedPaths] + exploder$y[exploderInd]
198 | }
199 | }
200 | paths[, !names(paths) %in% c('x0', 'y0', 'exploded')]
201 | }
202 | # nocov end
203 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 |
6 |
7 | ```{r, include = FALSE}
8 | knitr::opts_chunk$set(
9 | collapse = TRUE,
10 | comment = "#>",
11 | fig.path = "man/figures/README-",
12 | out.width = "100%",
13 | dev.args = list(png = list(type = "cairo")),
14 | fig.retina = 2
15 | )
16 | ```
17 |
18 | # ggcolormeter
19 |
20 |
21 | [)`-gogreen.svg)](https://github.com/yjunechoe/ggcolormeter)
22 | [](https://github.com/yjunechoe/ggcolormeter/actions/workflows/R-CMD-check.yaml)
23 | [](https://app.codecov.io/gh/yjunechoe/ggcolormeter?branch=main)
24 |
25 |
26 | The `{ggcolormeter}` package provides a single function [`guide_colormeter()`](https://yjunechoe.github.io/ggcolormeter/reference/guide_colormeter.html), which is a `{ggplot2}` color/fill legend **guide extension** in the style of a dashboard meter.
27 |
28 | ## Installation
29 |
30 | ```{r, eval=FALSE}
31 | install.packages("ggcolormeter")
32 | # or
33 | remotes::install_github("yjunechoe/ggcolormeter")
34 | ```
35 |
36 |
37 | ## Simple usage
38 |
39 | ```{r simple-usage}
40 | library(ggplot2)
41 | library(ggcolormeter)
42 |
43 | theme_set(theme_classic())
44 |
45 | p <- ggplot(mtcars, aes(drat, hp)) +
46 | geom_point(aes(color = mpg))
47 |
48 | p +
49 | scale_color_viridis_c(
50 | option = "inferno",
51 | breaks = scales::breaks_pretty(10),
52 | guide = guide_colormeter()
53 | )
54 | ```
55 |
56 | # Colormeter guide theme components
57 |
58 | The colormeter guide has argument families for styling 5 distinct components of the guide:
59 |
60 | 1) [Size and aspect](https://github.com/yjunechoe/ggcolormeter#1-size-and-aspect)
61 | 2) [Arc](https://github.com/yjunechoe/ggcolormeter#2-arc)
62 | 3) [Label](https://github.com/yjunechoe/ggcolormeter#3-label)
63 | 4) [Dashboard](https://github.com/yjunechoe/ggcolormeter#4-dashboard)
64 | 5) [Frame](https://github.com/yjunechoe/ggcolormeter#5-frame)
65 |
66 | Position of these theme elements is relative to the [guide-internal coordinate system](https://yjunechoe.github.io/ggcolormeter/reference/legend-coords.html), which you can inspect with the `debug = TRUE` argument.
67 |
68 | ## 1) Size and aspect
69 |
70 | The colormeter legend is a bit pecular in that its size doesn't expand with more keys: the colormeter has a fixed size and shape, and its elements are packed inside it.
71 |
72 | You can primarily control the size of the legend with `legend_size` and `aspect.ratio`
73 |
74 | ```{r}
75 | p +
76 | scale_color_viridis_c(
77 | option = "inferno",
78 | breaks = scales::breaks_pretty(10),
79 | guide = guide_colormeter(
80 | legend_size = unit(3, "cm"),
81 | aspect.ratio = .8
82 | )
83 | )
84 | ```
85 |
86 | Note that the usual legend background is still present and different from the dashboard circle:
87 |
88 | ```{r}
89 | p +
90 | scale_color_viridis_c(
91 | option = "inferno",
92 | breaks = scales::breaks_pretty(10),
93 | guide = guide_colormeter(
94 | legend_size = unit(3, "cm"),
95 | aspect.ratio = .8
96 | )
97 | ) +
98 | theme(legend.background = element_rect(color = "red", fill = "pink"))
99 | ```
100 |
101 | Most of the time you'd want to remove this legend background, as the dashboard serves that purpose:
102 |
103 | ```{r}
104 | p +
105 | scale_color_viridis_c(
106 | option = "inferno",
107 | breaks = scales::breaks_pretty(10),
108 | guide = guide_colormeter(
109 | )
110 | ) +
111 | theme(
112 | legend.position = c(.85, .75),
113 | legend.background = element_blank()
114 | )
115 | ```
116 |
117 | ## 2) Arc
118 |
119 | ```{r}
120 | formals(guide_colormeter)[grepl("arc", names(formals(guide_colormeter)))]
121 | ```
122 |
123 | Non-positional aesthetic arguments for the color arc:
124 |
125 | ```{r arc-theme}
126 | p +
127 | scale_color_viridis_c(
128 | option = "inferno",
129 | breaks = scales::breaks_pretty(10),
130 | guide = guide_colormeter(
131 | arc_width = 1/6, # thinner arcs
132 | arc_gap = 1/3, # bigger gaps
133 | arc_rounding = 0.03 # rounded corners
134 | )
135 | )
136 | ```
137 |
138 | By default, label and dashboard radii are derived from `arc_radius`:
139 |
140 | ```{r arc-radius}
141 | p +
142 | scale_color_viridis_c(
143 | option = "inferno",
144 | breaks = scales::breaks_pretty(10),
145 | guide = guide_colormeter(
146 | arc_radius = 1.2
147 | )
148 | )
149 | ```
150 |
151 | You can use `arc_range` to set the start and end angles of the color meter, which may yield different shapes:
152 |
153 | ```{r}
154 | p +
155 | scale_color_viridis_c(
156 | option = "inferno",
157 | breaks = scales::breaks_pretty(5), # half the arcs
158 | guide = guide_colormeter(
159 | arc_range = c(-pi/2, 0) # quarter circle
160 | )
161 | )
162 | ```
163 |
164 | The defaults aren't great for when you change from the dashboard shape. Some manual adjustments may be desirable:
165 |
166 | ```{r}
167 | p +
168 | scale_color_viridis_c(
169 | option = "inferno",
170 | breaks = scales::breaks_pretty(5),
171 | guide = guide_colormeter(
172 | arc_range = c(-pi/2, 0),
173 | title_position = c(-.2, .2), # moves title left and up from center
174 | legend_padding = grid::unit(0.7, "lines") # pads relative to legend label
175 | )
176 | )
177 | ```
178 |
179 | ## 3) Label
180 |
181 | ```{r}
182 | formals(guide_colormeter)[grepl("label", names(formals(guide_colormeter)))]
183 | ```
184 |
185 | By default, the dashboard radius is derived from `label_radius`:
186 |
187 | ```{r}
188 | p +
189 | scale_color_viridis_c(
190 | option = "inferno",
191 | breaks = scales::breaks_pretty(10),
192 | guide = guide_colormeter(
193 | label_radius = 1.5
194 | )
195 | )
196 | ```
197 |
198 | Like `ggplot2::guide_colorsteps()`, the argument `show.limits` controls labeling the limits of the scale:
199 |
200 | ```{r}
201 | p +
202 | scale_color_viridis_c(
203 | option = "inferno",
204 | breaks = scales::breaks_pretty(10),
205 | guide = guide_colormeter(
206 | label_radius = 1.3,
207 | show.limits = TRUE
208 | )
209 | )
210 | ```
211 |
212 | ## 4) Dashboard
213 |
214 | ```{r}
215 | formals(guide_colormeter)[grepl("dashboard", names(formals(guide_colormeter)))]
216 | ```
217 |
218 | `dashboard_radius` controls the radius of just the dashboard circle
219 |
220 | ```{r}
221 | p +
222 | scale_color_viridis_c(
223 | option = "inferno",
224 | breaks = scales::breaks_pretty(10),
225 | guide = guide_colormeter(
226 | dashboard_radius = 1.2,
227 | )
228 | )
229 | ```
230 |
231 | By default, the dashboard is clipped to the legend boundary, which can be turned off:
232 |
233 | ```{r}
234 | p +
235 | scale_color_viridis_c(
236 | option = "inferno",
237 | breaks = scales::breaks_pretty(10),
238 | guide = guide_colormeter(
239 | title = "mpg
240 | miles per gallon",
241 | clip_dashboard = FALSE
242 | )
243 | ) +
244 | theme(legend.title = ggtext::element_markdown(vjust = -.6))
245 | ```
246 |
247 | Non-positional aesthetic arguments for the dashboard:
248 |
249 | ```{r}
250 | p +
251 | scale_color_viridis_c(
252 | option = "inferno",
253 | breaks = scales::breaks_pretty(10),
254 | guide = guide_colormeter(
255 | dashboard_fill = "skyblue",
256 | dashboard_color = "steelblue",
257 | dashboard_linetype = 5,
258 | dashboard_linewidth = 4
259 | )
260 | )
261 | ```
262 |
263 | ## 5) Frame
264 |
265 | ```{r}
266 | formals(guide_colormeter)[grepl("frame", names(formals(guide_colormeter)))]
267 | ```
268 |
269 | Frames simply decorate the color arcs/bars:
270 |
271 | ```{r}
272 | p +
273 | scale_color_viridis_c(
274 | option = "inferno",
275 | breaks = scales::breaks_pretty(10),
276 | guide = guide_colormeter(
277 | frame_color = "black",
278 | frame_linewidth = .3
279 | )
280 | )
281 | ```
282 |
283 | ## Miscellaneous
284 |
285 | Set `debug = TRUE` to inspect the internal legend coordinate system (for deciding on `dashboard_radius`, `arc_width`, `title_position`, etc.):
286 |
287 | ```{r}
288 | p +
289 | scale_color_viridis_c(
290 | option = "inferno",
291 | breaks = scales::breaks_pretty(10),
292 | guide = guide_colormeter(debug = TRUE)
293 | )
294 | ```
295 |
296 | Puttings labels inside the arc:
297 |
298 | ```{r}
299 | p +
300 | scale_color_viridis_c(
301 | option = "inferno",
302 | breaks = scales::breaks_pretty(5),
303 | guide = guide_colormeter(
304 | arc_width = 0.1,
305 | label_radius = .7,
306 | aspect.ratio = 1.1,
307 | dashboard_color = NA
308 | )
309 | ) +
310 | theme(legend.position = c(.85, .75))
311 | ```
312 |
313 | ## Acknowledgments
314 |
315 | - Thomas Lin Pedersen for [`{ggforce}`](https://github.com/thomasp85/ggforce), whose several unexported functions are used in this package.
316 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # ggcolormeter
5 |
6 |
7 |
8 | [](https://github.com/yjunechoe/ggcolormeter)
9 | [](https://github.com/yjunechoe/ggcolormeter/actions/workflows/R-CMD-check.yaml)
10 | [](https://app.codecov.io/gh/yjunechoe/ggcolormeter?branch=main)
12 |
13 |
14 | The `{ggcolormeter}` package provides a single function
15 | [`guide_colormeter()`](https://yjunechoe.github.io/ggcolormeter/reference/guide_colormeter.html),
16 | which is a `{ggplot2}` color/fill legend **guide extension** in the
17 | style of a dashboard meter.
18 |
19 | ## Installation
20 |
21 | ``` r
22 | install.packages("ggcolormeter")
23 | # or
24 | remotes::install_github("yjunechoe/ggcolormeter")
25 | ```
26 |
27 | ## Simple usage
28 |
29 | ``` r
30 | library(ggplot2)
31 | library(ggcolormeter)
32 |
33 | theme_set(theme_classic())
34 |
35 | p <- ggplot(mtcars, aes(drat, hp)) +
36 | geom_point(aes(color = mpg))
37 |
38 | p +
39 | scale_color_viridis_c(
40 | option = "inferno",
41 | breaks = scales::breaks_pretty(10),
42 | guide = guide_colormeter()
43 | )
44 | ```
45 |
46 |
47 |
48 | # Colormeter guide theme components
49 |
50 | The colormeter guide has argument families for styling 5 distinct
51 | components of the guide:
52 |
53 | 1) [Size and
54 | aspect](#1-size-and-aspect)
55 | 2) [Arc](#2-arc)
56 | 3) [Label](#3-label)
57 | 4) [Dashboard](#4-dashboard)
58 | 5) [Frame](#5-frame)
59 |
60 | Position of these theme elements is relative to the [guide-internal
61 | coordinate
62 | system](https://yjunechoe.github.io/ggcolormeter/reference/legend-coords.html),
63 | which you can inspect with the `debug = TRUE` argument.
64 |
65 | ## 1) Size and aspect
66 |
67 | The colormeter legend is a bit pecular in that its size doesn’t expand
68 | with more keys: the colormeter has a fixed size and shape, and its
69 | elements are packed inside it.
70 |
71 | You can primarily control the size of the legend with `legend_size` and
72 | `aspect.ratio`
73 |
74 | ``` r
75 | p +
76 | scale_color_viridis_c(
77 | option = "inferno",
78 | breaks = scales::breaks_pretty(10),
79 | guide = guide_colormeter(
80 | legend_size = unit(3, "cm"),
81 | aspect.ratio = .8
82 | )
83 | )
84 | ```
85 |
86 |
87 |
88 | Note that the usual legend background is still present and different
89 | from the dashboard circle:
90 |
91 | ``` r
92 | p +
93 | scale_color_viridis_c(
94 | option = "inferno",
95 | breaks = scales::breaks_pretty(10),
96 | guide = guide_colormeter(
97 | legend_size = unit(3, "cm"),
98 | aspect.ratio = .8
99 | )
100 | ) +
101 | theme(legend.background = element_rect(color = "red", fill = "pink"))
102 | ```
103 |
104 |
105 |
106 | Most of the time you’d want to remove this legend background, as the
107 | dashboard serves that purpose:
108 |
109 | ``` r
110 | p +
111 | scale_color_viridis_c(
112 | option = "inferno",
113 | breaks = scales::breaks_pretty(10),
114 | guide = guide_colormeter(
115 | )
116 | ) +
117 | theme(
118 | legend.position = c(.85, .75),
119 | legend.background = element_blank()
120 | )
121 | ```
122 |
123 |
124 |
125 | ## 2) Arc
126 |
127 | ``` r
128 | formals(guide_colormeter)[grepl("arc", names(formals(guide_colormeter)))]
129 | #> $arc_range
130 | #> c(-4/7 * pi, 4/7 * pi)
131 | #>
132 | #> $arc_radius
133 | #> [1] 1
134 | #>
135 | #> $arc_width
136 | #> arc_radius/4
137 | #>
138 | #> $arc_gap
139 | #> arc_radius/5
140 | #>
141 | #> $arc_rounding
142 | #> [1] 0
143 | ```
144 |
145 | Non-positional aesthetic arguments for the color arc:
146 |
147 | ``` r
148 | p +
149 | scale_color_viridis_c(
150 | option = "inferno",
151 | breaks = scales::breaks_pretty(10),
152 | guide = guide_colormeter(
153 | arc_width = 1/6, # thinner arcs
154 | arc_gap = 1/3, # bigger gaps
155 | arc_rounding = 0.03 # rounded corners
156 | )
157 | )
158 | ```
159 |
160 |
161 |
162 | By default, label and dashboard radii are derived from `arc_radius`:
163 |
164 | ``` r
165 | p +
166 | scale_color_viridis_c(
167 | option = "inferno",
168 | breaks = scales::breaks_pretty(10),
169 | guide = guide_colormeter(
170 | arc_radius = 1.2
171 | )
172 | )
173 | ```
174 |
175 |
176 |
177 | You can use `arc_range` to set the start and end angles of the color
178 | meter, which may yield different shapes:
179 |
180 | ``` r
181 | p +
182 | scale_color_viridis_c(
183 | option = "inferno",
184 | breaks = scales::breaks_pretty(5), # half the arcs
185 | guide = guide_colormeter(
186 | arc_range = c(-pi/2, 0) # quarter circle
187 | )
188 | )
189 | ```
190 |
191 |
192 |
193 | The defaults aren’t great for when you change from the dashboard shape.
194 | Some manual adjustments may be desirable:
195 |
196 | ``` r
197 | p +
198 | scale_color_viridis_c(
199 | option = "inferno",
200 | breaks = scales::breaks_pretty(5),
201 | guide = guide_colormeter(
202 | arc_range = c(-pi/2, 0),
203 | title_position = c(-.2, .2), # moves title left and up from center
204 | legend_padding = grid::unit(0.7, "lines") # pads relative to legend label
205 | )
206 | )
207 | ```
208 |
209 |
210 |
211 | ## 3) Label
212 |
213 | ``` r
214 | formals(guide_colormeter)[grepl("label", names(formals(guide_colormeter)))]
215 | #> $label.theme
216 | #> NULL
217 | #>
218 | #> $label_radius
219 | #> arc_radius * 1.25
220 | ```
221 |
222 | By default, the dashboard radius is derived from `label_radius`:
223 |
224 | ``` r
225 | p +
226 | scale_color_viridis_c(
227 | option = "inferno",
228 | breaks = scales::breaks_pretty(10),
229 | guide = guide_colormeter(
230 | label_radius = 1.5
231 | )
232 | )
233 | ```
234 |
235 |
236 |
237 | Like `ggplot2::guide_colorsteps()`, the argument `show.limits` controls
238 | labeling the limits of the scale:
239 |
240 | ``` r
241 | p +
242 | scale_color_viridis_c(
243 | option = "inferno",
244 | breaks = scales::breaks_pretty(10),
245 | guide = guide_colormeter(
246 | label_radius = 1.3,
247 | show.limits = TRUE
248 | )
249 | )
250 | ```
251 |
252 |
253 |
254 | ## 4) Dashboard
255 |
256 | ``` r
257 | formals(guide_colormeter)[grepl("dashboard", names(formals(guide_colormeter)))]
258 | #> $dashboard_radius
259 | #> label_radius * 1.2
260 | #>
261 | #> $dashboard_color
262 | #> [1] "black"
263 | #>
264 | #> $dashboard_fill
265 | #> [1] NA
266 | #>
267 | #> $dashboard_linewidth
268 | #> [1] 0.5
269 | #>
270 | #> $dashboard_linetype
271 | #> [1] 1
272 | #>
273 | #> $clip_dashboard
274 | #> [1] TRUE
275 | #>
276 | #> $close_dashboard
277 | #> clip_dashboard
278 | ```
279 |
280 | `dashboard_radius` controls the radius of just the dashboard circle
281 |
282 | ``` r
283 | p +
284 | scale_color_viridis_c(
285 | option = "inferno",
286 | breaks = scales::breaks_pretty(10),
287 | guide = guide_colormeter(
288 | dashboard_radius = 1.2,
289 | )
290 | )
291 | ```
292 |
293 |
294 |
295 | By default, the dashboard is clipped to the legend boundary, which can
296 | be turned off:
297 |
298 | ``` r
299 | p +
300 | scale_color_viridis_c(
301 | option = "inferno",
302 | breaks = scales::breaks_pretty(10),
303 | guide = guide_colormeter(
304 | title = "mpg
305 | miles per gallon",
306 | clip_dashboard = FALSE
307 | )
308 | ) +
309 | theme(legend.title = ggtext::element_markdown(vjust = -.6))
310 | ```
311 |
312 |
313 |
314 | Non-positional aesthetic arguments for the dashboard:
315 |
316 | ``` r
317 | p +
318 | scale_color_viridis_c(
319 | option = "inferno",
320 | breaks = scales::breaks_pretty(10),
321 | guide = guide_colormeter(
322 | dashboard_fill = "skyblue",
323 | dashboard_color = "steelblue",
324 | dashboard_linetype = 5,
325 | dashboard_linewidth = 4
326 | )
327 | )
328 | ```
329 |
330 |
331 |
332 | ## 5) Frame
333 |
334 | ``` r
335 | formals(guide_colormeter)[grepl("frame", names(formals(guide_colormeter)))]
336 | #> $frame_color
337 | #> [1] NA
338 | #>
339 | #> $frame_linewidth
340 | #> [1] 0.5
341 | #>
342 | #> $frame_linetype
343 | #> [1] 1
344 | ```
345 |
346 | Frames simply decorate the color arcs/bars:
347 |
348 | ``` r
349 | p +
350 | scale_color_viridis_c(
351 | option = "inferno",
352 | breaks = scales::breaks_pretty(10),
353 | guide = guide_colormeter(
354 | frame_color = "black",
355 | frame_linewidth = .3
356 | )
357 | )
358 | ```
359 |
360 |
361 |
362 | ## Miscellaneous
363 |
364 | Set `debug = TRUE` to inspect the internal legend coordinate system (for
365 | deciding on `dashboard_radius`, `arc_width`, `title_position`, etc.):
366 |
367 | ``` r
368 | p +
369 | scale_color_viridis_c(
370 | option = "inferno",
371 | breaks = scales::breaks_pretty(10),
372 | guide = guide_colormeter(debug = TRUE)
373 | )
374 | ```
375 |
376 |
377 |
378 | Puttings labels inside the arc:
379 |
380 | ``` r
381 | p +
382 | scale_color_viridis_c(
383 | option = "inferno",
384 | breaks = scales::breaks_pretty(5),
385 | guide = guide_colormeter(
386 | arc_width = 0.1,
387 | label_radius = .7,
388 | aspect.ratio = 1.1,
389 | dashboard_color = NA
390 | )
391 | ) +
392 | theme(legend.position = c(.85, .75))
393 | ```
394 |
395 |
396 |
397 | ## Acknowledgments
398 |
399 | - Thomas Lin Pedersen for
400 | [`{ggforce}`](https://github.com/thomasp85/ggforce), whose several
401 | unexported functions are used in this package.
402 |
--------------------------------------------------------------------------------
/_pkgdown.yml:
--------------------------------------------------------------------------------
1 | url: https://yjunechoe.github.io/ggcolormeter/
2 | template:
3 | bootstrap: 5
4 |
5 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | comment: false
2 |
3 | coverage:
4 | status:
5 | project:
6 | default:
7 | target: auto
8 | threshold: 1%
9 | informational: true
10 | patch:
11 | default:
12 | target: auto
13 | threshold: 1%
14 | informational: true
15 |
--------------------------------------------------------------------------------
/cran-comments.md:
--------------------------------------------------------------------------------
1 | ## R CMD check results
2 |
3 | 0 errors | 0 warnings | 1 note
4 |
5 | * This is a new release.
6 |
--------------------------------------------------------------------------------
/ggcolormeter.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: knitr
13 | LaTeX: pdfLaTeX
14 |
15 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageUseDevtools: Yes
20 | PackageInstallArgs: --no-multiarch --with-keep.source
21 |
--------------------------------------------------------------------------------
/man/figures/README-arc-radius-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-arc-radius-1.png
--------------------------------------------------------------------------------
/man/figures/README-arc-theme-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-arc-theme-1.png
--------------------------------------------------------------------------------
/man/figures/README-simple-usage-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-simple-usage-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-10-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-10-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-11-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-11-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-12-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-12-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-13-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-13-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-14-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-14-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-15-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-15-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-16-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-16-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-17-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-17-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-18-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-18-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-19-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-19-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-2-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-2-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-3-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-3-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-4-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-4-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-5-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-5-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-6-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-6-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-7-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-7-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-8-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-8-1.png
--------------------------------------------------------------------------------
/man/figures/README-unnamed-chunk-9-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjunechoe/ggcolormeter/30f5b3a1b9ed66dc91f7ef86d53d99bbffb3c469/man/figures/README-unnamed-chunk-9-1.png
--------------------------------------------------------------------------------
/man/guide_colormeter.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/guide_colormeter.R
3 | \name{guide_colormeter}
4 | \alias{guide_colormeter}
5 | \title{A color legend in the style of a dashboard meter}
6 | \usage{
7 | guide_colormeter(
8 | title = ggplot2::waiver(),
9 | title.theme = NULL,
10 | label.theme = NULL,
11 | legend_size = unit(5, "lines"),
12 | legend_padding = unit(c(1.2, 1, 0.3, 1), "lines"),
13 | title_position = c(0, 0),
14 | arc_range = c(-4/7 * pi, 4/7 * pi),
15 | arc_radius = 1,
16 | arc_width = arc_radius/4,
17 | arc_gap = arc_radius/5,
18 | arc_rounding = 0,
19 | label_radius = arc_radius * 1.25,
20 | dashboard_radius = label_radius * 1.2,
21 | dashboard_color = "black",
22 | dashboard_fill = NA,
23 | dashboard_linewidth = 0.5,
24 | dashboard_linetype = 1,
25 | clip_dashboard = TRUE,
26 | close_dashboard = clip_dashboard,
27 | frame_color = NA,
28 | frame_linewidth = 0.5,
29 | frame_linetype = 1,
30 | aspect.ratio = 1,
31 | show.limits = NULL,
32 | debug = FALSE,
33 | reverse = FALSE,
34 | available_aes = c("colour", "color", "fill"),
35 | ...
36 | )
37 | }
38 | \arguments{
39 | \item{title}{A character string or expression indicating a title of guide.
40 | If \code{NULL}, the title is not shown. By default
41 | (\code{\link[ggplot2:waiver]{waiver()}}), the name of the scale object or the name
42 | specified in \code{\link[ggplot2:labs]{labs()}} is used for the title.}
43 |
44 | \item{title.theme}{A theme object for rendering the title text. Usually the
45 | object of \code{\link[ggplot2:element_text]{element_text()}} is expected. By default, the theme is
46 | specified by \code{legend.title} in \code{\link[ggplot2:theme]{theme()}} or theme.}
47 |
48 | \item{label.theme}{A theme object for rendering the label text. Usually the
49 | object of \code{\link[ggplot2:element_text]{element_text()}} is expected. By default, the theme is
50 | specified by \code{legend.text} in \code{\link[ggplot2:theme]{theme()}}.}
51 |
52 | \item{legend_size}{Size of the legend box.}
53 |
54 | \item{legend_padding}{Spacing between the color meter and the legend boundary.}
55 |
56 | \item{title_position}{<\code{\link{legend-coords}}> 2-length vector for the x/y-position of the legend title.}
57 |
58 | \item{arc_range}{<\code{\link{legend-coords}}> 2-length vector for the start and end angles of the color meter.}
59 |
60 | \item{arc_radius}{<\code{\link{legend-coords}}> Radius of the color meter.}
61 |
62 | \item{arc_width}{<\code{\link{legend-coords}}> Width of the arcs in the color meter.}
63 |
64 | \item{arc_gap}{<\code{\link{legend-coords}}> Gap between arcs in the color meter.}
65 |
66 | \item{arc_rounding}{<\code{\link{legend-coords}}> Rounding of arcs in the color meter.}
67 |
68 | \item{label_radius}{<\code{\link{legend-coords}}> Radius of the labels.}
69 |
70 | \item{dashboard_radius}{<\code{\link{legend-coords}}> Radius of the dashboard background.}
71 |
72 | \item{dashboard_color}{Dashboard background color.}
73 |
74 | \item{dashboard_fill}{Dashboard background fill.}
75 |
76 | \item{dashboard_linewidth}{Dashboard background line width.}
77 |
78 | \item{dashboard_linetype}{Dashboard background line type.}
79 |
80 | \item{clip_dashboard}{Whether the dashboard circle should clip to the legend boundary.}
81 |
82 | \item{close_dashboard}{Whether the dashboard should be closed where it meets the legend boundary.}
83 |
84 | \item{frame_color}{Color of the frame drawn around the arcs.}
85 |
86 | \item{frame_linewidth}{Width of the frame drawn around the arcs.}
87 |
88 | \item{frame_linetype}{Line type of the frame drawn around the arcs.}
89 |
90 | \item{aspect.ratio}{Aspect ratio for the legend.}
91 |
92 | \item{show.limits}{Logical. Should the limits of the scale be shown with
93 | labels and ticks. Default is \code{NULL} meaning it will take the value from the
94 | scale. This argument is ignored if \code{labels} is given as a vector of
95 | values. If one or both of the limits is also given in \code{breaks} it will be
96 | shown irrespective of the value of \code{show.limits}.}
97 |
98 | \item{debug}{If \code{TRUE}, axes and origin for <\code{\link{legend-coords}}> are drawn over the legend for debugging.}
99 |
100 | \item{reverse}{logical. If \code{TRUE} the colourbar is reversed. By default,
101 | the highest value is on the top and the lowest value is on the bottom}
102 |
103 | \item{available_aes}{A vector of character strings listing the aesthetics
104 | for which a colourbar can be drawn.}
105 |
106 | \item{...}{Ignored.}
107 | }
108 | \value{
109 | A guide object of class 'colormeter'
110 | }
111 | \description{
112 | A color legend in the style of a dashboard meter
113 | }
114 | \examples{
115 | library(ggplot2)
116 | # A standard plot
117 | p <- ggplot(mtcars, aes(drat, hp)) +
118 | geom_point(aes(color = mpg))
119 | # Colormeter guide for color scale
120 | p +
121 | scale_color_viridis_c(
122 | option = "inferno",
123 | breaks = scales::breaks_pretty(10),
124 | guide = guide_colormeter()
125 | )
126 |
127 | }
128 |
--------------------------------------------------------------------------------
/man/legend-coords.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/guide_colormeter.R
3 | \name{legend-coords}
4 | \alias{legend-coords}
5 | \title{Colormeter legend coordinate system}
6 | \description{
7 | Due to the peculiar nature of the colormeter legend (e.g., dynamic size and positioning
8 | of color bars/arcs depending on the number of breaks), many parts of the legend are drawn in a
9 | mini isolated coordinate space. You can inspect this coordinate space with \code{debug = TRUE}.
10 |
11 | The coordinate space defaults to the x-y range of the legend "data", which considers the
12 | polar-transformed positioning of the color arcs/bars, the labels, and the dashboard circle.
13 | }
14 | \examples{
15 | library(ggplot2)
16 | # A standard plot
17 | p <- ggplot(mtcars, aes(drat, hp)) +
18 | geom_point(aes(color = mpg))
19 | # Colormeter guide for color scale
20 | p +
21 | scale_color_viridis_c(
22 | option = "inferno",
23 | breaks = scales::breaks_pretty(10),
24 | guide = guide_colormeter(debug = TRUE)
25 | )
26 | }
27 | \keyword{internal}
28 |
--------------------------------------------------------------------------------