2014-10-22 6 views
41

मेरे पास एक ऐसा फ़ंक्शन है जो एक ggplot ऑब्जेक्ट में हेरफेर करता है, इसे एक ग्रोब में परिवर्तित करके और परतों को संशोधित करके। मैं फ़ंक्शन को एक ggplot ऑब्जेक्ट को वापस करने के लिए नहीं चाहता हूं। क्या ग्रोब को वापस जीजी में परिवर्तित करने का कोई आसान तरीका है?ggplotGrob के विपरीत?

The documentationggplotGrob पर बहुत ही विचित्र है।
सरल उदाहरण:

P <- ggplot(iris) + geom_bar(aes(x=Species, y=Petal.Width), stat="identity") 

G <- ggplotGrob(P) 
... some manipulation to G ... 

## DESIRED: 
P2 <- inverse_of_ggplotGrob(G) 

such that, we can continue to use basic ggplot syntax, ie 
`P2 + ylab ("The Width of the Petal")` 

अद्यतन:

टिप्पणी में सवाल का जवाब करने के लिए, प्रेरणा यहाँ में लेबल नाम के मूल्य पर आधारित, प्रोग्राम के रूप में पहलू लेबल के रंग को संशोधित करने के लिए है प्रत्येक पहलू नीचे दिए गए कार्य अच्छी तरह से काम करते हैं (पिछले प्रश्न में बपतिस्मा से इनपुट के आधार पर)।

मैं colorByGroup से वापसी मूल्य के लिए एक ggplot ऑब्जेक्ट होने के लिए, केवल एक ग्रोब नहीं चाहता हूं।

यहाँ उन दिलचस्पी

get_grob_strips <- function(G, strips=grep(pattern="strip.*", G$layout$name)) { 

    if (inherits(G, "gg")) 
    G <- ggplotGrob(G) 
    if (!inherits(G, "gtable")) 
    stop ("G must be a gtable object or a gg object") 

    strip.type <- G$layout[strips, "name"] 
    ## I know this works for a simple 
    strip.nms <- sapply(strips, function(i) { 
    attributes(G$grobs[[i]]$width$arg1)$data[[1]][["label"]] 
    }) 

    data.table(grob_index=strips, type=strip.type, group=strip.nms) 
} 


refill <- function(strip, colour){ 
    strip[["children"]][[1]][["gp"]][["fill"]] <- colour 
    return(strip) 
} 

colorByGroup <- function(P, colors, showWarnings=TRUE) { 
## The names of colors should match to the groups in facet 
    G <- ggplotGrob(P) 
    DT.strips <- get_grob_strips(G) 

    groups <- names(colors) 
    if (is.null(groups) || !is.character(groups)) { 
    groups <- unique(DT.strips$group) 
    if (length(colors) < length(groups)) 
     stop ("not enough colors specified") 
    colors <- colors[seq(groups)] 
    names(colors) <- groups 
    } 


    ## 'groups' should match the 'group' in DT.strips, which came from the facet_name 
    matched_groups <- intersect(groups, DT.strips$group) 
    if (!length(matched_groups)) 
    stop ("no groups match") 
    if (showWarnings) { 
     if (length(wh <- setdiff(groups, DT.strips$group))) 
     warning ("values in 'groups' but not a facet label: \n", paste(wh, colapse=", ")) 
     if (length(wh <- setdiff(DT.strips$group, groups))) 
     warning ("values in facet label but not in 'groups': \n", paste(wh, colapse=", ")) 
    } 

    ## identify the indecies to the grob and the appropriate color 
    DT.strips[, color := colors[group]] 
    inds <- DT.strips[!is.na(color), grob_index] 
    cols <- DT.strips[!is.na(color), color] 

    ## Fill in the appropriate colors, using refill() 
    G$grobs[inds] <- mapply(refill, strip = G$grobs[inds], colour = cols, SIMPLIFY = FALSE) 

    G 
} 

उत्तर

8

मैं कहूंगा कि कोई के लिए, कोड है। ggplotGrob एक तरफा सड़क है। grob वस्तुओं ग्रिड द्वारा परिभाषित primitives ड्राइंग कर रहे हैं। आप खरोंच से मनमाना grobs बना सकते हैं। ग्रॉब्स के यादृच्छिक संग्रह को उस फ़ंक्शन में वापस करने का कोई सामान्य तरीका नहीं है जो उन्हें उत्पन्न करेगा (यह अचूक नहीं है क्योंकि यह 1: 1 नहीं है)। एक बार जब आप ग्रोब जाते हैं, तो आप कभी वापस नहीं जाते।

आप एक कस्टम वर्ग में एक ggplot ऑब्जेक्ट लपेट सकते हैं और कुछ कस्टम ग्रोब हेरफेर करने के लिए साजिश/प्रिंट कमांड को अधिभारित कर सकते हैं, लेकिन शायद यह और भी हैक-आश है।

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