首页 > 解决方案 > 增加 geom_line() 堆栈之间的距离

问题描述

我有一些来自 XRD 的衍射数据。我想将所有内容都绘制在一张图表中,但要堆叠起来。因为 y 的范围非常大,所以堆叠并不是那么直接。如果您想玩,有一个数据链接,简单的脚本如下

https://www.dropbox.com/s/b9kyubzncwxge9j/xrd.csv?dl=0

library(dplyr)
library(ggplot2)
#load it up
xrd <- read.csv("xrd.csv")
#melt it

xrd.m = melt(xrd, id.var="Degrees_2_Theta")
# Reorder so factor levels are grouped together

xrd.m$variable = factor(xrd.m$variable, 
                        levels=sort(unique(as.character(xrd.m$variable))))
names(xrd.m)[names(xrd.m) == "variable"] <- "Sample"
names(xrd.m)[names(xrd.m) == "Degrees_2_Theta"] <- "angle"

#colours use for nearly everything

cbPalette <- c("#000000", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7")

#plot
ggplot(xrd.m, aes(angle, value, colour=Sample, group=Sample)) +
  geom_line(position = "stack") +
  scale_colour_manual(values=cbPalette) +
  theme_linedraw() +
  theme(legend.position = "none",  
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank()) + 
  labs(x="Degrees 2-theta", y="Intensity - stacked for clarity")  

这是情节-如您所见,它并没有完全堆叠

这是我在 excel 中的一些东西。丑陋 - 但稍微好一点

我不确定我是否会真正使用 R 中的堆叠绘图函数,因为我发现它总是与过去的经验相去甚远,而是可能使用我在 excel 中使用的相同数据操作。

标签: rggplot2

解决方案


似乎您对申请结果的理解与position="stack"实际geom_line()发生的情况不同。您想要做的最好的方法是使用faceting或创建ridgeline plot。我将在此处通过一些示例数据为您提供这两种方法的解决方案(对不起,我不单击保管箱链接,它们最终还是会中断)。

实际上是做什么的position="stack"

的结果position="stack"将是您的每条线的 y 值将被添加或“堆叠”在结果图中。这意味着绘制的线条实际上只会准确反映其中一条线的数据中的实际值,而另一条线将“添加在”该线的顶部(堆叠)。通过一个示例可以最好地说明该行为:

ex <- data.frame(x=c(1,1,2,2,3,3), y=c(1,5,1,2,1,1), grp=rep(c('A','B'),3))
ggplot(ex, aes(x,y, color=grp)) + geom_line()

在此处输入图像描述

“A”的 y 值在所有 x 值处都等于 1。这与指示相同position="identity"。现在,让我们看看如果我们使用会发生什么position="stack"

ggplot(ex, aes(x,y, color=grp)) + geom_line(position="stack")

在此处输入图像描述

您应该看到,为“B”绘制的 y 值等于 B,而“A”的 y 值实际上是“A”的值加上“B”的值。希望这是有道理的。

刻面

您要做的是采用您拥有的重叠线并垂直“分离”它们,对吗?这不是很堆叠,因为您可能希望将它们的 y 值保持为position="identity"(默认值)。一种很容易做到这一点的方法是使用faceting,它根据数据集中的一个或两个变量创建你可以称之为“堆叠图”的东西。在这种情况下,我使用的是示例数据(出于上述原因),但您可以使用它来了解您希望如何安排自己的数据。

set.seed(1919191)
df <- data.frame(
  x=rep(1:100, 5),
  y=c(rnorm(100,0,0.1), rnorm(100,0,0.2), rnorm(100,0,0.3), rnorm(100,0,0.4), rnorm(100,0,0.5)),
  sample_name=c(rep('A',100), rep('B',100), rep('C',100), rep('D',100), rep('E',100)))

# plot code
p <- ggplot(df, aes(x,y, color=sample_name))
p + geom_line() + facet_grid(sample_name ~ .)

在此处输入图像描述

创建脊线图

另一种做同样事情的方法是创建所谓的ridgeline plot。您可以通过包执行此操作ggridges,这是一个使用示例geom_ridgeline()

p + geom_ridgeline(
    aes(y=sample_name, height=y),
    fill=NA, scale=1, min_height=-Inf)

在此处输入图像描述

这里的想法是理解geom_ridgeline()将 y 轴更改为分组变量(因此我们实际上必须在 中重新定义它aes()),并且每个组的实际 y 值应该分配给height=审美。如果您的数据具有负 y 值(现在height=的值),您还需要设置min_height=,否则默认情况下它将在 0 处切断它们。您还可以通过玩来更改每个组的分隔程度scale=(顺便说一句,并不总是以您认为的方式改变)。


推荐阅读