2012-02-07 8 views
6

pngファイルと同じggplot2グラフ出力のサイズがいくつか必要になることがよくあります。各PNGファイルのサイズは、出力の高さと幅(ピクセル単位)に変数を使用して生成するのに十分簡単です。 ggplot2の部分では、フォントやその他の要素のサイズに変数を使用し、各パスでこれらの変数を変更する単純なループを設定します。これはすべて期待どおりに動作し、Rとggplot2の柔軟性に敬意を表します。R:ggplot2がフォントサイズの変更を反映しない関数で使用される変数

ほとんどの場合、私は少数のチャートタイプのうちの1つを作成していますが、そのほとんどは変化しません。したがって、定型コードを見て、ggplot2のプロットをリストに返す単純な関数を作成することは理にかなっていると思いました。私がする必要があるのは、関数にデータフレーム、チャートに使用したい列の名前とその他の変数を渡すだけです。ループはプロットの名前を作成し、ggplotを呼び出してその結果をリストの要素に代入します。 2番目のパスでは、フォントサイズの変数は変更されますが、そうでない場合は同じように動作します。

しかし、フォントサイズはggplotによって選択されていないようです。具体的には、変数を使ってgeom_text()のサイズ、x軸とy軸のテキストのサイズ、プロットのタイトルを制御しています。関数から返された後にリストの内容を出力すると、geom_text()のサイズは期待どおりに変化しますが、他の2つの要素は同じでなければ変更されません。

Image 1 - (これは、例示目的のためだけであり、私は同じピクセルサイズを持つ2つの「中」と「大」のPNGファイルを使用していますが、通常、一方が他方の2倍になります下のコードであることに注意してください。)

そして、最初に別のタイトルと軸のテキストの大きさを持つべきである第二の画像、のではなく、:

Image 2

の一環として、「インライン」を使用する場合、このアプローチはうまく動作しますので通常のコードチャンク私は、いくつかの簡単な問題があると仮定することができます私が呼び出している方法や、おそらく問題の原因となっている機能をリフレッシュすることです。どんな助けでも大歓迎です。

私は以前のRで名前付き関数を使用していませんでした。私は専門家ではなくカジュアルなプログラマーですので、以下のdodgyコードについて事前にお詫び申し上げます。

# 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) 

} 
+2

'theme_text'呼び出しは即座に評価されるのではなく、必要なときにのみ評価されます。後で利用可能な' fontsize'の値を使用します。イテラループの開始。問題を次に示します。 'get(" size "、envir = environment(myplots [[1])$ ​​options $ plot.title))'(28ではなく16でなければなりません)どこかに 'force'を追加するか、コードを変更して各反復がそれ自身の環境を持つようにして問題を解決するかもしれません。 –

+0

このループをインラインで使用すると、ループの最後にprintステートメントがあります。おそらく、これが評価を強制するでしょう。おそらくそれがなぜ機能するのでしょうか?これありがとう。私は、怠け者の評価は主に理論的な問題だとは思っていましたが、明らかにそうではありませんでした! – SlowLearner

答えて

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 
+0

とてもいいです、私はそれを考えていませんでした。結果は有望です:今、私はgeom_sizeとfontsizeの両方を独立して変更することができますが、第2のグラフのtitlesizeは堅実に揺れを拒否しています。 'print(titlesize < - 28)'のような独自のprint文で2番目のif文に 'titlesize'の割り当てをラップして、それを強制的に評価するようにしましたが、顕著な効果はありませんでした。割り当ては明らかに効いているので、私は迷っています。それはさらにレイジーな評価かもしれません。骨アイドル評価、おそらく?どんなところでも、私はまだパズルの一部が欠けているようです。 – SlowLearner

+0

私は、リストではなくプロットを返すように改訂しました。プロット作成の直後にデバイスプロットコールを貼り付けて、すべてが順番に評価されるようにしました。上記のコードを編集しました。 –

+0

最終的に成功しました。おそらく、通常の時間外のソリューションのために余分なポイントを与えるべきです!どうもありがとう。 – SlowLearner

関連する問題