繁体   English   中英

覆盖两个相同尺寸的冲积地块

[英]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()来查看“绘图”区域的位置。


结论

  1. 参数cw = 0.1 (默认值)。 您可以更改它,但 x 坐标会有所不同。

  2. 设置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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM