2012-05-10 20 views
24

मैं ggplot2 के साथ इस साजिश बनाया:ggplot2 में साजिश क्षेत्र के बाहर लाइनों को कैसे आकर्षित करें?

enter image description here

बाहर लाइनों Y पैमाने पर, (यानी पाठ 1 के लिए लाइनों की Y स्थिति 100 और 85 होना चाहिए) के अनुरूप करने की जरूरत है। एकमात्र तरीका मैं आंकड़े के दाईं ओर एक रिक्त साजिश खींचकर ब्रैचर्ट के समान पैमाने पर और फिर लाइनों को आकर्षित करने के लिए एनोटेट फ़ंक्शन का उपयोग करके कर सकता हूं। एक और तरीका है कि grid.lines के साथ लाइनों को "मैन्युअल रूप से" खींचें, हालांकि grid.lines के निर्देशांक साजिश के वाई पैमाने के अनुरूप नहीं होंगे।

क्या किसी भी तरह से एक अलग दृष्टिकोण का उपयोग करके इन लाइनों को आकर्षित करना संभव है? मुझे लगता है कि इसे grid.lines के साथ किया जाना होगा। मैं grid.lines पर ब्रैरर्ट के वाई निर्देशांक कैसे पास कर सकता हूं?

library (ggplot2) 
test= data.frame(
    group=c(rep(1,6), rep(2,6)), 
    subgroup=c(1,1,1,2,2,2,1,1,1,2,2,2), 
    category=c(rep(1:3, 4)), 
    count=c(10,80,10,5,90,5, 10,80,10,5,90,5 ) 
) 

qplot(subgroup, 
     count, 
     data=test, 
     geom="bar", 
     stat="identity", 
     fill =category, 
     facets = .~ group, width=0.9)+ 
     opts(legend.position="none", 
      plot.margin = unit(c(0,9,2,0), "lines")) 

enter image description here

मैं सलाखों के अधिकार के लिए लाइनों कैसे आकर्षित कर सकते हैं:

नीचे कम से कम कोड यह आंकड़ा बनाने के लिए प्रयोग किया जाता है?

मैं हाल ही में ggplot2 में साजिश क्षेत्र के बाहर पाठ ड्राइंग के बारे में प्रश्न पूछा और समाधान gt$layout और grid.draw उपयोग करने के लिए किया गया था।

Displaying text below the plot generated by ggplot2

समान दृष्टिकोण यहां इस्तेमाल किया जा सकता है? यह मेरी समझ है कि annotation_custom केवल पाठ के लिए है और अन्य ग्राफिकल तत्वों के साथ काम नहीं करेगा। धन्यवाद

उत्तर

20

अद्यतन

मूल समाधान annotation_custom इस्तेमाल किया, लेकिन annotation_custom के साथ एक समस्या यह है कि यह सभी पैनलों में एनोटेशन खींचता है। हालांकि, एक सरल संशोधन के साथ, annotation_custom एक पैनल केवल (बैप्टिस्ट के जवाब here से लिया)

annotation_custom2 <- 
function (grob, xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf, data) 
{ 
    layer(data = data, stat = StatIdentity, position = PositionIdentity, 
     geom = ggplot2:::GeomCustomAnn, 
     inherit.aes = TRUE, params = list(grob = grob, 
              xmin = xmin, xmax = xmax, 
              ymin = ymin, ymax = ymax)) 
} 

library(ggplot2) 
library(grid) 

#Some data 
test = data.frame(
    group=c(rep(1,6), rep(2,6)), 
    subgroup=c(1,1,1,2,2,2,1,1,1,2,2,2), 
    category=c(rep(1:3, 4)), 
    count=c(10,80,10,5,90,5, 10,80,10,5,90,5 ) 
) 

# base plot 
p <- ggplot(test) + 
    geom_bar(aes(subgroup, count, fill = category), stat = "identity") + 
    facet_grid(. ~ group) + 
    theme(legend.position = "none", 
     plot.margin = unit(c(1,5,1,1), "lines")) 

# Create the text Grobs 
Text1 = textGrob("Text 1") 
Text2 = textGrob("Text 2") 
Text4 = textGrob("Text 4") 

