2015-01-08 5 views
4

레이블이 하나만있는 곳에 차트가있는 누적 막 대형 차트를 만들려고합니다. 내 스택은 항상 텍스트에 맞게 충분히 클 수는 없으므로 스택에 들어 가지 않는 레이블의 스택 오른쪽에있는 레이블을 가리키는 지시선을 사용하고 싶습니다. 또는 모든 레이블이 모두 지시선이있는 스택의 오른쪽에 있으면 괜찮습니다.ggplot2 안내선이있는 막대 차트 레이블

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 

이 내가 현재 작업이 무엇 :

내 data.frame는 다음과 같이 보이는 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은 까다로운 문제였습니다. 나는 White Rock과 겹쳐지지 않도록 수동으로 y 위치를 약간 높게 이동했습니다.

gg1은 기본 그래픽입니다. 막대 안에 라벨이 있습니다. gg2은 바의 오른쪽에 추가되어야하는 레이블을 얻기 위해 생성됩니다. dan에서 ggplots이 사용하고 x 값 (즉, x = 1.35)을 수정 한 데이터를 살펴 보았습니다. 나는 또한 여기에서 3 개의 장소를 삭제했다. 유사한 작업은 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