Remove a layer from a ggplot2 chart
ggplot2, r
Solution
For ggplot2 version 2.2.1, I had to modify the proposed `remove_geom` function like this:
remove_geom <- function(ggplot2_object, geom_type) {
# Delete layers that match the requested type.
layers <- lapply(ggplot2_object$layers, function(x) {
if (class(x$geom)[1] == geom_type) {
NULL
} else {
x
}
})
# Delete the unwanted layers.
layers <- layers[!sapply(layers, is.null)]
ggplot2_object$layers <- layers
ggplot2_object
}
Here's an example of how to use it:
library(ggplot2)
set.seed(3000)
d <- data.frame(
x = runif(10),
y = runif(10),
label = sprintf("label%s", 1:10)
)
p <- ggplot(d, aes(x, y, label = label)) + geom_point() + geom_text()
Let's show the original plot:
p
Now let's remove the labels and show the plot again:
p <- remove_geom(p, "GeomText")
p
Problem
I'd like to remove a `layer` (in this case the results of `geom_ribbon`) from a ggplot2 created grid object. Is there a way I can remove it once it's already part of the object? ``` library(ggplot2) dat <- data.frame(x=1:3, y=1:3, ymin=0:2, ymax=2:4) p <- ggplot(dat, aes(x=x, y=y)) + geom_ribbon(aes(ymin=ymin, ymax=ymax), alpha=0.3) + geom_line() # This has the geom_ribbon p # This overlays another ribbon on top p + geom_ribbon(aes(ymin=ymin, ymax=ymax, fill=NA)) ``` I'd like this functionality to allow me to build more complicated plots on top of less complicated ones. I am using functions that return a grid object and then printing out the final plot once it is fully assembled. The base plot has a single line with a corresponding error bar (`geom_ribbon`) surrounding it. The more complicated plot will have several lines and the multiple overlapping `geom_ribbon` objects are distracting. I'd like to remove them from the plots with multiple lines. Additionally, I'll be able to quickly create alternative versions using facets or other ggplot2 functionality. Edit: Accepting @mnel's answer as it works. Now I need to determine how to dynamically access the `geom_ribbon` layer, which is captured in the SO question here. Edit 2: For completeness, this is the function I created to solve this problem: ``` remove_geom <- function(ggplot2_object, geom_type) { layers <- lapply(ggplot2_object$layers, function(x) if(x$geom$objname == geom_type) NULL else x) layers <- layers[!sapply(layers, is.null)] ggplot2_object$layers <- layers ggplot2_object } ``` Edit 3: See the accepted answer below for the latest versions of ggplot (>=2.x.y)