├── .Rbuildignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── R ├── legends.R └── theme_cropped_map.R ├── README.Rmd ├── README.md ├── inst └── examples │ └── coffee.R ├── man ├── figures │ └── README-example-1.png ├── inset_legend_custom.Rd ├── inset_themes.Rd └── theme_cropped_map.Rd └── tests ├── testthat.R └── testthat ├── _snaps └── inset-legend │ └── coffee.png └── test-inset-legend.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^LICENSE\.md$ 2 | ^README\.Rmd$ 3 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: inlegend 2 | Title: Inset legend themes for ggplot2 maps 3 | Version: 0.1.0 4 | Authors@R: 5 | person(given = "Miles", 6 | family = "McBain", 7 | role = c("aut", "cre"), 8 | email = "miles.mcbain@gmail.com", 9 | comment = c(ORCID = "0000-0003-2865-2548")) 10 | Description: Provides themes for making ggplot2 maps with inset legends and without whitespace around the margins. 11 | License: MIT + file LICENSE 12 | Encoding: UTF-8 13 | LazyData: true 14 | Roxygen: list(markdown = TRUE) 15 | RoxygenNote: 7.1.1 16 | Suggests: 17 | testthat (>= 3.0.0), 18 | spData, 19 | dplyr, 20 | ggspatial, 21 | sf, 22 | diffviewer 23 | Imports: 24 | ggplot2, 25 | magrittr, 26 | ggfx 27 | Config/testthat/edition: 3 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2020 2 | COPYRIGHT HOLDER: Miles McBain 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2020 Miles McBain 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 | export(inset_legend_custom) 4 | export(inset_legend_dark) 5 | export(inset_legend_light) 6 | export(theme_cropped_map) 7 | importFrom(magrittr,"%>%") 8 | -------------------------------------------------------------------------------- /R/legends.R: -------------------------------------------------------------------------------- 1 | ##' Inset legend themes for ggplot2 maps 2 | ##' 3 | ##' These themes move and restyle the ggplot2 legend to be more in line with mapping nroms. 4 | ##' `ggplot2` are inset in the desired map corner. The legends are restyled to appear simpler and draw less attention when overlaid on maps. 5 | ##' 6 | ##' Convenience parameters are provided to tweak the size of legend text. The text style can be fully customised with the `ggplot2` theme engine. See examples. 7 | ##' 8 | ##' @name inset_themes 9 | ##' @title inset map legend themes 10 | ##' @param location the location to inset legends. One of "top-left", "top-right", "bottom-left", "bottom-right" 11 | ##' @param title_text_size a convenience parameter for setting the size of the legend title text. For high resolution maps the defaults tend to be too small. 12 | ##' @param text_size a convenience parameter for setting the size the legend key elements text. For high resolution maps the defaults tend to be too small. 13 | ##' @return `inlegend_dark` returns dark legend theme based on kepler.gl as an object of classes `theme` and `gg`. 14 | ##' @author Miles McBain 15 | ##' @export 16 | ##' @example inst/examples/coffee.R 17 | inset_legend_dark <- function(location = "top-right", 18 | title_text_size = NULL, 19 | text_size = NULL) { 20 | inset_legend_custom( 21 | inlegend.location = location, 22 | legend.background = ggfx::with_shadow( 23 | ggplot2::element_rect( 24 | colour = "#242730", 25 | fill = "#242730", 26 | size = 0.6 27 | ), 28 | x_offset = -1, 29 | y_offset = 1, 30 | sigma = 4 31 | ), 32 | legend.text = ggplot2::element_text( 33 | colour = "#a0a7b4", 34 | size = text_size 35 | ), 36 | legend.title = ggplot2::element_text( 37 | colour = "#f0f0f0", 38 | margin = ggplot2::margin(0, 0, 5, 0), 39 | size = title_text_size 40 | ), 41 | legend.key = ggplot2::element_rect( 42 | fill = "#242730", 43 | colour = NA 44 | ) 45 | ) 46 | } 47 | 48 | ##' @rdname inset_themes 49 | ##' @return `inlegend_light` returns a light white legend theme as an object of classes `theme` and `gg`. 50 | ##' @export 51 | inset_legend_light <- function(location = "top-right", 52 | title_text_size = NULL, 53 | text_size = NULL) { 54 | inset_legend_custom( 55 | inlegend.location = location, 56 | legend.background = ggfx::with_shadow( 57 | x_offset = -1, 58 | y_offset = 1, 59 | sigma = 2, 60 | ggplot2::element_rect( 61 | colour = "#ffffff", 62 | fill = "#ffffff", 63 | size = 0.6 64 | ) 65 | ), 66 | legend.text = ggplot2::element_text( 67 | colour = "#767d7d", 68 | size = text_size 69 | ), 70 | legend.title = ggplot2::element_text( 71 | colour = "#2b2d2d", 72 | margin = ggplot2::margin(0, 0, 5, 0), 73 | size = title_text_size 74 | ), 75 | legend.key = ggplot2::element_rect( 76 | fill = "#ffffff", 77 | colour = NA 78 | ) 79 | ) 80 | } 81 | 82 | globalVariables(".inlegend_positions", "inlegend") 83 | .inlegend_positions <- new.env() 84 | .inlegend_positions$`top-right` <- 85 | list( 86 | legend.box.margin = ggplot2::margin(r = 5, t = 5), 87 | legend.justification = c(1, 1), 88 | legend.position = c(1.0, 1.0) 89 | ) 90 | .inlegend_positions$`top-left` <- 91 | list( 92 | legend.box.margin = ggplot2::margin(l = 5, t = 5), 93 | legend.justification = c(0, 1), 94 | legend.position = c(0, 1.0) 95 | ) 96 | .inlegend_positions$`bottom-right` <- 97 | list( 98 | legend.box.margin = ggplot2::margin(r = 5, b = 5), 99 | legend.justification = c(1, 0), 100 | legend.position = c(1.0, 0) 101 | ) 102 | .inlegend_positions$`bottom-left` <- 103 | list( 104 | legend.box.margin = ggplot2::margin(l = 5, b = 5), 105 | legend.justification = c(0, 0), 106 | legend.position = c(0, 0) 107 | ) 108 | 109 | ##' Build a custom inset map legend 110 | ##' 111 | ##' This function has defaults that will position an inset map ggplot2 legend. It is the legend constructor used by `inset_legend_light` and `inset_legend_dark`. 112 | ##' 113 | ##' @title build custom inset map legend. 114 | ##' @param inlegend.location the location of the legend. One of "top-right", 115 | ##' "top-left", "bottom-left", "bottom-right" 116 | ##' @param legend.background the background rectangle the legend is drawn on. A 117 | ##' `ggplot::element_rect`, where the following parameter mappings map to what 118 | ##' you see: 119 | ##' 120 | ##' * `fill` - background colour 121 | ##' * `colour` - border colour 122 | ##' * `size` - border thickness. 123 | ##' @param legend.text text for labels, eg factor names, or scale tick labels. A 124 | ##' `ggplot2::element_text`, where the following parameters map to what you see: 125 | ##' * `colour` - the text colour 126 | ##' * `size` - the text size 127 | ##' * `face` - the text face (e.g. bold) 128 | ##' * `family` - the text font 129 | ##' * `margin` - `ggplot2::margin` that sets the spacing around the legend element text 130 | ##' @param legend.title text for legend title. A ggplot2::element_text, where 131 | ##' the following parameters map to what you see: 132 | ##' 133 | ##' * `colour` - the text colour 134 | ##' * `size` - the text size 135 | ##' * `face` - the text face (e.g. bold) 136 | ##' * `family` - the text font 137 | ##' * `margin` - `ggplot2::margin` that sets the spacing around the title text 138 | ##' and legend.background edge. 139 | ##' @param legend.key the background rectangles that the individual legend key elements are drawn on. A `ggplot2::element_rect` where the following parameters map to what you see: 140 | ##' 141 | ##' * `fill` - the rectangle 142 | ##' @param legend.margin The spacing between the edge of the legend.background and legend elements (text, keys etc.). A `ggplot2::margin object`. Additional padding on bottom seems to be required for things to look right. 143 | ##' @param ... arguments passed to `ggplot2::theme`. 144 | ##' @return a object of classes 'theme' and 'gg' 145 | ##' @author Miles McBain 146 | ##' @importFrom magrittr %>% 147 | ##' @export 148 | inset_legend_custom <- function(inlegend.location = c( 149 | "top-right", 150 | "top-left", 151 | "bottom-left", 152 | "bottom-right" 153 | ), 154 | legend.background, 155 | legend.text, 156 | legend.title, 157 | legend.key, 158 | legend.margin = ggplot2::margin(8, 8, 10, 8), 159 | ...) { 160 | legend_location <- match.arg(inlegend.location) 161 | location_params <- get(legend_location, envir = .inlegend_positions) 162 | 163 | ggplot2::theme( 164 | legend.background = legend.background, 165 | legend.text = legend.text, 166 | legend.title = legend.title, 167 | legend.key = legend.key, 168 | legend.justification = location_params$legend.justification, 169 | legend.position = location_params$legend.position, 170 | legend.margin = legend.margin, 171 | legend.box.margin = location_params$legend.box.margin, 172 | ... 173 | ) 174 | } -------------------------------------------------------------------------------- /R/theme_cropped_map.R: -------------------------------------------------------------------------------- 1 | ##' Remove plot axis and whitespace margins 2 | ##' 3 | ##' In a map where the legend is inset it may be convenient to have the plot 4 | ##' tightly cropped around the map extent. This theme give you a such a plot. 5 | ##' Beware that there is no space for titles, so that kind of information must 6 | ##' be conveyed in section headings or captions. 7 | ##' 8 | ##' When saving map using this theme as an image, you will see whitespace in the 9 | ##' output unless the aspect ratio of your output image matches the aspect ratio 10 | ##' of the map (plot area) exactly. 11 | ##' 12 | ##' @title theme_cropped_map 13 | ##' @param ... arguments passed to `ggplot2::theme()` 14 | ##' @return 15 | ##' @author Miles McBain 16 | ##' @export 17 | theme_cropped_map <- function(...) { 18 | list( 19 | ggplot2::theme( 20 | axis.text = ggplot2::element_blank(), 21 | axis.ticks = ggplot2::element_blank(), 22 | axis.line = ggplot2::element_blank(), 23 | axis.title = ggplot2::element_blank(), 24 | panel.border = ggplot2::element_blank(), 25 | plot.margin = ggplot2::unit( 26 | x = c(0, 0, 0, 0), 27 | units = "mm" 28 | ), 29 | axis.ticks.length = ggplot2::unit( 30 | x = 0, 31 | units = "mm" 32 | ), 33 | ... 34 | ), 35 | ggplot2::scale_y_continuous(expand = c(0, 0)), 36 | ggplot2::scale_x_continuous(expand = c(0, 0)) 37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /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 | ) 14 | ``` 15 | 16 | # inlegend 17 | 18 | 19 | 20 | 21 | `ggplot2` theming helpers for making static maps with inset legends: 22 | 23 | * `inset_legend_dark()` 24 | * `inset_legend_light()` 25 | * `theme_cropped_map()` 26 | 27 | ## Installation 28 | 29 | From [GitHub](https://github.com/) with: 30 | 31 | ``` r 32 | # install.packages("devtools") 33 | devtools::install_github("milesmcbain/inlegend") 34 | ``` 35 | 36 | ## Example 37 | 38 | ```{r example, fig.cap = "Bike share capacity, London. Via {spData}", dpi = 200, fig.width = 8} 39 | library(spData) 40 | library(snapbox) ##remotes::install_github("anthonynorth/snapbox") 41 | library(ggplot2) 42 | library(ggspatial) 43 | library(sf) 44 | library(inlegend) 45 | library(stylebox) 46 | ggplot() + 47 | layer_mapbox( 48 | spData::cycle_hire_osm, 49 | stylebox::mapbox_gallery_frank() 50 | ) + 51 | layer_spatial(spData::cycle_hire_osm, 52 | aes(colour = capacity), 53 | alpha = 0.75) + 54 | scale_colour_viridis_b() + 55 | inset_legend_light("top-right") + 56 | theme_cropped_map() 57 | ``` 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # inlegend 5 | 6 | 7 | 8 | 9 | 10 | `ggplot2` theming helpers for making static maps with inset legends: 11 | 12 | - `inset_legend_dark()` 13 | - `inset_legend_light()` 14 | - `theme_cropped_map()` 15 | 16 | ## Installation 17 | 18 | From [GitHub](https://github.com/) with: 19 | 20 | ``` r 21 | # install.packages("devtools") 22 | devtools::install_github("milesmcbain/inlegend") 23 | ``` 24 | 25 | ## Example 26 | 27 | ``` r 28 | library(spData) 29 | #> To access larger datasets in this package, install the spDataLarge 30 | #> package with: `install.packages('spDataLarge', 31 | #> repos='https://nowosad.github.io/drat/', type='source')` 32 | library(snapbox) ##remotes::install_github("anthonynorth/snapbox") 33 | library(ggplot2) 34 | library(ggspatial) 35 | library(sf) 36 | #> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1 37 | library(inlegend) 38 | library(stylebox) 39 | ggplot() + 40 | layer_mapbox( 41 | spData::cycle_hire_osm, 42 | stylebox::mapbox_gallery_frank() 43 | ) + 44 | layer_spatial(spData::cycle_hire_osm, 45 | aes(colour = capacity), 46 | alpha = 0.75) + 47 | scale_colour_viridis_b() + 48 | inset_legend_light("top-right") + 49 | theme_cropped_map() 50 | #> Warning in showSRID(uprojargs, format = "PROJ", multiline = "NO", prefer_proj 51 | #> = prefer_proj): Discarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 52 | #> +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null 53 | #> +wktext +no_defs +type=crs 54 | #> Warning in showSRID(uprojargs, format = "PROJ", multiline = "NO", prefer_proj = 55 | #> prefer_proj): Discarded datum World Geodetic System 1984 in CRS definition 56 | #> Warning in showSRID(uprojargs, format = "PROJ", multiline = "NO", prefer_proj 57 | #> = prefer_proj): Discarded ellps WGS 84 in CRS definition: +proj=merc +a=6378137 58 | #> +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null 59 | #> +wktext +no_defs +type=crs 60 | #> Warning in showSRID(uprojargs, format = "PROJ", multiline = "NO", prefer_proj = 61 | #> prefer_proj): Discarded datum World Geodetic System 1984 in CRS definition 62 | ``` 63 | 64 |
69 | 70 | Bike share capacity, London. Via {spData} 71 | 72 |
73 | 74 |