[英]Overlay two alluvial plots with same dimensions
我试图在 R 中的冲积图上绘制矩形。我的代码是:
library(alluvial)
tit <- as.data.frame(Titanic)
tit2d <- aggregate(Freq ~ Class + Survived, data=tit, sum)
alluvial(tit2d, freq = tit2d$Freq, xw = 0.0, alpha = 0.8,
gap.width = 0.1, col = "steelblue", border = "white",
layer = tit2d$Survived != "Yes", blocks = F)
par(new = TRUE)
plot(c(0, 1), c(0, 1), type = "n", xlab = "", ylab = "")
rect(0, 0, 0.3, 0.4, col = "red")
但是如何确保两个图的坐标相同,因为我的矩形基于冲积坐标?
通常 par("usr") 命令可以告诉您当前绘图区域的极值。 但是这里有点困难,因为冲积函数在函数内部调整了mar
图形参数。 它将边距更改为c(2,1,1,1)
。 在函数结束时,它会将边距恢复到最初的状态。 默认边距为 c(5, 4, 4, 2) + 0.1,表示底部、左侧、顶部和右侧外边距到绘图区域之间的行数(1 行 = 1/5 英寸)。 查看par
帮助页面并向下滚动,直到您到达 mai 以查看一个好的图表。 冲积函数所做的另一个调整是将轴的默认样式从常规 (xaxs="r", yaxs="r") 更改为内部 (xaxs="i", yaxs="i"),这会导致轴进一步延伸。
例如:
alluvial( tit2d, freq=tit2d$Freq, xw=0.0, alpha=0.8,
gap.width=0.1, col= "steelblue", border="white",
layer = tit2d$Survived != "Yes", blocks = F )
u <- par("usr"); u
par(new=TRUE)
plot(0, type= "n", xlab = "", ylab = "", las=1, xaxs = "i", yaxs = "i",
xlim=c(u[1], u[2]), ylim=c(u[3], u[4]))
rect(u[1], u[3], u[2], u[4], col = "red")
您将在大部分绘图区域中看到一个红色矩形。 矩形极端和冲积极端之间的巨大差距是由于边缘的所述变化。
您可以尝试通过手动减少边距来模拟冲积功能,如下所示:
op <- par(mar=c(2,1,1,1))
par(new=TRUE)
plot(0, type= "n", xlab = "", ylab = "", las=1,
xlim=c(u[1], u[2]), ylim=c(u[3], u[4]))
rect(u[1], u[3], u[2], u[4], col = "green")
par(op)
您的绿色矩形现在应该覆盖整个冲积地块。
编辑:要突出显示较低的矩形:
par(new=TRUE, mar=c(2,1,1,1))
u <- par("usr")
rect(u[1], temp$endpoints[[1]][1,1], u[1]+0.2, # Note: cw has a default value of 0.1
temp$endpoints[[1]][1,2], col = "red")
rect(u[1]+1, temp$endpoints[[1]][1,1], u[1]+1.2,
temp$endpoints[[1]][1,2], col = "red")
rect(u[1]+2, temp$endpoints[[1]][1,1], u[1]+2.2,
temp$endpoints[[1]][1,2], col = "red")
编辑:感谢@Darren Tsai 指出像rect()
这样的低级绘图函数没有用于修改轴样式的“xaxs”参数,因为轴已经存在!
你可以想为什么这个函数只返回端点的 y 坐标矩阵?
从文档alluvial
,它说:
x 坐标是连续的自然数。
解释
在您的示例中,图中有三个支柱,这意味着它们的中点分别位于 1、2、3。 但是,每个柱子的左右边界在哪里? 我认为您忽略了cw
alluvial()
一个关键参数cw
,它控制柱子的宽度。 如果您不设置它,它将采用其默认值0.1
。 每个柱子的左右边界将是
现在您可以轻松找到每个柱子的两个边界。
temp <- alluvial(tit2d, freq = tit2d$Freq, xw = 0, alpha = 0.8,
gap.width = 0.1, col = "steelblue", border = "white",
layer = tit2d$Survived != "Yes", blocks = F)
par(xpd = TRUE)
abline(v = 1:3, lwd = 3, col = "red")
abline(v = 1:3 - 0.1, lwd = 3, col = "blue")
abline(v = 1:3 + 0.1, lwd = 3, col = "green")
如果要突出显示某个矩形:
par(xpd = TRUE)
y <- temp$endpoints
# bottom-left rectangle
rect(1 - 0.1, y[[1]][1, 1],
1 + 0.1, y[[1]][1, 2], col = "red")
# the second pillar, the fourth rectangle from the bottom
rect(2 - 0.1, y[[2]][4, 1],
2 + 0.1, y[[2]][4, 2], col = "orange")
为什么是par(xpd = TRUE)
?
par("xpd")
可以设置
FALSE
(默认):所有绘图都被剪切到“绘图”区域TRUE
:所有绘图都被剪切到“图形”区域NA
:所有绘图都被剪切到“设备”区域如果你不改变默认值,所有的低级绘图函数,例如points()
, abline()
, rect()
, text()
...,当离开“绘图”区域时都会被剪掉。 您可以使用box()
来查看“绘图”区域的位置。
结论
参数cw = 0.1
(默认值)。 您可以更改它,但 x 坐标会有所不同。
设置par(xpd = TRUE)
。
补充
如果要更改条纹的绘制顺序,请尝试调整参数layer
。 它可以是逻辑或数字向量。 数字越大,条纹绘制得越早,即低于数字较小的条纹。
在您的示例中,您可以根据Freq
的等级更改顺序。
请注意以下区别:
rank(tit2d$Freq)
将较小的值映射到较低的等级。rank(-tit2d$Freq)
将较小的值映射到较高的等级。tit2d$Freq
# [1] 122 167 528 673 203 118 178 212
rank(tit2d$Freq)
# [1] 2 3 7 8 5 1 4 6
rank(-tit2d$Freq)
# [1] 7 6 2 1 4 8 5 3
因此,您在评论中需要的是后者。
alluvial(tit2d, freq = tit2d$Freq, xw = 0, alpha = 0.8,
gap.width = 0.1, col = "steelblue", border = "white",
layer = rank(-tit2d$Freq), blocks = F)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.