2012-02-07 10 views
6

मुझे अक्सर पीएनजी फ़ाइलों में एक ही ggplot2 चार्ट आउटपुट के कई अलग-अलग आकारों की आवश्यकता होती है। प्रत्येक पीएनजी फ़ाइल का आकार आउटपुट ऊंचाई और चौड़ाई पिक्सेल में चर के लिए चर का उपयोग करके उत्पन्न करने के लिए काफी आसान है। Ggplot2 भाग के लिए मैं फ़ॉन्ट्स और कुछ अन्य तत्वों के आकार के लिए चर का उपयोग करता हूं और एक साधारण लूप सेट करता हूं जो प्रत्येक पास में उन चर को बदलता है। यह सब अपेक्षित काम करता है और आर और ggplot2 की लचीलापन के लिए श्रद्धांजलि है।आर: फ़ंक्शन में प्रयुक्त ggplot2 फ़ॉन्ट आकार परिवर्तनीय में परिवर्तन को प्रतिबिंबित नहीं करता

अधिकांश समय मैं चार्ट प्रकारों की एक छोटी संख्या में से एक बना रहा हूं, जिनमें से अधिकांश भिन्न नहीं होते हैं। तदनुसार मैंने सोचा कि यह एक सरल कार्य बनाने के लिए समझ में आता है जो बॉयलरप्लेट कोड की देखभाल करता है और सूची में ggplot2 से प्लॉट देता है। मुझे बस इतना करना है कि डेटा फ्रेम फ़ंक्शन को पास करें, कॉलम का नाम जिसे मैं चार्ट में उपयोग करना चाहता हूं और कुछ अन्य चर। लूप प्लॉट के लिए एक नाम बनाता है, ggplot को कॉल करता है और परिणाम को सूची में एक तत्व को असाइन करता है। दूसरे पास पर यह फ़ॉन्ट आकार चर बदलता है लेकिन अन्यथा समान रूप से व्यवहार करता है।

हालांकि, फ़ॉन्ट आकार ggplot द्वारा उठाए जाने लगते नहीं हैं। विशेष रूप से, मैं geom_text(), x और y अक्ष पाठ का आकार और साजिश का शीर्षक नियंत्रित करने के लिए चर का उपयोग कर रहा हूं। जब मैं फ़ंक्शन से वापस लौटने के बाद सूची की सामग्री मुद्रित करता हूं, तो geom_text() आकार बदल रहा है जैसा कि कोई अपेक्षा करेगा, लेकिन अन्य दो तत्व अपरिवर्तित होते हैं जब उन्हें अलग होना चाहिए। (ध्यान दें कि नीचे दिए गए कोड में मैं दो 'मध्यम' और 'बड़ी' पीएनजी फाइलों का उपयोग उसी पिक्सेल आकार के साथ कर रहा हूं लेकिन आमतौर पर एक दूसरे के रूप में दोगुना होगा - यह केवल चित्रकारी उद्देश्यों के लिए है।)

Image 1 के हिस्से के रूप

Image 2

क्योंकि इस दृष्टिकोण ठीक काम करता है जब 'में लाइन' का प्रयोग किया:

और दूसरी छवि, जो पहले के लिए अलग शीर्षक और अक्ष पाठ आकार होना चाहिए, लेकिन ऐसा नहीं करता एक सामान्य कोड खंड मैं केवल यह मान सकता हूं कि इसमें कुछ सीधी समस्या है जिस तरह से मैं कॉल कर रहा हूं या शायद उस समस्या को ताज़ा कर रहा हूं जो समस्या पैदा कर रहा है। किसी भी मदद की बहुत सराहना की।

मैंने पहले आर में नामित फ़ंक्शंस का उपयोग नहीं किया है और मैं पेशेवर के बजाए एक आकस्मिक प्रोग्रामर हूं, इसलिए नीचे डोडी कोड के लिए अग्रिम क्षमा करें।

# 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' उपलब्ध का मूल्य है कि बाद में उपयोग करेगा, पिछले करने के लिए इसी itera लूप का टयन। निम्नलिखित समस्या दिखाता है: 'प्राप्त करें ("आकार", envir = पर्यावरण (myplots [[1]] $ विकल्प $ plot.title)) '(यह 16 होना चाहिए, 28 नहीं)। कहीं 'बल' जोड़ना, या कोड बदलना ताकि प्रत्येक पुनरावृत्ति का अपना पर्यावरण हो, समस्या को ठीक कर सकता है। –

+0

जब मैं इस लूप इन-लाइन का उपयोग करता हूं तो मेरे पास लूप के अंत में एक प्रिंट स्टेटमेंट होता है और शायद यह बल मूल्यांकन करता है, जो संभवतः यह क्यों काम करता है? इसके लिए शुक्रिया। मेरे पास इस तरह का विचार था कि आलसी मूल्यांकन काफी हद तक सैद्धांतिक समस्या थी लेकिन स्पष्ट रूप से नहीं! – 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 और फोंटसाइज दोनों को स्वतंत्र रूप से बदलने के लिए प्राप्त कर सकता हूं, लेकिन दूसरे चार्ट में शीर्षकबद्धता लगातार झुकाव से इनकार कर रही है। मैंने दूसरे प्रिंट में स्टेटमेंट को 'टाइटलस्लाइज' असाइनमेंट को लपेटने की कोशिश की, अगर इस प्रिंट को प्रिंट करने के लिए मजबूर करने के लिए 'प्रिंट (टाइटलस्लाइज़ <- 28)' जैसे अपने प्रिंट स्टेटमेंट में स्टेटमेंट को बिना किसी ध्यान देने योग्य प्रभाव के। असाइनमेंट स्पष्ट रूप से काम कर रहा है, इसलिए मुझे नुकसान हुआ है। क्या यह एक आलसी मूल्यांकन भी हो सकता है; हड्डी-निष्क्रिय मूल्यांकन, शायद? जो भी हो, मैं अभी भी पहेली का हिस्सा गायब प्रतीत होता हूं। – SlowLearner

+0

मैंने इसे एक सूची के बजाय साजिश वापस करने के लिए संशोधित किया, और मैंने प्लॉट सृजन के बाद डिवाइस प्लॉटिंग कॉल को ठीक कर दिया ताकि सब कुछ अनुक्रम में मूल्यांकन हो। ऊपर संपादित कोड। –

+0

आखिर में सफलता - शैक्षिक भी पोर पर भी। शायद आपको सामान्य घंटों के बाहर समाधान के लिए एक अतिरिक्त बिंदु भी देना चाहिए! बहुत धन्यवाद। – SlowLearner

संबंधित मुद्दे