R:ggplot2在函数中使用不反映字体大小变量的变化

时间:2012-02-07 00:26:57

标签: r ggplot2

我经常需要几个不同大小的相同ggplot2图表输出到png文件。每个png文件的大小很容易通过使用变量输出高度和宽度(以像素为单位)生成。对于ggplot2部分,我使用变量作为字体和某些其他元素的大小,并设置一个简单的循环,在每次传递中更改这些变量。这一切都按预期工作,是对R和ggplot2灵活性的致敬。

大多数情况下,我创建了少量图表类型中的一种,其中大多数都没有变化。因此,我认为创建一个简单的函数来处理样板代码并从列表中的ggplot2返回图表是有意义的。我需要做的就是将数据框,我想要在图表中使用的列的名称以及其他几个变量传递给函数。循环为绘图创建名称,调用ggplot并将结果分配给列表中的元素。在第二遍时,它会更改字体大小变量,但行为相同。

然而,字体大小似乎没有被ggplot拾取。具体来说,我使用变量来控制geom_text()的大小,x轴和y轴文本的大小以及绘图的标题。当我从函数返回后打印列表的内容时,geom_text()大小正在按预期变化,但是当它们应该不同时,其他两个元素不变。 (请注意,在下面的代码中,我使用两个具有相同像素大小的“中”和“大”png文件,但通常一个是另一个的两倍 - 这仅用于说明目的。)

Image 1

第二张图片应该有不同的标题和轴文字大小,但不是:

Image 2

因为这种方法在使用'in-line'作为普通代码块的一部分时工作正常,所以我只能假设我正在调用或者刷新导致问题的函数的方式存在一些直接的问题。任何帮助非常感谢。

我之前没有在R中使用过命名函数,而且我是一名休闲程序员而不是专业人员,所以请为下面的狡猾代码提前道歉。

# create test data
set.seed(12345)
mydf <- data.frame(passdate=seq(as.Date("1995/1/1"), by="month", length.out=204),passval=runif(204, min=25, max=100),ignoreval=runif(204, min=-21, max=-2))

myplots <- list()
myplots <- chart_high_mom(mydf,'passdate','passval','1995-02-01','2011-12-31',"My title here")

# first chart
mywidth = 700
myheight = 600
png(filename = "chart1.png", width = 700, height = 600, units = "px", res = NA)
print(myplots[[1]])
dev.off()
# second chart - this intended to be twice as large when bugs fixed
png(filename = "chart2.png", width = 700, height = 600, units = "px", res = NA)
print(myplots[[2]])
dev.off()
# end of calling code

chart_high_mom <- function(
    x = NULL, # a data frame containing the data to plot
    datecol, # name of column holding yyyy-mm-dd date series
    valcol, # name of column holding value to use for calculation
    fstartdate, # date in yyyy-mm-dd format specifying first date to plot
    fenddate, # date in yyyy-mm-dd format specifying last date to plot
    ftitle # title to add to plot
    )
    {

    require(gdata)
    require(xts)
    require(ggplot2)
    require(lubridate)    
    # strip the data frame down
    x <- subset(x,select = c(datecol,valcol))
    colnames(x) <- c('mydate','myval')
    # create year and month columns
    x$year <- as.numeric(format(as.Date(x$mydate), format="%Y"))
    x$month <- as.numeric(format(as.Date(x$mydate), format="%m"))
    # create month-on-month change column
    mydata.xts <- xts(x$myval,order.by=x$mydate)
    x$myvalmom <- diff(mydata.xts,lag=1)/lag(mydata.xts,1)

    plotlist <- list()

    for (i in 1:2) { # loop to create plot with two different sets of font sizes

        plotname <- paste("myplot", i, sep = "")

        if (i == 1) {
            fontsize <- 8
            titlesize <- 16
            geomtextsize <- 4
            ftitle <- "medium"
        }
        if (i == 2) {
            fontsize <- 24
            titlesize <- 28
            geomtextsize <- 5
            ftitle <- "large"
        }

        print(paste("i = ",i," and fontsize = ",fontsize," and plot = ",plotname,sept=""))

        plotlist[[plotname]] <- ggplot(x[x$mydate>=fstartdate & x$mydate<=fenddate,], 
            aes(x=month(mydate,label=TRUE),y=year(mydate), fill = myvalmom, label = sprintf("%1.1f%%", 100*myvalmom))) + 
          scale_y_date(major="years", format="%Y") +
          geom_tile() + 
          geom_text(data=x[x$mydate>=fstartdate & x$mydate<=fenddate,],size = geomtextsize,colour = "black") +
          scale_fill_gradient2(low = "blue", high = "red",midpoint=0) +
          scale_x_discrete(expand=c(0,0)) +
          scale_y_reverse(breaks=1980:2012, labels=1980:2012, expand=c(0,0) ) +

          opts(

          axis.text.y = theme_text(size = fontsize, colour = "grey50"),
          axis.text.x = theme_text(size = fontsize, colour = "grey50"),
          plot.title = theme_text(size = titlesize),
          title = ftitle,
          panel.grid.minor = theme_blank(),
          axis.ticks = theme_blank(),
          panel.grid.major = theme_blank(),
          axis.title.y = theme_blank(),
          axis.title.x = theme_blank(),
          panel.background = theme_rect(fill = "transparent",colour = NA),
          legend.position = "none"
          )

    }

return(plotlist)

}

