-
Notifications
You must be signed in to change notification settings - Fork 2.1k
view facet label text #4979
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
You can intercept the text rendering at the element drawing stage. You can wrap library(ggplot2)
library(rlang)
# Subclass element_text
element_text_refit <- function(...) {
elem <- element_text(...)
class(elem) <- c("element_text_refit", class(elem))
elem
}
# S3 method for `element_grob()`
element_grob.element_text_refit <- function(
element, label = "", size = NULL, ...
) {
n_lines <- stringr::str_count(label, pattern = "\n") + 1
size <- rep_len(size %||% element$size, length(n_lines)) / n_lines
class(element) <- setdiff(class(element), "element_text_refit")
element_grob(element, label = label, size = size, ...)
}
# Example data with various number of lines on the strip
df <- iris
levels(df$Species) <- c("Setosa", "Iris\nversicolor", "The plant\nIris\nvirginica")
ggplot(df, aes(Sepal.Width, Sepal.Length)) +
geom_point() +
facet_wrap(~ Species) +
theme(
strip.text = element_text_refit(size = 36)
) Created on 2022-09-06 by the reprex package (v2.0.1) |
@teunbrand Very nice, thanks! I was able to implement your solution and it does indeed avoid reliance on non-exported functions. I have the remaining problem, though, that element-wise rescaling does not let me accommodate the case where one margin has multiple facets, such as the column facets in the example below (trivial here, but a real problem for certain facet_wrap cases). Viewing the labels in totality (as seen in library(ggplot2)
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
facet_grid(
cyl ~ am + gear,
labeller = label_both
) +
theme_bw() Created on 2022-09-06 with reprex v2.0.2 |
So here is an unsupported method how you could wrangle the facet text from a build ggplot2 object: library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.2.2
p <- ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
facet_grid(
cyl ~ am + gear,
labeller = label_both
) +
theme_bw()
b <- ggplot_build(p)
layout <- b$layout$layout
col_vars <- unique(layout[names(b$layout$facet_params$cols)])
row_vars <- unique(layout[names(b$layout$facet_params$rows)])
b$layout$facet_params$labeller(col_vars)
#> [[1]]
#> [1] "am: 0" "am: 0" "am: 1" "am: 1"
#>
#> [[2]]
#> [1] "gear: 3" "gear: 4" "gear: 4" "gear: 5"
b$layout$facet_params$labeller(row_vars)
#> [[1]]
#> [1] "cyl: 4" "cyl: 6" "cyl: 8" Created on 2022-12-14 by the reprex package (v2.0.1) A question that deserves some considering is whether ggplot2 should provide programmatic access to strip labels. The use case presented here is one thing, but another consideration is that it might make it easier for packages like BrailleR to describe a plot. |
labeller()
and related functionality give huge flexibility for controlling strips, thanks! But I've been asked to write an extension that programmatically modifies strip text font size in the event that a strip has many lines. At present it is hard to examine strip text in advance. Apparentlylabeller()
is called once duringbuild_strip()
and the result is immediately rendered as grobs. Stealing ideas from https://github.com/yjunechoe/ggtrace I can doinvisible(ggplotGrob(x))
while runningtrace()
onbuild_strip()
, but the latter is not exported so there is going to be a package check warning that will probably keep the solution from ever posting on CRAN.I completely understand if you do not want to export
build_strip()
. Is there an alternative way, existing or otherwise (feature request), to view the facet label text of a ggplot object before rendering?The text was updated successfully, but these errors were encountered: