ggplot:如何改变facet标签?
我已经使用了下面的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 ~ .) + opts(panel.background = theme_blank())
生产
但是,我希望将标签标签更改为更短的标签(如Hosp 1,Hosp 2 …),因为它们太长了,看起来很拥挤(增加graphics高度不是一种select,文档中的空间太多)。 我看着facet_grid帮助页面,但无法弄清楚如何。
使用类似于以下的方式更改基础级别的名称:
# 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 ~ .)
这是一个更好的解决scheme,避免编辑你的数据:
假设你的情节是由你的数据框的一部分组成的,它有一个control, test1, test2
级别control, test1, test2
,然后创build一个由这些值命名的列表:
hospital_names <- list( 'Hospital#1'="Some Hospital", 'Hospital#2'="Another Hospital", 'Hospital#3'="Hospital Number 3", 'Hospital#4'="The Other Hospital" )
然后创build一个“贴标签”function,并将其推入到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) ...
这使用数据框的级别来索引hospital_names列表,返回列表值(正确的名称)。
请注意,这只适用于你只有一个分面variables。 如果您有两个方面,那么您的标签工具需要为每个方面返回一个不同的名称向量。 你可以用这样的东西做到这一点:
plot_labeller <- function(variable,value){ if (variable=='facet1') { return(facet1_names[value]) } else { return(facet2_names[value]) } }
其中facet1_names
和facet2_names
是由分面索引名称('Hostpital#1'等)索引的名称的预定义列表。
编辑:如果您传递贴标签不知道的variables/值组合,上述方法失败。 您可以为未知variables添加一个失败保护,如下所示:
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)) } }
回答如何改变ggplot带有facet和margin = TRUE的strip.text标签
编辑: 警告 :如果您使用此方法来面向字符列,您可能会得到不正确的标签。 看到这个错误报告 。 在最新版本的ggplot2中修复。
这是另外一个解决scheme,它是由@ naught101提供的,但更简单,也不会在最新版本的ggplot2上发出警告。
基本上,你首先创build一个命名的字符向量
hospital_names <- c( `Hospital#1` = "Some Hospital", `Hospital#2` = "Another Hospital", `Hospital#3` = "Hospital Number 3", `Hospital#4` = "The Other Hospital" )
然后你用它作为一个贴标签,只需修改@ naught101给出的代码的最后一行即可
... + facet_grid(hospital ~ ., labeller = as_labeller(hospital_names))
希望这可以帮助。
如果你有两个方面的hospital
和room
但只想重命名一个,你可以使用:
facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names)))
为了使用基于vector的方法重命名两个方面(如naught101的答案),可以这样做:
facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names), room = as_labeller(room_names)))
请注意,如果ggplot显示的variables比variables实际包含的要less(这可能会发生,如果你是例如子集),这个解决scheme将无法正常工作:
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)
一个简单的解决scheme(除了在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)
下面是我使用ggplot2版本2.2.1与facet_grid(yfacet~xfacet)
做的:
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) ) )
请注意,这不包含对as_labeller()
的调用,这是我一段时间as_labeller()
。
这种方法的灵感来自于帮助页面上的最后一个示例Coerce到贴标签function 。
只是扩大naught101的答案 – 信贷给他
plot_labeller <- function(variable,value, facetVar1='<name-of-1st-facetting-var>', var1NamesMapping=<pass-list-of-name-mappings-here>, facetVar2='', var2NamesMapping=list() ) { #print (variable) #print (value) if (variable==facetVar1) { value <- as.character(value) return(var1NamesMapping[value]) } else if (variable==facetVar2) { value <- as.character(value) return(var2NamesMapping[value]) } else { return(as.character(value)) } }
你必须做的是创build一个名称到名称映射的列表
clusteringDistance_names <- list( '100'="100", '200'="200", '300'="300", '400'="400", '600'="500" )
并用新的默认参数重新定义plot_labeller()
:
plot_labeller <- function(variable,value, facetVar1='clusteringDistance', var1NamesMapping=clusteringDistance_names, facetVar2='', var1NamesMapping=list() )
接着:
ggplot() + facet_grid(clusteringDistance ~ . , labeller=plot_labeller)
或者,您可以为每个您想要的标签更改创build专用function。
我有另一种方法来实现相同的目标,而不改变基础数据:
ggplot(transform(survey, survey = factor(survey, labels = c("Hosp 1", "Hosp 2", "Hosp 3", "Hosp 4"))), 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 ~ .) + opts(panel.background = theme_blank())
我上面做的是更改原始数据框中的因子的标签,这是与您的原始代码相比唯一的区别。
facet_wrap
和facet_grid
接受来自ifelse
input作为参数。 所以如果用于分面的variables是合乎逻辑的,那么解决scheme非常简单:
facet_wrap(~ifelse(variable, "Label if true", "Label if false"))
如果variables有更多的类别,则ifelse
语句需要嵌套 。
作为副作用,这也允许在ggplot
调用中创build组。