2012-02-07 22 views
6

Tôi thường cần một vài kích cỡ khác nhau của cùng một đầu ra biểu đồ ggplot2 cho tệp png. Kích thước của mỗi tệp png đủ dễ dàng để tạo ra bằng cách sử dụng các biến cho chiều cao và chiều rộng đầu ra tính bằng pixel. Đối với phần ggplot2, tôi sử dụng các biến cho kích thước phông chữ và một số phần tử khác và thiết lập một vòng lặp đơn giản thay đổi các biến đó trong mỗi lần truyền. Điều này tất cả các công trình như mong đợi và là một cống nạp cho sự linh hoạt của R và ggplot2.R: ggplot2 được sử dụng trong hàm không phản ánh thay đổi về biến kích thước phông chữ

Hầu hết thời gian tôi đang tạo một trong số ít loại biểu đồ, hầu hết trong số đó không thay đổi. Theo đó tôi nghĩ rằng sẽ có ý nghĩa để tạo ra một hàm đơn giản trông coi mã boilerplate và trả về các ô từ ggplot2 trong một danh sách. Tất cả những gì tôi cần làm là chuyển đến chức năng khung dữ liệu, tên của cột mà tôi muốn sử dụng trong biểu đồ và một vài biến khác. Vòng lặp tạo tên cho cốt truyện, gọi ggplot và gán kết quả cho một phần tử trong danh sách. Vào lần thứ hai, nó thay đổi các biến kích thước phông chữ nhưng nếu không thì sẽ hoạt động giống hệt nhau.

Tuy nhiên, kích thước phông chữ dường như không bị nhận bởi ggplot. Cụ thể, tôi đang sử dụng các biến để kiểm soát kích thước của geom_text(), kích thước của văn bản trục x và y và tiêu đề của ô. Khi tôi in nội dung của danh sách sau khi nó được trả về từ hàm, kích thước geom_text() đang thay đổi như mong đợi, nhưng hai phần tử khác không thay đổi khi chúng khác nhau. (Lưu ý rằng trong mã bên dưới, tôi đang sử dụng hai tệp png 'trung bình' và 'lớn' với cùng kích thước pixel nhưng thường là một tệp lớn gấp hai lần so với tệp kia - đây chỉ là mục đích minh họa.)

Image 1

và hình ảnh thứ hai, mà cần phải có tiêu đề và văn bản trục kích cỡ khác nhau để là người đầu tiên, nhưng không:

Image 2

Bởi vì phương pháp này hoạt động tốt khi sử dụng 'in-line' như là một phần của một đoạn mã bình thường tôi chỉ có thể giả định rằng có một số vấn đề đơn giản với cách tôi gọi hoặc có thể làm mới chức năng đang gây ra sự cố. Bất kỳ giúp đỡ nhiều đánh giá cao.

Tôi chưa sử dụng các hàm được đặt tên trong R trước đây và tôi là một lập trình viên bình thường chứ không phải là chuyên gia, vì vậy xin lỗi trước cho mã dodgy bên dưới.

# 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

Đây là vấn đề với việc đánh giá lười biếng. Các cuộc gọi 'theme_text' không được đánh giá ngay lập tức, nhưng chỉ khi cần thiết, sau này sẽ sử dụng giá trị' fontsize' có sẵn tại thời điểm sau đó, tương ứng với itera tion của vòng lặp. Sau đây cho thấy vấn đề: 'get (" size ", envir = environment (myplots [[1]] $ options $ plot.title))' (nó phải là 16, không phải 28). Thêm 'force' vào đâu đó, hoặc thay đổi mã để mỗi lần lặp có môi trường riêng của nó có thể khắc phục được sự cố. –

+0

Khi tôi sử dụng vòng lặp này trong dòng tôi có một tuyên bố in ở cuối vòng lặp và có lẽ lực lượng đánh giá này, có lẽ là lý do tại sao nó hoạt động? Cảm ơn vì điều này. Tôi đã có loại suy nghĩ rằng đánh giá lười biếng phần lớn là một vấn đề lý thuyết nhưng dường như không! – SlowLearner

Trả lời

4

Xác định các chức năng cốt truyện của bạn đầu tiên (để họ có thể chấp nhận các thông số bạn sẽ được thay đổi:

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) 

    } 

.... sau đó gọi cho họ và gọi cho họ với các giá trị tham số bạn muốn:.

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

Rất đẹp, tôi đã không nghĩ về điều đó.Kết quả là đầy hứa hẹn: bây giờ tôi có thể nhận được cả hai geom_size và phông chữ để thay đổi một cách độc lập, nhưng tiêu đề trong biểu đồ thứ hai là kiên định từ chối nhúc nhích. Tôi đã thử gói nhiệm vụ 'titleize' trong câu lệnh if thứ hai trong câu lệnh in của chính nó như thế này 'print (titleize <- 28)' để buộc nó được đánh giá nhưng không có bất kỳ hiệu ứng đáng chú ý nào. Việc phân công rõ ràng là làm việc, vì vậy tôi đang thua lỗ. Nó có thể là một đánh giá thậm chí lazier; đánh giá nhàn rỗi xương, có lẽ? Dù sao, tôi dường như vẫn còn thiếu một phần của câu đố. – SlowLearner

+0

Tôi sửa đổi nó để chỉ trả lại cốt truyện chứ không phải là một danh sách, và tôi bị mắc kẹt thiết bị âm mưu cuộc gọi ngay sau khi tạo ra âm mưu vì vậy tất cả mọi thứ được đánh giá theo thứ tự. Đã chỉnh sửa mã ở trên. –

+0

Thành công cuối cùng - giáo dục để lỗ chân lông trên cũng. Có lẽ nên cung cấp cho bạn một điểm thêm cho một giải pháp ngoài giờ bình thường là tốt! Cảm ơn nhiều. – SlowLearner

Các vấn đề liên quan