我将尝试使用一个简化的示例来描述我的问题。我正在尝试用ggplot2绘制几种密度,例如:
library(reshape2)
library(ggplot2)
set.seed(1)
x <- replicate(5, rnorm(100))
colnames(x) <- paste0("x", 1:5)
ggplot(melt(x), aes(value, color = Var2)) + geom_density()
这按预期工作。现在,我想添加一个比例非常不同的新变量:
z <- cbind(x, y = rnorm(100) * 50)
ggplot(melt(z), aes(value, color = Var2)) + geom_density()
这将产生预期的图形,但不幸的是,我不想制作该图形。我想保留两个轴的原始比例,以便仍可以看到前五个密度之间的差异,并且新变量的密度将显示为平坦。
是否可以通过简单的方式执行此操作?就像告诉ggplot覆盖新密度而不更改缩放比例一样?还是让ggplot在计算轴的极限时忽略变量?
我可以考虑手动解决方案,该解决方案将首先保存轴的限制,然后在使用新变量创建图形时指定它们。但这可能不是最优雅的解决方案,并且可能需要大量额外的代码。如果可能的话,我宁愿避免这种解决方案(特别是因为我的情况实际上要复杂得多,并且包含多个带有facet_wrap()
的图)
任何建议或提示都将受到欢迎。提前非常感谢!
PS:为了给您提供更多背景信息,我试图将几个后验分布与它们的先验分布(平坦的)作图。我只能从先验中提取数据,而不能从其确切的密度函数中提取数据;否则,我只会用stat_function()
覆盖先验数据。
答案 0 :(得分:2)
这是更改第二个Y轴的一种很酷的方法:
首先,让我们以更通用的格式重新创建图表。我将创建一个数据框X(注意:它是大写的)
X <- data.frame(x)
g <- ggplot()
g <- g + geom_density(data = X, aes(x1, colour= "X1"))
g <- g + geom_density(data = X, aes(x2, colour= "x2"))
g <- g + geom_density(data = X, aes(x3, colour= "x3"))
g <- g + geom_density(data = X, aes(x3, colour= "x4"))
g
哪个会生成一张密度图
好的,很酷,现在让我们在您提到的z中重新创建问题
Z <- data.frame(z)
g <- ggplot()
g <- g + geom_density(data = Z, aes(x1, colour= "X1"))
g <- g + geom_density(data = Z, aes(x2, colour= "x2"))
g <- g + geom_density(data = Z, aes(x3, colour= "x3"))
g <- g + geom_density(data = Z, aes(x3, colour= "x4"))
g <- g + geom_density(data = Z, aes(x3, colour= "x4"))
g <- g + geom_density(data = Z, aes(y, colour= "y"))
g
哪个给
好的,现在我们可以根据第二个轴的子集
z <- cbind(x, y = rnorm(100) * 50)
即50岁,但您可以按自己的意愿做任何事情。
Z <- data.frame(z)
g <- ggplot()
g <- g + geom_density(data = Z, aes(x1, colour= "x1"))
g <- g + geom_density(data = Z, aes(x2, colour= "x2"))
g <- g + geom_density(data = Z, aes(x3, colour= "x3"))
g <- g + geom_density(data = Z, aes(x3, colour= "x4"))
g <- g + geom_density(data = Z, aes(y/50, colour= "y"))
g <- g + scale_y_continuous(sec.axis = sec_axis(~.*50, name= "Y Second Axis"))
g
哪个可以给我们所需的双y轴!
您也可以做一个x轴的双轴操作。
g <- ggplot()
g <- g + geom_density(data = Z, aes(x1, colour= "x1"))
g <- g + geom_density(data = Z, aes(x2, colour= "x2"))
g <- g + geom_density(data = Z, aes(x3, colour= "x3"))
g <- g + geom_density(data = Z, aes(x3, colour= "x4"))
g <- g + geom_density(data = Z, aes(y/50, colour= "y"))
g <- g + scale_x_continuous(sec.axis = sec_axis(~.*50, name= "x Second Axis"))
g
希望有帮助!
编辑:
经过澄清,看起来想要的结果只是保持原始的x轴限制,而增加新的更大的密度。我们既可以使用我的样式,也可以使用您使用的融合格式来做到这一点。
g <- ggplot()
g <- g + geom_density(data = Z, aes(x1, colour= "x1"))
g <- g + geom_density(data = Z, aes(x2, colour= "x2"))
g <- g + geom_density(data = Z, aes(x3, colour= "x3"))
g <- g + geom_density(data = Z, aes(x3, colour= "x4"))
g <- g + geom_density(data = Z, aes(y, colour= "y"))
g <- g + xlim(range(-4:4))
g
OR
ggplot(melt(z), aes(value, color = Var2)) + geom_density() + xlim(range(-4, 4)
编辑2:这为我们提供了一个具有右轴的图,但它从密度图中删除了值(如Remek所指出的,以及Jon Spring的注释中的解决方案)。我们可以得到使密度值保持不变的图吗?是!我们需要coord_cartesian(),这还将使我们能够进行“放大”,而不是散发超出我们限制范围的值。
以下是两种样式的解决方案:
g <- ggplot()
g <- g + geom_density(data = Z, aes(x1, colour= "X1"))
g <- g + geom_density(data = Z, aes(x2, colour= "x2"))
g <- g + geom_density(data = Z, aes(x3, colour= "x3"))
g <- g + geom_density(data = Z, aes(x3, colour= "x4"))
g <- g + geom_density(data = Z, aes(x3, colour= "x4"))
g <- g + geom_density(data = Z, aes(y, colour= "y"))
g <- g + coord_cartesian(xlim=c(-4, 4))
g
ggplot(melt(z), aes(value, color = Var2)) + geom_density() + coord_cartesian(xlim=c(-4, 4))
答案 1 :(得分:1)
如何使用预合并的数据指定范围?
ggplot(melt(z), aes(value, color = Var2)) +
geom_density() +
coord_cartesian(xlim = c(min(melt(x)$value),
max(melt(x)$value)))
或者,我们可以使用相同的melt(z)
,但使用新变量撤消数据:
ggplot(melt(z), aes(value, color = Var2)) +
geom_density() +
coord_cartesian(xlim = c(min(subset(melt(z), Var2 != "y")$value),
max(subset(melt(z), Var2 != "y")$value)))