2015-01-08 97 views
4

我試圖創建一個標籤堆疊的條形圖,其中只有1條。我的堆棧並不總是足夠大,無法放入文本,所以我想要將標記指向堆棧右側的標籤,以找出無法放入堆棧的標籤。或者,如果所有標籤都位於帶引線的堆棧的右側,則可以。ggplot2與領導線疊加的條形圖標籤

我data.frame看起來是這樣的:

Regional.District Municipality Population.2010  mp 
Metro    Bowen Island   3678 1839.0 
Metro     Coquitlam   126594 66975.0 
Metro      Delta   100000 180272.0 
Metro    Langley City   25858 243201.0 
Metro    Maple Ridge   76418 294339.0 
Metro     New West   66892 365994.0 
Metro  North Vancouver (City)   50725 424802.5 
Metro    Port Coquitlam   57431 478880.5 
Metro     Port Moody   33933 524562.5 
Metro      Surrey   462345 772701.5 
Metro    West Vancouver   44058 1025903.0 
Metro     White Rock   19278 1057571.0 
Metro      Anmore   2203 1068311.5 
Metro     Belcarra    690 1069758.0 
Metro     Burnaby   227389 1183797.5 
Metro    Langley (Town)   104697 1349840.5 
Metro     Lions Bay   1395 1402886.5 
Metro  Metro Vancouver-uninc   24837 1416002.5 
Metro North Vancouver (District)   88370 1472606.0 
Metro    Pitt Meadows   18136 1525859.0 
Metro     Richmond   196858 1633356.0 
Metro   Vancouver (City)   642843 2053206.5 

這是我目前有工作: current bar chart

這是我想要得到什麼工作: potential future bar chart

這是我的代碼:

library(ggplot2) 
ggplot(muns, aes(x = Regional.District, y = Population.2010, fill = Municipality)) + 
    geom_bar(stat = 'identity', colour = 'gray32', width = 0.6, show_guide = FALSE) + 
    geom_text(aes(y = muns$mp, label = muns$Municipality), colour = 'gray32') 

這是可能的自動化?我沒有使用ggplot2來完成這件事。 謝謝!

回答

4

這是一種可能性。我認爲這項工作確實需要一些手動工作,儘管你可以自動化一些過程。我最初調查了哪些標籤必須留在酒吧外面。然後,我看到一些標籤重疊在一起。我的解決方案是移動欄左側的一些標籤。 Anmore是一個棘手的。我手動將其y位置稍微偏移一點,以便它不會與White Rock重疊。

gg1是基本圖形。酒吧內有標籤。創建gg2以獲取應該添加在條右側的標籤。在dan中,我研究了ggplots使用和修改x值的數據(即x = 1.35)。我也在這裏刪除了三個地方。在emodan2的三個地方也做了類似的工作。在gg3中,我添加了標籤。最後的工作是添加細分。我創建了三個新的數據框來繪製段。

library(dplyr) # I use the dev version (dplyr 0.4) 
library(ggplot2) 

# as_data_frame() is available in dplyr 0.4 
mydf <- as_data_frame(list(Regional.District = rep("Metro", times = 22), 
          Municipality = c("Bowen Island", "Coquitlam", "Delta", 
              "Langley City", "Maple Ridge", "New West", 
              "North Vancouver (City)", "Port Coquitlam", "Port Moody", 
              "Surrey", "West Vancouver", "White Rock", 
              "Anmore", "Belcarra", "Burnaby", "Langley (Town)", 
              "Lions Bay", "Metro Vancouver-uninc", 
              "North Vancouver (District)", "Pitt Meadows", 
              "Richmond", "Vancouver (City)"), 
          Population = c(3678, 126594, 100000, 25858, 76418, 66892, 50725, 
              57431, 33933, 462345, 44058, 19278, 2203, 690, 
              227389, 104697, 1395, 24837, 88370, 18136, 196858, 
              642843), 
          mp = c(1839.0, 66975.0, 180272.0, 243201.0, 294339.0, 365994.0, 
            424802.5, 478880.5, 524562.5, 772701.5, 1025903.0, 1057571.0, 
            1068311.5, 1069758.0, 1183797.5, 1349840.5, 1402886.5, 1416002.5, 
            1472606.0, 1525859.0, 1633356.0, 2053206.5))) 


# Get label for places which has more than or less than 60,000 people 

ana <- mutate(mydf, foo = ifelse(Population > 60000, Municipality, NA)) 
bob <- mutate(mydf, foo = ifelse(Population > 60000, NA, Municipality)) 


# Plot with places which have more than 60,000 people 
gg1 <- ggplot(mydf, aes(x = Regional.District, y = Population, fill = Municipality)) + 
     geom_bar(stat = "identity", colour = "gray32", width = 0.4, show_guide = FALSE) + 
     geom_text(aes(y = ana$mp, label = ana$foo), colour = "gray32", size = 3) 

# Plot with places which have less than 60,000 people 
gg2 <- ggplot(mydf, aes(x = Regional.District, y = Population, fill = Municipality)) + 
     geom_bar(stat = "identity", colour = "gray32", width = 0.4, show_guide = FALSE) + 
     geom_text(aes(y = bob$mp, label = bob$foo), colour = "gray32") 

# Label for right 
dan <- na.omit(ggplot_build(gg2)$data[[2]]) %>% 
     filter(!label %in% c("Belcarra", "Metro Vancouver-uninc", "Anmore")) %>% 
     mutate(x = 1.35) 

# Label for left 
emo <- filter(ggplot_build(gg2)$data[[2]], 
       label %in% c("Belcarra", "Metro Vancouver-uninc")) %>% 
     mutate(x = 0.65) 

# Special label for right 
dan2 <- filter(ggplot_build(gg2)$data[[2]], label == "Anmore") %>% 
     mutate(x = 1.35, y = 1098312) 

# Add labels 
gg3 <- gg1 + 
     annotate("text", x = dan$x, y = dan$y, label = dan$label, colour = "gray32", size = 3) + 
     annotate("text", x = emo$x, y = emo$y, label = emo$label, colour = "gray32", size = 3) + 
     annotate("text", x = dan2$x, y = dan2$y, label = dan2$label, colour = "gray32", size = 3) 


# Create data frames for segments 
# right seg 
r.seg <- data.frame(x = rep(1.2, times = 9), 
        xend = rep(1.25, times = 9), 
        y = dan$y, 
        yend = dan$y) 

# left seg 
l.seg <- data.frame(x = rep(0.76, times = 2), 
        xend = rep(0.8, times = 2), 
        y = emo$y, 
        yend = emo$y) 

# Anmore seg 
a.seg <- data.frame(x = 1.2, 
        xend = 1.25, 
        y = 1068312, 
        yend = dan2$y) 

# Draw the segments           
gg3 + 
annotate("segment", x = r.seg$x, xend = r.seg$xend, y = r.seg$y, yend = r.seg$yend) + 
annotate("segment", x = l.seg$x, xend = l.seg$xend, y = l.seg$y, yend = l.seg$yend) + 
annotate("segment", x = a.seg$x, xend = a.seg$xend, y = a.seg$y, yend = a.seg$yend) 

enter image description here

+0

那太好了,謝謝! – hailes

+0

@hailes歡迎您。 :) – jazzurro