R:绘图循环中的对数y轴生成空图

时间:2014-12-22 17:17:58

标签: r plot logarithm rect

我试图将数据绘制成具有par(mfrow)的分割图,并且我试图获得y对数y轴,轴被定义为正常,但不知何时绘图数据将不会被绘制,并且绘图是空的。

我的问题:有没有人看到我的代码出现了什么问题以及为什么没有绘制任何内容(代码执行没有错误)?

第二个问题:如何定义y轴的刻度线和轴标签,以便只显示10,100和1000?

以下是我的代码,其中包含一些与我的初始数据结构相同的示例数据xy

xy <- structure(list(GROUP = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("Group1", "Group2", "Group3"), class = "factor"), YEAR1 = c(1966L, 1967L, 1968L, 1969L, 1970L, 1971L, 1972L, 1973L, 1964L, 1965L,1966L, 1967L, 1968L, 1971L, 1972L, 1973L, 1974L, 1975L, 1976L), YEAR2 = c(1967L, 1968L, 1969L, 1970L, 1971L, 1972L,1973L, 1974L, 1965L, 1966L, 1967L, 1968L, 1969L, 1972L, 1973L,1974L, 1975L, 1976L, 1977L), SAMPLES1 = c(83L, 86L, 118L, 116L, 114L, 111L, 108L, 106L, 24L, 25L, 26L, 26L, 26L, 87L, 82L, 218L, 203L, 221L, 219L), SAMPLES2 = c(83L, 86L, 118L, 116L, 114L, 111L, 108L, 106L, 24L, 25L, 26L, 26L, 26L, 87L, 82L, 218L, 203L, 221L, 219L), RANK = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L,2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L)), .Names = c("GROUP","YEAR1", "YEAR2", "SAMPLES1", "SAMPLES2", "RANK"), class = "data.frame", row.names = c(NA, -19L))

ind <- split(x = xy,f = xy[,'RANK'])
fname <- 'Plot.png'
png(fname, width=4658, height=6716, res=300)
par(mfrow=c(3,1), oma = c( 2, 2, 2, 2 ) )
# initiate plot
for (i in seq_along(ind)){
  i <- ind[[i]]
  xx = unlist(i[, c(2, 4)])
  yy = unlist(i[, c(3, 5)])
  my_x_lim <- range(c(1530, 2015)) 
  my_y_lim=range(c(yy,10,100))
  mar.default <- c(2,4,2,4) + 0.1
  par(mar = mar.default + c(-1.2, 0, -1.2, 0),mgp = c(0, 1, 0)) 
  plot(xx, yy,log="y",xaxs="i",type='n', xlab=NA,ylab=NA,xlim = my_x_lim, ylim=my_y_lim,las=1,xaxt="n") 
  rect(par("usr")[1], par("usr")[3], par("usr")[2], par("usr")[4], col = "grey")
  par(mar = mar.default + c(-0.5, 0, -0.5, 0),mgp = c(0, 1, 0))
  axis(1, at = seq(1000, 2050, 10), cex.axis=0.7,lty=0, lwd.ticks=0,labels=TRUE, tcl=0)
  par(mar = mar.default + c(-1, 0, -1, 0),mgp = c(0, 1, 0))
  apply(i, 1, function(y) 
    rect(y[2], min(y[3], 0), y[4], max(y[3], 0), col= 'seagreen',border=NA)) 
  par(mar = mar.default + c(-1.2, 0, -1.2, 0),mgp = c(0, 1, 0)) 
  axis(1, at = seq(1000, 2050, 5), cex.axis=0.5, labels=NA, tcl=-0.3)
  axis(1, at = seq(1000, 2050, 10), cex.axis=0.5, labels=NA, tcl=-0.3,lwd.ticks=0.5)
  axis(3, at = seq(1000, 2050, 5), cex.axis=0.5, labels=NA, tcl=-0.3)
  axis(3, at = seq(1000, 2050, 10), cex.axis=0.5, labels=NA, tcl=-0.3,lwd.ticks=0.5)
  axis(2, at = seq(-100000, 100000, 1000), cex.axis=0.5, labels=NA, tcl=-0.2,lwd.ticks=0.5)
  axis(4, cex.axis=0.7, las=1, labels=TRUE)
}
dev.off() 

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题:

  1. 我认为在分配给xxyy时,您的代码是错误的。我认为您的y轴基于$SAMPLES[12]$YEAR[12]上的x轴,但您要将$YEAR1$SAMPLE1分配给xx,同样到yy。修复列引用,您的数据可能会正确排序/范围。

  2. 使用apply将行转换为向量;通常这很好,但由于其中一个元素($GROUP)是一个字符串,所有其他元素都会转换为字符串,因此对rect的中间应用调用是使用字符串,而不是数字。相应地对data.frame进行子集化,例如i[,-1]

  3. 您的y轴是对数但在调用rect时使用的是零(log(0)未定义)。将rect中的引用更改为1,这些可能会开始工作。

  4. 使用上面定义的xy数据,如果正确且可用,此代码会生成一些内容:

    ind <- split(x = xy,f = xy[,'RANK'])
    par(mfrow=c(3,1), oma = c( 2, 2, 2, 2 ) )
    # initiate plot
    for (i in seq_along(ind)){
      i <- ind[[i]]
      xx = unlist(i[, c(2, 3)])
      yy = unlist(i[, c(4, 5)])
      my_x_lim <- range(c(1530, 2015)) 
      my_y_lim=range(c(yy,10,100))
      mar.default <- c(2,4,2,4) + 0.1
      par(mar = mar.default + c(-1.2, 0, -1.2, 0),mgp = c(0, 1, 0)) 
      plot(xx, yy,log="y",xaxs="i",type='n', xlab=NA,ylab=NA,xlim = my_x_lim, ylim=my_y_lim,las=1,xaxt="n") 
      rect(par("usr")[1], par("usr")[3], par("usr")[2], par("usr")[4], col = "grey")
      par(mar = mar.default + c(-0.5, 0, -0.5, 0),mgp = c(0, 1, 0))
      axis(1, at = seq(1000, 2050, 10), cex.axis=0.7,lty=0, lwd.ticks=0,labels=TRUE, tcl=0)
      par(mar = mar.default + c(-1, 0, -1, 0),mgp = c(0, 1, 0))
      apply(i[, -1], 1, function(y)
        rect(min(y[1:2]), min(y[3], 1), max(y[1:2]), max(y[3], 1), col= 'seagreen', border=NA))
      par(mar = mar.default + c(-1.2, 0, -1.2, 0),mgp = c(0, 1, 0)) 
      axis(1, at = seq(1000, 2050, 5), cex.axis=0.5, labels=NA, tcl=-0.3)
      axis(1, at = seq(1000, 2050, 10), cex.axis=0.5, labels=NA, tcl=-0.3,lwd.ticks=0.5)
      axis(3, at = seq(1000, 2050, 5), cex.axis=0.5, labels=NA, tcl=-0.3)
      axis(3, at = seq(1000, 2050, 10), cex.axis=0.5, labels=NA, tcl=-0.3,lwd.ticks=0.5)
      axis(2, at = seq(-100000, 100000, 1000), cex.axis=0.5, labels=NA, tcl=-0.2,lwd.ticks=0.5)
      axis(4, cex.axis=0.7, las=1, labels=TRUE)
    }