ggplot:如何更改构面标签?

wis*_*ame 210 symbols r facet ggplot2 plotmath

我使用了以下ggplot命令:

ggplot(survey, aes(x = age)) + stat_bin(aes(n = nrow(h3), y = ..count.. / n), binwidth = 10)
  + scale_y_continuous(formatter = "percent", breaks = c(0, 0.1, 0.2))
  + facet_grid(hospital ~ .)
  + theme(panel.background = theme_blank())
Run Code Online (Sandbox Code Playgroud)

生产

替代文字

我想将facet标签更改为更短的标签(如Hosp 1,Hosp 2 ......),因为它们现在太长并且看起来很狭窄(增加图形的高度不是一个选项,它需要文档中的空间太大).我查看了facet_grid帮助页面,但无法弄清楚如何.

nau*_*101 271

这是一个避免编辑数据的解决方案:

假设您的绘图由group数据框的具有级别的部分构成control, test1, test2,然后创建由这些值命名的列表:

hospital_names <- list(
  'Hospital#1'="Some Hospital",
  'Hospital#2'="Another Hospital",
  'Hospital#3'="Hospital Number 3",
  'Hospital#4'="The Other Hospital"
)
Run Code Online (Sandbox Code Playgroud)

然后创建一个'贴标机'功能,并将其推入facet_grid调用:

hospital_labeller <- function(variable,value){
  return(hospital_names[value])
}

ggplot(survey,aes(x=age)) + stat_bin(aes(n=nrow(h3),y=..count../n), binwidth=10)
 + facet_grid(hospital ~ ., labeller=hospital_labeller)
 ...
Run Code Online (Sandbox Code Playgroud)

这使用数据框的级别来索引hospital_names列表,返回列表值(正确的名称).


请注意,这仅适用于只有一个分面变量的情况.如果您有两个方面,那么您的贴标机功能需要为每个方面返回不同的名称向量.您可以使用以下内容执行此操作:

plot_labeller <- function(variable,value){
  if (variable=='facet1') {
    return(facet1_names[value])
  } else {
    return(facet2_names[value])
  }
}
Run Code Online (Sandbox Code Playgroud)

其中facet1_namesfacet2_names是由facet索引名称('Hostpital#1'等)索引的预定义名称列表.


编辑:如果您传递标签程序不知道的变量/值组合,则上述方法将失败.您可以为未知变量添加故障保护,如下所示:

plot_labeller <- function(variable,value){
  if (variable=='facet1') {
    return(facet1_names[value])
  } else if (variable=='facet2') {
    return(facet2_names[value])
  } else {
    return(as.character(value))
  }
}
Run Code Online (Sandbox Code Playgroud)

答案改编自如何使用facet和margin = TRUE更改ggplot中的strip.text标签


编辑:警告:如果您使用此方法按字符列进行构面,则可能是标签不正确.请参阅此错误报告. 修复了最新版本的ggplot2.

  • 注意:这在ggplot2 v.2中不起作用 - 贴标机功能已更改.@mbirons的回答是http://stackoverflow.com/a/34811062/162832 (15认同)
  • 很好,但不能使用facet_wrap,而@Vince解决方案也适用于facet_wrap. (9认同)
  • 由于此处使用的贴标机现已弃用,我们可以更新此内容吗? (2认同)

mbi*_*ron 193

这是另一个解决方案,它符合@ naught101给出的一个解决方案,但更简单,也没有对最新版本的ggplot2发出警告.

基本上,您首先要创建一个命名的字符向量

hospital_names <- c(
                    `Hospital#1` = "Some Hospital",
                    `Hospital#2` = "Another Hospital",
                    `Hospital#3` = "Hospital Number 3",
                    `Hospital#4` = "The Other Hospital"
                    )
Run Code Online (Sandbox Code Playgroud)

然后你将它用作贴标机,只需修改@ naught101给出的代码的最后一行即可

