2013-11-21 20 views
14

yılında, etiketli satırlar ve sütunlar ile, dikdörtgen bir efsaneyi yapın:Bunun gibi, ben dolgu ve alfa hem haritalama faktörleri olduğum bir ggplot var ızgara

set.seed(47) 
the_data <- data.frame(value = rpois(6, lambda=20), 
         cat1 = rep(c("A", "B"), each = 3), 
         cat2 = rep(c("X", "Y", "Z"), 2)) 

ggplot(the_data, aes(y = value, x = cat2, alpha = cat1, fill = cat2)) + 
    geom_bar(stat = "identity", position = "dodge") + 
    scale_alpha_discrete(range = c(0.5, 1)) + 
    theme_bw() 

enter image description here

Ben bunu üretmek için aldığım insanlar alfa efsanesi çok net değil. Ben iyi bir alternatif (ı baz grafikleri bir araya kesmek) böyle bir şey olacağını düşünüyorum: Ben üst düzey ggplot komutlarla böyle bir efsane üretemez biliyorum

enter image description here

ama elimden grid içinde yap ve onu arsa üstüne koydu?

+2

sadece iki kere kullanmak en hızlı çözüm olabilir ** Kafes** arsa ve efsanesi için ayrı bölgeler ayırmak için viewports, daha sonra el yapımı efsaneyi üst vitrininize yerleştirmek için ** gridBase ** paketini kullanın. ('vignette (" gridBase ")' bir intro verir veya "[r] gridBase" için daha fazla örnek için SO üzerinde arama yapar.) –

+0

@ JoshO'Brien "gridBase" hakkında bilgi sahibi olmadı, işaretçi için teşekkürler! – Gregor

+0

Evet, bazen çok kullanışlı geliyor. [Burada] (http://stackoverflow.com/questions/11489447/combining-two-plots-in-r/11496362#11496362) ve [burada] (http://stackoverflow.com/questions/9985013/how-do -you-draw-a-line-genelinde-çok-rakam-ortam-in-r/9985936 # 9985936), aksi takdirde zor etkileri gerçekleştirmek için kullandım birkaç yer vardır. –

cevap

14

İşte olası bir başlangıç ​​noktası. Uygun efsanelere sahip iki farklı çizim oluşturuyorum - 'parlak' ve 'solgun'. Efsaneleri çizim nesnelerinden çıkarın. Ardından parçaları bir araya getirmek için, bir arsa için gridviewport s kullanın ve her bir efsane için bir tane kullanın.

library(grid) 
library(gtable) 

# create plot with legend with alpha = 1 
g1 <- ggplot(the_data, aes(y = value, x = cat2, alpha = cat1, fill = cat2)) + 
    geom_bar(stat = "identity", position = "dodge") + 
    scale_alpha_discrete(range = c(0.5, 1)) + 
    theme_bw() + 
    guides(fill = guide_legend(title = "A", 
          title.hjust = 0.4), 
     alpha = FALSE) + 
    theme_bw() + 
    theme(legend.text = element_blank()) 

g1 

# grab legend 
legend_g1 <- gtable_filter(ggplot_gtable(ggplot_build(g1)), "guide-box") 


# create plot with 'pale' legend 
g2 <- ggplot(the_data, aes(y = value, x = cat2, alpha = cat1, fill = cat2)) + 
    geom_bar(stat = "identity", position = "dodge") + 
    scale_alpha_discrete(range = c(0.5, 1)) + 
    guides(fill = guide_legend(override.aes = list(alpha = 0.5), 
          title = "B", 
          title.hjust = 0.3), 
     alpha = FALSE) + 
    theme_bw() 
g2 

# grab legend 
legend_g2 <- gtable_filter(ggplot_gtable(ggplot_build(g2)), "guide-box") 



# arrange plot and legends 

# legends to the right 

# define plotting regions (viewports) 
vp_plot <- viewport(x = 0.4, y = 0.5, 
        width = 0.8, height = 1) 

vp_legend_g1 <- viewport(x = 0.85, y = 0.5, 
          width = 0.4, height = 0.4) 

vp_legend_g2 <- viewport(x = 0.90, y = 0.5, 
          width = 0.4, height = 0.4) 


# clear current device 
grid.newpage() 

# add objects to the viewports 
# plot without legend 
print(g1 + theme(legend.position = "none"), vp = vp_plot) 
upViewport(0) 

pushViewport(vp_legend_g1) 
grid.draw(legend_g1) 
upViewport(0) 

pushViewport(vp_legend_g2) 
grid.draw(legend_g2) 

enter image description here

# legends on top 
vp_plot <- viewport(x = 0.5, y = 0.4, 
        width = 1, height = 0.85) 

vp_legend_g1 <- viewport(x = 0.5, y = 0.9, 
         width = 0.4, height = 0.4) 

vp_legend_g2 <- viewport(x = 0.55, y = 0.9, 
         width = 0.4, height = 0.4) 

grid.newpage() 

print(g1 + theme(legend.position = "none"), vp = vp_plot) 
upViewport(0) 

pushViewport(vp_legend_g1) 
grid.draw(legend_g1) 
upViewport(0) 

pushViewport(vp_legend_g2) 
grid.draw(legend_g2) 

enter image description here

+1

Her şeyden sonra size kesinlikle bir oy vermem gerekiyor, ancak Josh'un stratejisi artık daha uygun görünüyor. –

+0

Bu güzel! Sağol Henrik. – Gregor

4

@Henrik

Bu biraz daha kolay olabilir

,

g1 <- ggplotGrob(p1) 
g2 <- ggplotGrob(p2) 

leg1 <- gtable_filter(g1, "guide-box") 
leg2 <- gtable_filter(g2, "guide-box") 
leg <- gtable:::cbind_gtable(leg1[["grobs"]][[1]], leg2[["grobs"]][[1]], "first") 

g1$grobs[g1$layout$name == "guide-box"][[1]] <- leg 
g1$widths[max(subset(g1$layout, name == "guide-box")[["r"]])] <- list(leg1$width + leg2$width) 

grid.newpage() 
grid.draw(g1) 
İlgili konular