Is there a way to search the entire output from ggplot_build()
(or any other function), almost like searching the complete content of every subdirectory of a folder?
The details:
I was looking for a solution to Retrieve values for axis labels in ggplot2_3.0.0, and one of the early answers revealed that, depending on the ggplot2
version, the correct answer most likely would contain the parts $layout
and / or $x.labels
in the output from ggplot_build(g)
. So I started checking the ggplot_build()
output each step of the way. One of the steps looks like the output below.
Snippet 1:
ggplot_build(g)$layout
Output 1:
<ggproto object: Class Layout, gg>
coord: <ggproto object: Class CoordCartesian, Coord, gg>
aspect: function
clip: on
[...]
map_position: function
panel_params: list
panel_scales_x: list
panel_scales_y: list
render: function
[...]
ylabel: function
super: <ggproto object: Class Layout, gg>
>
And deep down there, under panel params
, x.labels
can be found along with lots of useful information like this:
Snippet 2:
ggplot_build(g)$layout$panel_params
Output 2:
[[1]]
[[1]]$`x.range`
[1] 7.7 36.3
[[1]]$x.labels
[1] "10" "15" "20" "25" "30" "35"
[[1]]$x.major
[1] 0.08041958 0.25524476 0.43006993 0.60489510 0.77972028 0.95454545
And it can be referenced directly like this:
Snippet 3:
ggplot_build(g)$layout$panel_params[[1]]$x.labels
Output 3:
[1] "10" "15" "20" "25" "30" "35"
My attempt for a more elegant approach:
I was certain I could do this with capture.output()
like you can with str()
as described here, but as far as I can tell, you won't find x.labels
there either. I'm not going to flood the question with that output since it's about 300 lines long.
Thank you for any suggestions!
%>% is a pipe operator reexported from the magrittr package. Start by reading the vignette. Adding things to a ggplot changes the object that gets created. The print method of ggplot draws an appropriate plot depending upon the contents of the variable.
Integrating the pipe operator with ggplot2 The pipe operator can also be used to link data manipulation with consequent data visualization.
To customize the plot, the following arguments can be used: alpha, color, dotsize and fill. Learn more here: ggplot2 dot plot.
Elements that are normally added to a ggplot with operator + , such as scales, themes, aesthetics can be replaced with the %+% operator.
This function goes through a nested list structure and finds the paths through that structure that contain a given character string:
find_name <- function(obj, name) {
# get all named paths through obj
find_paths <- function(obj, path) {
if ((!is.list(obj) && is.null(names(obj))) || identical(obj, .GlobalEnv)) {
return (path)
} else {
if (is.null(names(obj))) {
return(c(path,
lapply(seq_along(obj), function(x) find_paths(obj[[x]], paste0(path, "[[", x, "]]")))
))
} else {
return(c(path,
lapply(names(obj), function(x) find_paths(obj[[x]], paste(path, x, sep = "$")))
))
}
}
}
# get all the paths through the nested structure
all_paths <- unlist(find_paths(obj, deparse(substitute(obj))))
# find the requested name
path_to_name <- grep(paste0("\\$", name, "$"), all_paths, value = TRUE)
return (path_to_name)
}
Here is an example of using this function with a ggplot_built
object:
library(ggplot2)
p <- ggplot(mtcars) + geom_point(aes(x = disp, y = mpg, col = as.factor(cyl)))
gb <- ggplot_build(p)
find_name(gb, "x.labels")
## [1] "gb$layout$panel_params[[1]]$x.labels"
You can also directly get the contents of x.labels
:
eval(parse(text = find_name(gb, "x.labels")))
## [1] "100" "200" "300" "400"
A few remarks on how this works:
find_paths()
goes through the nested structure and returns all "paths" through the structure in a form similar to "gb$layout$panel_params[[1]]$x.labels"
.FALSE
for is.list()
and environments. One has to take care of all these situations.ggplot_built
contains a reference to the global environment (gb$layout$facet_params$plot_env
), which leads to an infinite loop if it is not properly treated.find_paths()
is a nested list again, but the structure can easily be simplified with unlist()
.find_name(gb, "x")
will not return "gb$layout$panel_params[[1]]$x.labels"
.I have tested the function with the ggplot_built
object from my example and with a nested list. I cannot guarantee that it works for all situations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With