【发布时间】:2017-03-19 18:46:53
【问题描述】:
我在 ggplot 上苦苦挣扎(我总是这样)。关于强制 ggplot 在图例中包含零值类别有许多非常类似的问题 - here 和 here(例如)。但是我(认为我)有一个稍微不同的要求,我所有的 scale_x_discrete 和 scale_fill_manual 都没有帮助。
要求:如您所见;右侧图没有 TM=5 类别中的数据 - 因此缺失。我需要的是正确的情节在轴上显示类别 5,但显然没有点或框。
当前剧情脚本:
#data
plotData <- data.frame("TM" = c(3,2,3,3,3,4,3,2,3,3,4,3,4,3,2,3,2,2,3,2,3,3,3,2,3,1,3,2,2,4,4,3,2,3,4,2,3),
"Score" = c(5,4,4,4,3,5,5,5,5,5,5,3,5,5,4,4,5,4,5,4,5,4,5,4,4,4,4,4,5,4,4,5,3,5,5,5,5))
#vars
xTitle <- bquote("T"["M"])
v.I <- plotData$TM
depVar <- plotData$Score
#plot
p <- ggplot(plotData, aes_string(x=v.I,y=depVar,color=v.I)) +
geom_point() +
geom_jitter(alpha=0.8, position = position_jitter(width = 0.2, height = 0.2)) +
geom_boxplot(width=0.75,alpha=0.5,aes_string(group=v.I)) +
theme_bw() +
labs(x=xTitle) +
labs(y=NULL) +
theme(legend.position='none',
axis.text=element_text(size=10, face="bold"),
axis.title=element_text(size=16))
尝试的解决方案:
-
drop=False缩放(由@Jarretinha here 建议)完全破坏边距和 x 轴标签> plot + scale_x_discrete(drop=FALSE) + scale_fill_manual(drop=FALSE)
-
遵循here 中的逻辑并手动设置
scale_fill_manual中的标签不会执行任何操作,并且会产生与上例相同的右侧图。> p + scale_fill_manual(values = c("red", "blue", "green", "purple", "pink"), labels = c("Cat1", "Cat2", "Cat3", "Cat4", "Cat5"), drop=FALSE) -
使用此逻辑并尝试使用
scale_x_discrete会导致 x 轴上的类别名称发生变化,但第五个仍然丢失,并且边距(作为尝试 1)再次被破坏。但显然scale_x_discrete很重要,不是整个答案> p + scale_x_discrete(limits = c("Cat1", "Cat2", "Cat3", "Cat4", "Cat5"), drop=FALSE)
ANSWER 以上示例由@Bouncyball 和@aosmith 提供的输入提供
#data
plotData <- data.frame("TM" = c(3,2,3,3,3,4,3,2,3,3,4,3,4,3,2,3,2,2,3,2,3,3,3,2,3,1,3,2,2,4,4,3,2,3,4,2,3),
"Score" = c(5,4,4,4,3,5,5,5,5,5,5,3,5,5,4,4,5,4,5,4,5,4,5,4,4,4,4,4,5,4,4,5,3,5,5,5,5))
plotData$TM <- factor(plotData$TM, levels=1:5) # add correct (desired number of factors to input data)
#vars
xTitle <- bquote("T"["M"])
v.I <- plotData$TM
depVar <- plotData$Score
myPalette <- c('#5c9bd4','#a5a5a4','#4770b6','#275f92','#646464','#002060')
#plot
ggplot(plotData, aes_string(x=v.I,y=depVar,color=v.I)) +
geom_jitter(alpha=0.8, position = position_jitter(width = 0.2, height = 0.2)) +
geom_boxplot(width=0.75,alpha=0.5,aes_string(group=v.I)) +
scale_colour_manual(values = myPalette, drop=F) + # new line added here
scale_x_discrete(drop=F) + # new line added here
theme_bw() +
labs(x=xTitle) +
labs(y=NULL) +
theme(legend.position='none',
axis.text=element_text(size=10, face="bold"),
axis.title=element_text(size=16))
【问题讨论】:
-
注意在您的第一个链接中推荐
drop = FALSE,x 变量是一个因素。您的 x 变量当前是数字。如果您将其作为一个因素并确保它具有所有 5 个兴趣级别(例如,plotData$TM = factor(plotData$TM, levels = 1:5)),您可以使用您链接到的答案。 -
这是一个旁白,但我对
aes_string(x=v.I,y=depVar,color=v.I)感到非常困惑。aes_string用于将数据框中列的 names 作为字符串传递,但您似乎正在映射原始数字向量,即使您本身传递了数据框。这是故意的吗? -
@joran 是故意的。为了获得一个可重现的示例,我只是从我更大的 .RMD 脚本中复制了基本脚本,因为这些图是从动态创建的数据帧中生成的。更有意义?
-
@aosmith - 我根据下面弹力球的帮助推测了这些因素,这一切都不同了!干杯
-
有点,只是它让你的例子有点荒谬。因为我的第一直觉是建议添加明确的因子水平,如下所述,但是这样做在您的数据框中实际上不会解决您提供的示例中的问题,因为您有将正在绘制的数据与您的数据框完全分离。以后最好还是
aes_string(x="TM",y="Score",color= "TM")。