... + facet_grid(hospital ~ ., labeller = as_labeller(hospital_names))
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

  • 这很酷.如果在facet网格中有两个变量会发生什么?像`医院〜性别'或什么?有没有办法在两个轴上使用贴标机?我在文档中看不到任何明显的东西. (4认同)
  • 请注意,如果你从naught的答案开始,这个只适用于**c()**而不是**列表()**. (3认同)
  • @naught101 问题的答案将是 domi 的答案:/sf/answers/2644523451/ 如果没有这个添加,这对我不起作用,对于我没有包含的变量产生 NA 。 (3认同)
  • 其中一个重要的部分是它适用于面网格的两个轴! (2认同)

Vin*_*nce 114

使用以下内容更改基础因子级别名称:

# Using the Iris data
> i <- iris
> levels(i$Species)
[1] "setosa"     "versicolor" "virginica" 
> levels(i$Species) <- c("S", "Ve", "Vi")
> ggplot(i, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ .)
Run Code Online (Sandbox Code Playgroud)

  • 太棒了,效果很好; 即使我更喜欢不改变底层数据的解决方案,它解决了我的问题,所以我可以随着我的工作而移动.谢谢. (17认同)
  • @wishihadabettername:为避免更改基础数据,您可以使用:`ggplot(transform(iris,Species = c("S","Ve","Vi")[as.numeric(Species)]),aes(Petal.长度))+ stat_bin()+ facet_grid(物种〜.)` (12认同)
  • 相关...如果您希望面板标签是 bquote() 表达式(例如,`levels(x$measurements) &lt;- c(bquote(Area ~~ (cm^2)), bquote(Length ~~ (cm) )))`) 它不会出现在数学表达式中。如何将表达式显示为方面标签? (2认同)

bov*_*der 24

以下是我facet_grid(yfacet~xfacet)使用ggplot2版本2.2.1的方法:

facet_grid(
    yfacet~xfacet,
    labeller = labeller(
        yfacet = c(`0` = "an y label", `1` = "another y label"),
        xfacet = c(`10` = "an x label", `20` = "another x label")
    )
)
Run Code Online (Sandbox Code Playgroud)

请注意,这不包含对as_labeller()某些内容的调用- 这是我努力了一段时间.

这种方法的灵感来自Coerce到贴标机功能的帮助页面上的最后一个示例.


dom*_*omi 22

如果你有两个方面hospitalroom,但要重命名只有一个,你可以使用:

facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names)))
Run Code Online (Sandbox Code Playgroud)

要使用基于矢量的方法重命名两个方面(如naught101的答案),您可以:

facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names),
                                                 room = as_labeller(room_names)))
Run Code Online (Sandbox Code Playgroud)

  • 这为我提供了所有标签的 NA :( (5认同)

小智 11

在不修改基础数据的情况下进行更改的最简便方法是:

1)使用为每个默认值添加反勾号as_labeller函数创建一个对象:

hum.names <- as_labeller(c(`50` = "RH% 50", `60` = "RH% 60",`70` = "RH% 70", `80` = "RH% 80",`90` = "RH% 90", `100` = "RH% 100")) #Necesarry to put RH% into the facet labels
Run Code Online (Sandbox Code Playgroud)

2)我们添加到GGplot中:

ggplot(dataframe, aes(x=Temperature.C,y=fit))+geom_line()+ facet_wrap(~Humidity.RH., nrow=2,labeller=hum.names)
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是最优雅的方法——它很有效并且适用于 ggplot2 版本 3.0.0.9000 (4认同)
  • @DenisCousineau 在这种情况下使用 `labeller = labeller(Type = c(...), Humidity = c(...))` 其中 ... 是键值对 (3认同)
  • 另外我要注意的是,如果您只是在所有内容前面加上 `RH%` 前缀,则更可靠的解决方案是将这个答案中的步骤 1 替换为 `hum_names &lt;- as_labeller(function(x) Paste('RH%', x ))` (3认同)

Nic*_*ick 11

简单的解决方案(从这里):

p <- ggplot(mtcars, aes(disp, drat)) + geom_point()
# Example (old labels)
p + facet_wrap(~am)


to_string <- as_labeller(c(`0` = "Zero", `1` = "One"))
# Example (New labels)
p + facet_wrap(~am, labeller = to_string)
Run Code Online (Sandbox Code Playgroud)


Mat*_*fou 8

请注意,如果ggplot显示的因子少于变量实际包含的因素,则此解决方案将无法正常工作(如果您进行了子集化,可能会发生这种情况):

 library(ggplot2)
 labeli <- function(variable, value){
  names_li <- list("versicolor"="versi", "virginica"="virg")
  return(names_li[value])
 }

 dat <- subset(iris,Species!="setosa")
 ggplot(dat, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ ., labeller=labeli)
Run Code Online (Sandbox Code Playgroud)

一个简单的解决方案(除了在names_li中添加所有未使用的因子,这可能是单调乏味的)是使用droplevels()删除未使用的因子,无论是在原始数据集中还是在labbeler函数中,请参阅:

labeli2 <- function(variable, value){
  value <- droplevels(value)
  names_li <- list("versicolor"="versi", "virginica"="virg")
  return(names_li[value])
}

dat <- subset(iris,Species!="setosa")
ggplot(dat, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ ., labeller=labeli2)
Run Code Online (Sandbox Code Playgroud)


Rom*_*rik 8

这个解决方案非常接近@domi所拥有的,但旨在通过获取前4个字母和最后一个数字来缩短名称.

library(ggplot2)

# simulate some data
xy <- data.frame(hospital = rep(paste("Hospital #", 1:3, sep = ""), each = 30),
                 value = rnorm(90))

shortener <- function(string) {
  abb <- substr(string, start = 1, stop = 4) # fetch only first 4 strings
  num <- gsub("^.*(\\d{1})$", "\\1", string) # using regular expression, fetch last number
  out <- paste(abb, num) # put everything together
  out
}

ggplot(xy, aes(x = value)) +
  theme_bw() +
  geom_histogram() +
  facet_grid(hospital ~ ., labeller = labeller(hospital = shortener))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


lil*_*ets 6

无论facet_wrapfacet_grid也接受输入ifelse作为参数。因此,如果用于构面的变量是逻辑的,则解决方案非常简单:

facet_wrap(~ifelse(variable, "Label if true", "Label if false"))
Run Code Online (Sandbox Code Playgroud)

如果变量具有更多类别,则该ifelse语句需要嵌套

作为副作用,这还允许在ggplot呼叫中分面创建组。


Tun*_*ung 5

通过解析数学符号,上标,下标,括号/括号等添加其他类似于@domi的解决方案。

library(tidyverse)
theme_set(theme_bw(base_size = 18))

### create separate name vectors
# run `demo(plotmath)` for more examples of mathematical annotation in R
am_names <- c(
  `0` = "delta^{15}*N-NO[3]^-{}",
  `1` = "sqrt(x,y)"
)

# use `scriptstyle` to reduce the size of the parentheses &
# `bgroup` to make adding `)` possible 
cyl_names <- c(
  `4` = 'scriptstyle(bgroup("", a, ")"))~T~-~5*"%"',
  `6` = 'scriptstyle(bgroup("", b, ")"))~T~+~10~degree*C',
  `8` = 'scriptstyle(bgroup("", c, ")"))~T~+~30*"%"'
)

ggplot(mtcars, aes(wt, mpg)) + 
  geom_jitter() +
  facet_grid(am ~ cyl,
             labeller = labeller(am  = as_labeller(am_names,  label_parsed),
                                 cyl = as_labeller(cyl_names, label_parsed))
             ) +
  geom_text(x = 4, y = 25, size = 4, nudge_y = 1,
            parse = TRUE, check_overlap = TRUE,
            label = as.character(expression(paste("Log"["10"], bgroup("(", frac("x", "y"), ")")))))
Run Code Online (Sandbox Code Playgroud)

### OR create new variables then assign labels directly
# reverse facet orders just for fun
mtcars <- mtcars %>% 
  mutate(am2  = factor(am,  labels = am_names),
         cyl2 = factor(cyl, labels = rev(cyl_names), levels = rev(attr(cyl_names, "names")))
  )

ggplot(mtcars, aes(wt, mpg)) + 
  geom_jitter() +
  facet_grid(am2 ~ cyl2,
             labeller = label_parsed) +
  annotate("text", x = 4, y = 30, size = 5,
           parse = TRUE, 
           label = as.character(expression(paste("speed [", m * s^{-1}, "]"))))
Run Code Online (Sandbox Code Playgroud)

reprex软件包(v0.2.1.9000)创建于2019-03-30