1 个答案:

答案 0 :(得分:4)

首先定义绘图函数(这样它们就可以接受您将要更改的参数:

chart_high_mom <- function(fontsize, titlesize, geomtextsize, ftitle,
    x = NULL, # a data frame containing the data to plot
    datecol, # name of column holding yyyy-mm-dd date series
    valcol, # name of column holding value to use for calculation
    fstartdate, # date in yyyy-mm-dd format specifying first date to plot
    fenddate # date in yyyy-mm-dd format specifying last date to plot
                         ) {


    # strip the data frame down
    x <- subset(x,select = c(datecol,valcol))
    colnames(x) <- c('mydate','myval')
    # create year and month columns
    x$year <- as.numeric(format(as.Date(x$mydate), format="%Y"))
    x$month <- as.numeric(format(as.Date(x$mydate), format="%m"))
    # create month-on-month change column
    mydata.xts <- xts(x$myval,order.by=x$mydate)
    x$myvalmom <- diff(mydata.xts,lag=1)/lag(mydata.xts,1)

    plotlist <- list()


        print(paste("i = ",i," and fontsize = ",fontsize," and titlesize = ",titlesize,sep=""))

        thisplot <- ggplot(x[x$mydate>=fstartdate &
                                             x$mydate<=fenddate,], 
            aes(x=month(mydate,label=TRUE),y=year(mydate), 
             fill = myvalmom, label = sprintf("%1.1f%%", 100*myvalmom))) + 
                    scale_y_date(major="years", format="%Y") +
                    geom_tile() + 
                    geom_text(data=x[x$mydate>=fstartdate &
                         x$mydate<=fenddate,],size = geomtextsize, 
                         colour = "black") +
          scale_fill_gradient2(low = "blue", high = "red",midpoint=0) +
          scale_x_discrete(expand=c(0,0)) +
      scale_y_reverse(breaks=1980:2012, labels=1980:2012, expand=c(0,0) ) +
          force(opts(axis.text.y = 
                  theme_text(size = force(fontsize), colour = "grey50"),
               axis.text.x = theme_text(size = force(fontsize), colour = "grey50"),
          plot.title = theme_text(size = titlesize),
          title = ftitle,
          panel.grid.minor = theme_blank(),
          axis.ticks = theme_blank(),
          panel.grid.major = theme_blank(),
          axis.title.y = theme_blank(),
          axis.title.x = theme_blank(),
          panel.background = theme_rect(fill = "transparent",colour = NA),
          legend.position = "none"
          ))
return(thisplot)

    }

....然后打电话给他们。并使用您想要的参数值调用它们:

set.seed(12345)
mydf <- data.frame(passdate=seq(as.Date("1995/1/1"), by="month", length.out=204),passval=runif(204, min=25, max=100),ignoreval=runif(204, min=-21, max=-2))

myplots <- list()

for (i in 1:2) { # loop to create plot with two different sets of font sizes
              if (i == 1) {
            print(fontsize <- 8)
            print(titlesize <- 32)
            print(geomtextsize <- 4)
            print(ftitle <- "medium");  
     myplots[[1]] <-chart_high_mom(fontsize= fontsize , titlesize= titlesize , geomtextsize= geomtextsize , ftitle= ftitle , x=mydf, 'passdate', 'passval', '1995-02-01', '2011-12-31')
      png(filename = "chart1.png", width = 700, height = 600, units = "px", res = NA)
print(myplots[[1]])
dev.off()             }
        if (i == 2) {
            fontsize <- 24
            titlesize <- 12
            geomtextsize <- 5
            ftitle <- "large"; 
     myplots[[2]] <-chart_high_mom(fontsize= fontsize , titlesize= titlesize , geomtextsize= geomtextsize , ftitle= ftitle , x=mydf, 'passdate', 'passval', '1995-02-01', '2011-12-31')
      png(filename = "chart2.png", width = 700, height = 600, units = "px", res = NA)
print(myplots[[2]])
dev.off()      }       }
# end of calling code