## Add the annotations 
# Which panel to attach the annotations 
data = data.frame(group=2) 

# Text 1 
p1 = p + annotation_custom2(Text1, xmin = 3., xmax = 3., ymin = 85, ymax = 100, data = data) + 
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 100, ymax = 100, data = data) + 
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 85, ymax = 85, data = data) + 
    annotation_custom2(linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 85, ymax = 100, data = data) 

# Text 2 
p1 = p1 + annotation_custom2(Text2, xmin = 3, xmax = 3, ymin = 20, ymax = 80, data = data) + 
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 80, ymax = 80, data = data) + 
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 20, ymax = 20, data = data) + 
    annotation_custom2(linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 20, ymax = 80, data = data) 

# Text 4 
p1 = p1 + annotation_custom2(Text4, xmin = 3, xmax = 3, ymin = 0, ymax = 15, data = data) + 
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 15, ymax = 15, data = data) + 
    annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 0, ymax = 0, data = data) + 
    annotation_custom2(linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 0, ymax = 15, data = data) 


# Code to override clipping 
gt <- ggplotGrob(p1) 
gt$layout[grepl("panel", gt$layout$name), ]$clip <- "off" 

# Draw the plot 
grid.newpage() 
grid.draw(gt) 

मूल समाधान में आकर्षित करने के लिए

मुझे लगता है कि लगभग किसी भी Grob grid() का उपयोग कर बनाई इस्तेमाल किया जा सकता बनाया जा सकता है annotation_custom() में। ऐसा करने के लिए साफ-सुथरा तरीके हो सकते हैं, लेकिन क्लिपिंग को ओवरराइड करने के लिए grid, annotation_custom और @ बपतिस्मा कोड from here का उपयोग करने का एक तरीका यहां है (जैसा कि पहले की पोस्ट में था)। Using grconvertX/grconvertY in ggplot2:

library (ggplot2) 
library(grid) 

test= data.frame(
    group=c(rep(1,6), rep(2,6)), 
    subgroup=c(1,1,1,2,2,2,1,1,1,2,2,2), 
    category=c(rep(1:3, 4)), 
    count=c(10,80,10,5,90,5, 10,80,10,5,90,5 ) 
) 

## EDIT: Updated qplot() command 
p <- qplot(subgroup, count, 
    data = test, geom = "bar", stat = "identity", 
    fill = category, 
    facets = .~ group, width = 0.9)+ 
    theme(legend.position="none", plot.margin = unit(c(0,9,2,0), "lines")) 



# Create the text Grobs 
Text1 = textGrob("Text 1") 
Text2 = textGrob("Text 2") 
Text4 = textGrob("Text 4") 

# Draw the plot 
# Text 1 
p1 = p + annotation_custom(grob = Text1, xmin = 3., xmax = 3., ymin = 85, ymax = 100) + 
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 100, ymax = 100) + 
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 85, ymax = 85) + 
    annotation_custom(grob = linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 85, ymax = 100) 

# Text 2 
p1 = p1 + annotation_custom(grob = Text2, xmin = 3, xmax = 3, ymin = 20, ymax = 80) + 
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 80, ymax = 80) + 
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 20, ymax = 20) + 
    annotation_custom(grob = linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 20, ymax = 80) 

# Text 4 
p1 = p1 + annotation_custom(grob = Text4, xmin = 3, xmax = 3, ymin = 0, ymax = 15) + 
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 15, ymax = 15) + 
    annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 0, ymax = 0) + 
    annotation_custom(grob = linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 0, ymax = 15) 

p1 

# Code to override clipping 
gt <- ggplot_gtable(ggplot_build(p1)) 
gt$layout$clip[gt$layout$name=="panel"] <- "off" 
grid.draw(gt) 

enter image description here

+0

सैंडी : फिर से धन्यवाद !!! मैंने माना कि पाठ प्रश्न में चाल केवल पाठ के साथ काम करती है। यह बहुत मदद करता है। –

+1

@ मैक्स चेर्नी, एक 'पॉलीलाइनग्राब' भी है जो कोड को थोड़ा अधिक कुशल बनाना चाहिए। –

+1

