【问题标题】:How to add an inset (subplot) to "topright" of an R plot?如何将插图(子图)添加到 R 图的“右上角”?
【发布时间】:2013-06-11 09:51:25
【问题描述】:

我想在绘图中插入一个占绘图区域(图形所在区域)宽度和高度 25% 的插图。

我试过了:

# datasets
d0 <- data.frame(x = rnorm(150, sd=5), y = rnorm(150, sd=5))
d0_inset <- data.frame(x = rnorm(1500, sd=5), y = rnorm(1500, sd=5))

# ranges
xlim <- range(d0$x)
ylim <- range(d0$y)

# plot
plot(d0)

# add inset
par(fig = c(.75, 1, .75, 1), mar=c(0,0,0,0), new=TRUE)
plot(d0_inset, col=2) # inset bottomright

这会将插图置于绝对右上角,并使用 25% 的设备宽度。如何将其更改为图形所在区域的坐标和宽度?

【问题讨论】:

  • 也许将layout()(例如here)与xpd=TRUE结合使用可能会奏效。
  • 有一个命令告诉你绘图区域的尺寸。

标签: r plot insets


【解决方案1】:

您可以使用par("usr") 来获取情节的限制, 在用户坐标中,grconvert[XY] 转换它们 归一化设备坐标(NDC,介于 0 和 1 之间), 在将它们与par(fig=...) 一起使用之前。

plot(d0)
u <- par("usr")
v <- c(
  grconvertX(u[1:2], "user", "ndc"),
  grconvertY(u[3:4], "user", "ndc")
)
v <- c( (v[1]+v[2])/2, v[2], (v[3]+v[4])/2, v[4] )
par( fig=v, new=TRUE, mar=c(0,0,0,0) )
plot(d0_inset, axes=FALSE, xlab="", ylab="")
box()

【讨论】:

  • 很好的例子。我会注意到,可以在第二个par 命令之前添加rect(u[2], u[4], (u[1]+u[2])/2, (u[3]+u[4])/2, col="white") 以用白色填充插入区域(并绘制黑色边框,从而无需box)。
【解决方案2】:

查看TeachingDemos 包中的subplot 函数。它可能会使您尝试做的事情更容易。

这是一个例子:

library(TeachingDemos)
d0 <- data.frame(x = rnorm(150, sd=5), y = rnorm(150, sd=5))
d0_inset <- data.frame(x = rnorm(1500, sd=5), y = rnorm(1500, sd=5))

plot(d0)
subplot( 
  plot(d0_inset, col=2, pch='.', mgp=c(1,0.4,0),
    xlab='', ylab='', cex.axis=0.5), 
  x=grconvertX(c(0.75,1), from='npc'),
  y=grconvertY(c(0,0.25), from='npc'),
  type='fig', pars=list( mar=c(1.5,1.5,0,0)+0.1) )

【讨论】:

  • 即使使用subplot 也很难控制插图的大小:The rectangle defined by x, y, size, vadj, and hadj will be used as the plotting area of the new plot. Any tick marks, axis labels, main and sub titles will be outside of this rectangle.
  • @Sven,如果您设置type='fig' 而不是默认的'plt',那么所有标签、刻度等都将在指定的矩形内。
  • @Sven,我在上面添加了一个使用subplot 的示例。这假设您希望它在您的评论中的右下角(易于更改到其他角落)并且您希望它占用 1/4 线性空间(面积的 1/16,也易于更改)。
  • 如果您使用split.screen() 拥有多个图,则子图似乎使用所有图的加法/高度。因此,您需要调整grconvertX()中的坐标。
  • @Sven,我从来没有让split.screen 玩得很好,所以我已经很多年没有使用它了。混合使用任何不同的工具来处理图形需要一定的小心。
【解决方案3】:

使用par("plt") 找出绘图区域的面积(似乎类似于 vincents 的答案)。 奇怪的是: fig 设置了插图的绘图区域的大小。因此,如果显示轴,插图的大小将大于您的 25%。

# datasets
d0 <- data.frame(x = rnorm(150, sd=5), y = rnorm(150, sd=5))
d0_inset <- data.frame(x = rnorm(1500, sd=5), y = rnorm(1500, sd=5))

# ranges
xlim <- range(d0$x)
ylim <- range(d0$y)

# plot
plot(d0)

# calculate position of inset
plotdim <- par("plt")
xleft    = plotdim[2] - (plotdim[2] - plotdim[1]) * 0.25
xright   = plotdim[2]  #
ybottom  = plotdim[4] - (plotdim[4] - plotdim[3]) * 0.25  #
ytop     = plotdim[4]  #

# set position for inset
par(
  fig = c(xleft, xright, ybottom, ytop)
  , mar=c(0,0,0,0)
  , new=TRUE
  )

# add inset
plot(d0_inset, col=2) # inset bottomright

【讨论】:

    【解决方案4】:

    对我来说,使用了 oce 库中的示例: http://finzi.psych.upenn.edu/library/oce/html/plotInset.html

    看例子:

    library(oce)
    
    ## power law in linear and log form
    x <- 1:10
    y <- x^2
    plot(x, y, log='xy',type='l')
    plotInset(3, 1, 10, 8,
              expr=plot(x,y,type='l',cex.axis=3/4,mgp=c(3/2,1/2,0)),
              mar=c(2.5,2.5,1,1))
    
    ## CTD data with location
    data(ctd) 
    plot(ctd, which="TS")
    plotInset(29.9, 2.7, 31, 10,
              expr=plot(ctd, which='map',
              coastline="coastlineWorld",
              span=5000, mar=NULL, cex.axis=3/4))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2019-11-16
      • 2021-08-17
      • 2018-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多