axis.break 和 ggplot2 还是 gap.plot?情节可能太复杂
axis.break and ggplot2 or gap.plot? plot may be too complex
我用 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)
不幸的是,我没有足够的声誉来 post 图片,但您可能会从代码中看到图形很复杂。
如果您能提供有用的建议,那就太好了。
非常感谢!
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 轴的解释范围,因此观察结果之间的差异较小。如果这是你想强调的东西,那可能很好。但如果某些数据的自然范围很窄,包括零(以及由此产生的空值 space)就会产生误导。例如,如果牛奶蛋白始终在 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
在"by hand"中绘制。请注意,该图看起来与前一个相同。如果你选择的主题使用了很多不同的尺寸,你会很不开心。
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)
现在我们需要用 labels = c(0, 4:7)
.
将 3.5 刻度重新标记为假零
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)。
认为图形语法是一门成熟的哲学;也就是说,每个元素背后都有深思熟虑的推理。这么挑剔是有充分理由的,你需要考虑一下你自己的理由对另一边是否有足够的分量。
我用 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)
不幸的是,我没有足够的声誉来 post 图片,但您可能会从代码中看到图形很复杂。
如果您能提供有用的建议,那就太好了。 非常感谢!
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 轴的解释范围,因此观察结果之间的差异较小。如果这是你想强调的东西,那可能很好。但如果某些数据的自然范围很窄,包括零(以及由此产生的空值 space)就会产生误导。例如,如果牛奶蛋白始终在 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
在"by hand"中绘制。请注意,该图看起来与前一个相同。如果你选择的主题使用了很多不同的尺寸,你会很不开心。
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)
现在我们需要用 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)。
认为图形语法是一门成熟的哲学;也就是说,每个元素背后都有深思熟虑的推理。这么挑剔是有充分理由的,你需要考虑一下你自己的理由对另一边是否有足够的分量。