R: Extract scale name from ggplot object

I was wondering how to extract the scale name (i.e. the legend name) from an object in the ggplot

most general way. In general, what I mean is that it fetches the same thing no matter how you changed the name of the scale using name

in a function scale

or using labs

.

For example:

library("ggplot2")
set.seed(3489243)
rho <- round(rnorm(25, 0, 5))
profit <- 0.5 + 0.3 * rho + rnorm(25, 0, 1)
BetaAdjusted <- factor(c(rep(TRUE, 15), rep(FALSE, 10)))
returns.both <- data.frame(rho, profit, BetaAdjusted)
p1 <- ggplot(aes(x=rho, y=profit, shape = BetaAdjusted),
        data=returns.both) + 
geom_point() + scale_shape_discrete(name = "Is Beta Adjusted?")
p2 <- ggplot(aes(x=rho, y=profit, shape = BetaAdjusted),
        data=returns.both) + 
geom_point() + labs(shape = "Is Beta Adjusted?")

      

I want to extract text Is Beta Adjusted

from p1

and p2

using the same code. Is it possible? Using labs(p2)

gives me the text below the list of labels, but using labs(p1)

gives me the text in the list of weights. I don't want to look at two places for the same text depending on user input. In the end, p1

it p2

creates the same schedule.

+3


source to share


3 answers


This solution is heavily dependent on the scale implementation, so use with caution (as ggplot2 may change this at some point).



p <- qplot(vs, wt, shape = factor(gear), color = factor(am), data = mtcars)

guide_names <- function(p, aes = c("shape", "colour", "size")) {
  sc <- as.list(p$scales)$scales
  nms <- lapply(sc, "[[", "name")
  if (length(nms) > 0) names(nms) <- lapply(sc, "[[", "aesthetics")
  modifyList(p$labels[names(p$labels) %in% aes], nms)
}

guide_names(p)
# $colour
# [1] "factor(am)"
# 
# $shape
# [1] "factor(gear)"

guide_names(p + labs(shape = "A") + labs(color = "B"))
# $colour
# [1] "B"
# 
# $shape
# [1] "A"

guide_names(p + scale_shape_discrete(name = "S") + scale_color_discrete(name = "C"))
# $colour
# [1] "C"
# 
# $shape
# [1] "S"

# if both are specified, scale_* is prefered
guide_names(p + labs(shape = "A") + scale_shape_discrete(name = "S"))
# $shape
# [1] "S"
# 
# $colour
# [1] "factor(am)"

      

+3


source


Is this what you mean?

 set.seed(3489243)
 rho <- round(rnorm(25, 0, 5))
 profit <- 0.5 + 0.3 * rho + rnorm(25, 0, 1)
 BetaAdjusted <- factor(c(rep(TRUE, 15), rep(FALSE, 10)))
 returns.both <- data.frame(rho, profit, BetaAdjusted)
 p1 <- ggplot(aes(x=rho, y=profit, shape = BetaAdjusted),
           data=returns.both) + 
  geom_point() + scale_shape_discrete(name = "Is Beta Adjusted?")
 p2 <- ggplot(aes(x=rho, y=profit, shape = BetaAdjusted),
           data=returns.both) + 
geom_point() + labs(shape = "Is Beta Adjusted?")


lapply(list(p1,p2),function(x)x$labels$shape)

      



[[1]] [1] "BetaAdjusted"

[[2]] [1] "Beta corrected?"

+1


source


It's easier to extract information from p2:

> p2$labels$shape
#[1] "Is Beta Adjusted?"

      

Whereas in p1 the text is "Beta corrected?" "hidden" in p1 $ scales:

> p1$scales
#Reference class object of class "Scales"
#Field "scales":
#[[1]]
#discrete_scale(aesthetics = "shape", scale_name = "shape_d", 
#    palette = shape_pal(solid), name = "Is Beta Adjusted?")

      

Alternatively, if the exact text is "Beta corrected?" not required, you can use the same syntax for both p1 and p2:

> p1$labels$shape
#[1] "BetaAdjusted"
> p2$labels$shape
#[1] "Is Beta Adjusted?"

      

0


source







All Articles