सावधानी बरतें : विधि दोनों पहलुओं में grobs आकर्षित करेगा। कोशिश करें: 'पी + annotation_custom (grob = textGrob (" कहीं भी पाठ "), xmin = 1.5, xmax = 1.5, ymin = 50, ymax = 50) ' –

5

मैं इस लिंक से लाइनों/पाठ का उपयोग कर कोड गयी। यह दृष्टिकोण grobs के बजाय grid.text और grid.lines का उपयोग करता है। मुझे यकीन नहीं है कि कौन सा दृष्टिकोण बेहतर है।

मुझे लगता है कि ग्रिड.लाइन को ग्रिड.polyline कथन में जोड़ा जा सकता है या संभवतः लूप के माध्यम से किया जा सकता है।एक्स और वाई पदों को प्रत्येक पंक्ति में हार्डकोडिंग के बजाय एक चर पर सेट किया जा सकता है।

एकमात्र संभावित जटिलता व्यूपोर्ट के पैमाने को पार कर रही है। हालांकि, जब तक जीजीपीएलओटी में समान पैमाने का उपयोग किया जाता है और व्यूपोर्ट को इस कोड को काम करना चाहिए। ध्यान दें कि व्यूपोर्ट किसी फ़ॉरमेट समस्याओं के लिए 100.

library (ggplot2) 
library(grid) 
library(gridBase) 

test= data.frame(
    group=c(rep(1,6), rep(2,6)), 
    subgroup=c(1,1,1,2,2,2,1,1,1,2,2,2), 
    category=c(rep(1:3, 4)), 
    count=c(10,80,10,5,90,5, 10,80,10,5,90,5 ) 
) 

qplot(subgroup, count, 
      data=test, geom="bar", stat="identity", 
      fill =category, 
      facets = .~ group, width=0.9)+ 
      opts(legend.position="none", plot.margin = unit(c(0,9,2,0), "lines")) 

current.vpTree() 
downViewport('panel-4-6') 
pushViewport(dataViewport(yscale=c(0,100), clip='off',xscale=c(0,1))) 

grid.text(x=1.21, y = 90, default.units='native' ,label="Text 1") 
grid.text(x=1.21, y = 55, default.units='native' ,label="Text 2") 
grid.text(x=1.21, y = 10, default.units='native' ,label="Text 3") 

grid.lines(x=c(1.02,1.12), y = c(95,95), default.units='native') 
grid.lines(x=c(1.02,1.12), y = c(85, 85), default.units='native') 
grid.lines(x=c(1.12,1.12), y = c(85, 95), default.units='native') 

grid.lines(x=c(1.02,1.12), y = c(80, 80), default.units='native') 
grid.lines(x=c(1.02,1.12), y = c(20, 20), default.units='native') 
grid.lines(x=c(1.12,1.12), y = c(80, 20), default.units='native') 

grid.lines(x=c(1.02,1.12), y = c(5, 5), default.units='native') 
grid.lines(x=c(1.02,1.12), y = c(15, 15), default.units='native') 
grid.lines(x=c(1.12,1.12), y = c(5, 15), default.units='native') 

क्षमा याचना करने के लिए 0 के रूप में साजिश की पूरी ऊंचाई उपयोग कर रहा है - मैं बस अपना कोड चिपकाया और यह इंडेंट करने के लिए कोड बटन का इस्तेमाल किया।

enter image description here

+1

यदि आप y-axis पर पैडिंग को हटाते हैं 'scale_y_continuous के साथ (विस्तार = सी (0, 0))' तो पैमाने सही लगता है। –

+0

सैंडी: मैं अपने मूल आकृति (नकली नहीं) पर लागू होने पर ग्रब्स के साथ आपका समाधान बेहतर काम करता था। ग्रॉब्स सलाखों की वास्तविक ऊंचाई को पुनः प्राप्त करते हैं, जबकि ग्रिड.लाइन/टेक्स्ट को समायोजित किया जाना चाहिए। मैंने दोनों दृष्टिकोणों की कोशिश की और तुम्हारा बहुत बेहतर है। बहुत बहुत धन्यवाद! –

5

अपडेट किया गयाopts पदावनत किया गया है; इसके बजाय theme का उपयोग करें।

