Skip to content

Commit f7246d4

Browse files
authored
Text size switch (#5260)
* Add `size_unit` parameter * Write test * Add NEWS bullet * snake_case to dot.case * More text units * Add test for error message
1 parent 4ef0284 commit f7246d4

File tree

5 files changed

+57
-4
lines changed

5 files changed

+57
-4
lines changed

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# ggplot2 (development version)
22

3+
* `geom_text()` and `geom_label()` gained a `size.unit` parameter that set the
4+
text size to millimetres, points, centimetres, inches or picas
5+
(@teunbrand, #3799).
6+
37
* The guide system, as the last remaining chunk of ggplot2, has been rewritten
48
in ggproto. The axes and legends now inherit from a <Guide> class, which makes
59
them extensible in the same manner as geoms, stats, facets and coords

R/geom-label.R

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ geom_label <- function(mapping = NULL, data = NULL,
1212
label.padding = unit(0.25, "lines"),
1313
label.r = unit(0.15, "lines"),
1414
label.size = 0.25,
15+
size.unit = "mm",
1516
na.rm = FALSE,
1617
show.legend = NA,
1718
inherit.aes = TRUE) {
@@ -39,6 +40,7 @@ geom_label <- function(mapping = NULL, data = NULL,
3940
label.padding = label.padding,
4041
label.r = label.r,
4142
label.size = label.size,
43+
size.unit = size.unit,
4244
na.rm = na.rm,
4345
...
4446
)
@@ -63,7 +65,8 @@ GeomLabel <- ggproto("GeomLabel", Geom,
6365
na.rm = FALSE,
6466
label.padding = unit(0.25, "lines"),
6567
label.r = unit(0.15, "lines"),
66-
label.size = 0.25) {
68+
label.size = 0.25,
69+
size.unit = "mm") {
6770
lab <- data$label
6871
if (parse) {
6972
lab <- parse_safe(as.character(lab))
@@ -80,6 +83,8 @@ GeomLabel <- ggproto("GeomLabel", Geom,
8083
label.padding <- rep(label.padding, length.out = 4)
8184
}
8285

86+
size.unit <- resolve_text_unit(size.unit)
87+
8388
grobs <- lapply(1:nrow(data), function(i) {
8489
row <- data[i, , drop = FALSE]
8590
labelGrob(lab[i],
@@ -91,7 +96,7 @@ GeomLabel <- ggproto("GeomLabel", Geom,
9196
angle = row$angle,
9297
text.gp = gpar(
9398
col = row$colour,
94-
fontsize = row$size * .pt,
99+
fontsize = row$size * size.unit,
95100
fontfamily = row$family,
96101
fontface = row$fontface,
97102
lineheight = row$lineheight

R/geom-text.R

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@
5252
#' the order of the data. Therefore data should be arranged by the label
5353
#' column before calling `geom_text()`. Note that this argument is not
5454
#' supported by `geom_label()`.
55+
#' @param size.unit How the `size` aesthetic is interpreted: as millimetres
56+
#' (`"mm"`, default), points (`"pt"`), centimetres (`"cm"`), inches (`"in"`),
57+
#' or picas (`"pc"`).
5558
#' @export
5659
#' @examples
5760
#' p <- ggplot(mtcars, aes(wt, mpg, label = rownames(mtcars)))
@@ -159,6 +162,7 @@ geom_text <- function(mapping = NULL, data = NULL,
159162
nudge_x = 0,
160163
nudge_y = 0,
161164
check_overlap = FALSE,
165+
size.unit = "mm",
162166
na.rm = FALSE,
163167
show.legend = NA,
164168
inherit.aes = TRUE)
@@ -185,6 +189,7 @@ geom_text <- function(mapping = NULL, data = NULL,
185189
params = list2(
186190
parse = parse,
187191
check_overlap = check_overlap,
192+
size.unit = size.unit,
188193
na.rm = na.rm,
189194
...
190195
)
@@ -206,7 +211,8 @@ GeomText <- ggproto("GeomText", Geom,
206211
),
207212

208213
draw_panel = function(data, panel_params, coord, parse = FALSE,
209-
na.rm = FALSE, check_overlap = FALSE) {
214+
na.rm = FALSE, check_overlap = FALSE,
215+
size.unit = "mm") {
210216
lab <- data$label
211217
if (parse) {
212218
lab <- parse_safe(as.character(lab))
@@ -221,14 +227,16 @@ GeomText <- ggproto("GeomText", Geom,
221227
data$hjust <- compute_just(data$hjust, data$x, data$y, data$angle)
222228
}
223229

230+
size.unit <- resolve_text_unit(size.unit)
231+
224232
textGrob(
225233
lab,
226234
data$x, data$y, default.units = "native",
227235
hjust = data$hjust, vjust = data$vjust,
228236
rot = data$angle,
229237
gp = gpar(
230238
col = alpha(data$colour, data$alpha),
231-
fontsize = data$size * .pt,
239+
fontsize = data$size * size.unit,
232240
fontfamily = data$family,
233241
fontface = data$fontface,
234242
lineheight = data$lineheight
@@ -276,3 +284,15 @@ just_dir <- function(x, tol = 0.001) {
276284
out[x > 0.5 + tol] <- 3L
277285
out
278286
}
287+
288+
resolve_text_unit <- function(unit) {
289+
unit <- arg_match0(unit, c("mm", "pt", "cm", "in", "pc"))
290+
switch(
291+
unit,
292+
"mm" = .pt,
293+
"cm" = .pt * 10,
294+
"in" = 72.27,
295+
"pc" = 12,
296+
1
297+
)
298+
}

man/geom_text.Rd

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-geom-text.R

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,24 @@ test_that("geom_text() drops missing angles", {
1818
)
1919
})
2020

21+
test_that("geom_text() accepts mm and pt size units", {
22+
p <- ggplot(data_frame0(x = 1, y = 1, label = "A"), aes(x, y, label = label))
23+
24+
grob <- layer_grob(p + geom_text(size = 10, size.unit = "mm"))[[1]]
25+
expect_equal(grob$gp$fontsize, 10 * .pt)
26+
27+
grob <- layer_grob(p + geom_text(size = 10, size.unit = "pt"))[[1]]
28+
expect_equal(grob$gp$fontsize, 10)
29+
})
30+
31+
test_that("geom_text() rejects exotic units", {
32+
p <- ggplot(data_frame0(x = 1, y = 1, label = "A"), aes(x, y, label = label))
33+
expect_error(
34+
ggplotGrob(p + geom_text(size = 10, size.unit = "npc")),
35+
"must be one of"
36+
)
37+
})
38+
2139
# compute_just ------------------------------------------------------------
2240

2341
test_that("vertical and horizontal positions are equivalent", {

0 commit comments

Comments
 (0)