【问题标题】:Overlay two alluvial plots with same dimensions覆盖两个相同尺寸的冲积地块
【发布时间】:2020-06-10 01:14:40
【问题描述】:

我正在尝试在 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")

但是我如何确保两个地块的坐标相同,因为我的矩形是基于冲积坐标的?

【问题讨论】:

  • 您可以在调用alluvial函数后立即使用par("usr")检查轴限制。

标签: r plot graphics


【解决方案1】:

通常 par("usr") 命令可以告诉您当前绘图区域的极值。但是这里有点难,因为冲积函数会调整函数内的mar图形参数。它将边距更改为c(2,1,1,1)。在函数结束时,它会将边距恢复到最初的状态。默认边距为 c(5, 4, 4, 2) + 0.1,表示绘图区域的底部、左侧、顶部和右侧外边距之间的行数(1 行 = 1/5 英寸)。查看par 的帮助页面并向下滚动,直到您到达 mai 以查看一个好的图表。冲积函数所做的另一项调整是将轴的默认 style 从常规 (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”参数,因为轴已经那里!

【讨论】:

  • 感谢您的详细回复。假设我将绘图结果存储在一个名为 temp 的变量中。该变量将存储绘图的端点,该端点基本上是坐标。如果我想突出显示左下角的矩形,我会获取坐标并绘制绘图rect(0,temp$endpoints[[1]][1,1],.3,temp$endpoints[[1]][1,2],col = "red") 它不起作用
  • temp= 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 )
  • 查看编辑。您需要修改我的回答中提到的绘图边距(mar=c(2,1,1,1)和轴 style:(xaxs="i", yaxs="i")。请记住,这就是冲积功能正在做的事情(秘密)。
  • xaxs = "i"yaxs = "i" 属于高级图形参数。我认为它们在低级函数 rect() 中没有意义。
  • @Darren Tsai... 你说的很对。感谢您注意到这一点。 ;)
【解决方案2】:

你可以想为什么这个函数只返回端点y坐标的矩阵?
alluvial的文档中说:

x 坐标是连续的自然数

说明

在您的示例中,图中有三个支柱,这意味着它们的中点分别位于 1、2、3。但是,每根柱子的左右边界在哪里?我认为您忽略了alluvial() 的一个关键参数cw,它控制柱子的宽度。如果您不设置它,它将采用默认值0.1。每根柱子的左右边界为

现在您可以轻松找到 eanch 柱子的两个边界。

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)

【讨论】:

  • 非常详细的答案。你能告诉我如何改变冲积层中的线条顺序吗?就像我希望 673 行位于 212 之上(在最后一列中)。我该怎么做?
  • @DhwaniDholakia 看到我的编辑。我添加了补充部分。
  • 您现在添加的解释除了回答我的问题外,还有很多信息。它甚至比冲积手册涵盖了更多的细节。非常感谢您的努力。
猜你喜欢
  • 1970-01-01
  • 2016-07-10
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多