I am trying to understand how I can make changes to the internals of a ggplot2 chart. I started reading the few ressources I could find about ggplot_built
and ggplot_gtable
, but I could not answer the question below.
Given a plot g
with 2 geom
.
g <- ggplot(iris, aes(Petal.Length, Petal.Width)) + geom_point() + geom_text(aes(label=Sepal.Width)) g
Is there a way to dive into the g
object and remove one/multiple geoms?
Can I get, starting from g
, a plot with no geoms?
Or with just the geom_text
removed?
I just noticed that removing geoms can have an impact on the layout of the other geoms. Probably great as a default and the intended behaviour for most use cases, but I actually need the exact same chart "layout" (axis and positions of remaining geoms).
Example, before removing one geom:
library(dplyr) library(ggplot2) count(mpg, class) %>% mutate(pct=n/sum(n)) %>% ggplot(aes(class, pct)) + geom_col(fill="blue") + geom_line(group=1) + geom_point(size=4)
after removing one geom (note that the y axis doesn't start at 0 anymore, I guess the default behaviour for line/point without bars):
library(dplyr) library(ggplot2) count(mpg, class) %>% mutate(pct=n/sum(n)) %>% ggplot(aes(class, pct)) + geom_col(fill="blue") + geom_line(group=1) + geom_point(size=4) -> p p$layers[[1]] <- NULL p
Any ways to force ggplot to keep the exact same layout?
%>% 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.
You may notice that we sometimes reference 'ggplot2' and sometimes 'ggplot'. To clarify, 'ggplot2' is the name of the most recent version of the package. However, any time we call the function itself, it's just called 'ggplot'.
geom_point.Rd. The point geom is used to create scatterplots. The scatterplot is most useful for displaying the relationship between two continuous variables.
Geoms. A layer combines data, aesthetic mapping, a geom (geometric object), a stat (statistical transformation), and a position adjustment. Typically, you will create layers using a geom_ function, overriding the default position and stat if needed.
You can access / manipulate g
's elements the way you would do with other R
object.
g$layers #[[1]] #geom_point: na.rm = FALSE #stat_identity: na.rm = FALSE #position_identity #[[2]] #mapping: label = Sepal.Width #geom_text: parse = FALSE, check_overlap = FALSE, na.rm = FALSE #stat_identity: na.rm = FALSE #position_identity
Remove geom_text
:
g$layers[[2]] <- NULL
Remove all layers
g$layers <- NULL g
The gginnards
package offers some functions to manipulate ggplot
layers, see the vignette User Guide: 4 Manipulation of plot layers for details.
edit
Following the question of How can I extract plot axes' ranges for a ggplot2 object? I came to a solution that uses ggplot_build
and ggplot_gtable
. The idea is simply to copy the layout parameters taken from ggplot_built(p)
to the new plot, for which we deleted a layer.
# create a copy of p p_new <- p # delete the first layer p_new$layers[[1]] <- NULL p_new_build <- ggplot_build(p_new) # this is the important line p_new_build$layout$panel_params <- ggplot_build(p)$layout$panel_params library(gridExtra) grid.arrange(p, ggplot_gtable(p_new_build), ncol = 2)
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