यहां एक और समाधान है। यह दोनों पैनलों में annotation_custom() ड्राइंग ग्रॉब्स की समस्या के दौर में आता है। यह दो ग्राफ खींचता है: पहला आपकी बार साजिश है; दूसरे में केवल एनोटेशन हैं। फिर दोनों को gridExtra पैकेज से एक साथ रखा जाता है। हालांकि, आपकी पॉलीलाइन समस्या बनी हुई है।

अभी भी दो भूखंडों में वाई-अक्ष स्केल प्राप्त करने का मुद्दा अभी भी है। लेकिन देखभाल के साथ, यह किया जा सकता है। भूखंड कि annnotations होता है, ध्यान दें कि किस तत्व कि y- अक्ष पैमाने पर एक प्रभाव हो सकता निकाल दिए जाते हैं नहीं (theme_blank() के माध्यम से, बल्कि (colour = NA का प्रयोग करके) छिपे हुए हैं।

library(ggplot2) 
library(gridExtra) 
library(grid) 

test= data.frame(
    group=c(rep(1,6), rep(2,6)), 
    subgroup=c(1,1,1,2,2,2,1,1,1,2,2,2), 
    category=c(rep(1:3, 4)), 
    count=c(10,80,10,5,90,5, 10,80,10,5,90,5)) 

# The bar plot 
p1 <- ggplot(test, aes(subgroup, count, fill = category)) + 
    geom_bar(stat = "identity") + 
    facet_grid(.~ group) + 
    theme(legend.position = "none", 
     plot.margin = unit(c(1,0,2,0), "lines")) 

p1 <- p1 + ylim(0, 100) 

# The empty plot to contain the annotations 
p2 = ggplot(data.frame(x = c(1,2), y = c(0,100), z = c(1,1)), aes(x,y)) + theme_bw() + facet_wrap(~ z) + 
    theme(axis.title.y = element_blank(), 
     axis.title.x = element_text(colour = NA), 
     axis.text.y = element_blank(), 
     axis.text.x = element_text(colour = NA), 
     panel.grid.major = element_blank(), 
     panel.grid.minor = element_blank(), 
     axis.ticks = element_line(colour = NA), 
     panel.border = element_rect(colour = NA), 
     strip.background = element_rect(colour = NA, fill = NA), 
     strip.text.x = element_text(colour = NA), 
     plot.margin = unit(c(1,0,2,0), "lines")) 


# The annotations 
Text1 = textGrob("Text 1") 
Text2 = textGrob("Text 2") 
Text4 = textGrob("Text 4") 

p2 = p2 + annotation_custom(grob = Text1, xmin = 1.4, xmax = 1.4, ymin = 85, ymax = 100) + 
     annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 100, ymax = 100) + 
     annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 85, ymax = 85) + 
     annotation_custom(grob = linesGrob(), xmin = 1.1, xmax = 1.1, ymin = 85, ymax = 100) 

p2 = p2 + annotation_custom(grob = Text2, xmin = 1.4, xmax = 1.4, ymin = 20, ymax = 80) + 
     annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 80, ymax = 80) + 
     annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 20, ymax = 20) + 
     annotation_custom(grob = linesGrob(), xmin = 1.1, xmax = 1.1, ymin = 20, ymax = 80) 

p2 = p2 + annotation_custom(grob = Text4, xmin = 1.4, xmax = 1.4, ymin = 0, ymax = 15) + 
     annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 15, ymax = 15) + 
     annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 0, ymax = 0) + 
     annotation_custom(grob = linesGrob(), xmin = 1.1, xmax = 1.1, ymin = 0, ymax = 15) 

# Putting the two plots together 
plot = arrangeGrob(p1, p2, ncol = 2, widths = unit(c(10, 2), c("null", "null"))) 
grid.draw(plot) 

bot

+0

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

+0

इस बिंदु पर, यह नहीं लगता कि GGPLOT को एनोटेट करने का एक आसान तरीका है। यह निश्चित रूप से किया जा सकता है लेकिन यह एसएएस डेटा एनाटेट सुविधा या बेस आर कार्यों के साथ आसान नहीं है। –

+0

क्या आपने अपना प्रश्न [ggplot2 मेलिंग सूची] (http://had.co.nz/ggplot2/) पर ले जाने पर विचार किया है? –

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