3

我用 ggplot2 创建了一个情节。这是关于牛奶蛋白质含量的。我有两组和 4 次治疗。我想展示组与治疗、均值和误差线之间的相互作用。蛋白质含量从 2.6% 开始。现在我的 y 轴从那里开始,没有间隙,但我的主管想要一个。我尝试了 plotrix 库的 axis.break() ,但什么也没发生。我试图用 gap.plot 重建图形但我没有成功,但我必须承认我不是 R-hero。

这是我的图形的代码:

Protein<-ggplot(data=D, aes(x=treat, y=Prot,group=group, shape=group))+
  geom_line(aes(linetype=group), size=1, position=position_dodge(0.2))+
  geom_point(size=3, position=position_dodge(0.2))+
  geom_errorbar(aes(ymin=Prot-Prot_SD,ymax=Prot+Prot_SD), width=.2,      
position=position_dodge(0.2))+ 
  scale_shape_discrete(name='group\n', labels=c('1\n(n =   
22,19,16,20)\n','2\n(n = 15,12,14,12)'))+
  scale_linetype_discrete(name="group\n", labels=c('control\n(n =   
22,19,16,20)\n','free-contact\n(n = 15,12,14,12)'))+
  scale_x_discrete(labels=c('0', '1', '2', '3'))+
  labs(x='\ntreatment', y='protein content (%)\n')
ProtStar<-Protein+annotate("text", x=c(1,2,3,4), y=c(3.25,3.25,3.25,3.25),   
label=c("Aa","Aa","Ab","Ba"), size=4)
plot(ProtStar)

不幸的是,我没有足够的声誉来发布图像,但是您可能从代码中看到图形很复杂。

如果您有有用的建议,那就太好了。非常感谢!

4

1 回答 1

11

TL;DR:看看底部。

考虑这些数字:

ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic()

在此处输入图像描述

这是你的基本情节。现在您必须考虑 Y 轴。


ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic() +
  scale_y_continuous(limits = c(0,NA), expand = c(0,0))

在此处输入图像描述

这是强调数据的最低值为零的最不具误导性的方式,即使没有低于某个值的实际点也是如此。牛奶蛋白质百分比是一个很好的数据示例,其中不可能出现负值,您想强调这一点,但没有观察值接近于零。

这也缩小了 Y 轴的解释范围,因此观测值之间的差异较小。如果这是你想强调的,那很好。但是,如果某些数据的自然范围很窄,包括零(以及由此产生的空白区域)就会产生误导。例如,如果牛奶蛋白始终介于 2.6% 和 2.7% 之间,那么零值并不是数据的真实下限,但与 -50% 一样不可能。


ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic() +
  scale_y_continuous(limits = c(0,NA), expand = c(0,0)) + 
  theme(axis.line.y = element_blank()) +
  annotate(geom = "segment", x = -Inf, xend = -Inf, y = -Inf, yend = Inf) 

在此处输入图像描述

不包括损坏的 Y 轴的原因有很多。许多人认为在数据范围内包含一个内部数据是不道德或具有误导性的。但是这种特殊情况超出了实际数据的范围。我认为规则可以为此有所改变。

第一步是删除自动 Y 轴线并使用“手动”绘制它annotate。请注意,该图看起来与前一个相同。如果您选择的主题使用了很多不同的尺寸,那么您将度过一段糟糕的时光。


ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic() + 
  scale_y_continuous(limits = c(3.5,NA), expand = c(0,0), 
                     breaks = c(3.5, 4:7)) + 
  theme(axis.line.y = element_blank()) +
  annotate(geom = "segment", x = -Inf, xend = -Inf, y = -Inf, yend = Inf)

在此处输入图像描述

现在您可以考虑实际数据从哪里开始,以及在哪里休息的好地方。您必须手动检查;例如min(iris$Sepal.Length),考虑刻度线的位置。这是个人判断电话。

我发现最低值是 4.3。我知道我希望休息时间低于最小值,并且我希望休息时间长约 0.5 个单位。所以我选择在 3.5 处打勾,然后在每个整数之后加上breaks = c(3.5, 4:7).


ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic() + 
  scale_y_continuous(limits = c(3.5,NA), expand = c(0,0), 
                     breaks = c(3.5, 4:7), labels = c(0, 4:7)) + 
  theme(axis.line.y = element_blank()) +
  annotate(geom = "segment", x = -Inf, xend = -Inf, y = -Inf, yend = Inf)

在此处输入图像描述

现在我们需要用 将 3.5 刻度重新标记为假零labels = c(0, 4:7)


ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic() + 
  scale_y_continuous(limits = c(3.5,NA), expand = c(0,0), 
                     breaks = c(3.5, 4:7), labels = c(0, 4:7)) + 
  theme(axis.line.y = element_blank()) +
  annotate(geom = "segment", x = -Inf, xend = -Inf, y = -Inf, yend = Inf) +
  annotate(geom = "segment", x = -Inf, xend = -Inf, y =  3.5, yend = 4,
           linetype = "dashed", color = "white")

在此处输入图像描述

现在我们在手动绘制的轴线上画一条白色虚线,从我们的假零(y = 3.5)到最低的真实刻度线(y = 4)。

考虑到图形的语法是一种成熟的哲学;也就是说,每个元素背后都有深思熟虑的推理。这样做很挑剔的事实是有充分的理由,你需要考虑你自己的理由是否足以在另一边产生足够的分量。

于 2017-09-25T16:43:20.653 回答