2016-06-23 71 views
0

我創建了此圖表。標籤佔用太多空間,很難看到哪個狀態是哪個。所以我想用圖形中的狀態代碼標籤或波紋管代替圖例。是否有捷徑可尋?用多級ggplot2圖中的標籤替換圖例

圖: enter image description here

代碼生成它:

url <- 'https://www.dropbox.com/s/f046jroutvt8ctk/SO_example_data_put_labels_in_graph.csv?raw=1' 
d <- read_csv(url) 

d %>% 
    ggplot(aes(x=popNb,y=tx_atendimento)) + 
    geom_rect(aes(xmin=pop1b,xmax=popNb, 
       ymin=tx0,ymax=tx_atendimento, 
       fill=UF)) + 
    geom_segment(aes(x=pop1b,xend=popNb, 
        y=tx_atendimento_UF,yend=tx_atendimento_UF)) + 
    theme(legend.position = "bottom", legend.direction = "horizontal") + 
    ggtitle('Daycare provision rate per state and municipality in Brazil (2014)') + 
    ggsave('plot_rec_bar_needs_labels.png') 

說明:

請注意,這不是一個正常的柱狀圖。每個自治市(數據集中的行)都由一個矩形表示,其寬度與該年齡和身高相應於規定率的子女人數相對應。我創建了x值,所以市政府首先按照州內的平均供應率(UF)排列,其次是州內各市(cod_mun6)之間的相同比率。我還添加了顯示每個城市平均值的條形圖,儘管這些數據僅在每個城市的首次觀察中可用。

因此該地塊在市,州級混合信息(雖然它們在短短一個data.frame「規格化」

我所知道的傳說可以被去除:+ theme(legend.position = "none",) 我試圖添加標籤:

  • + geom_label(aes(x=mean_popNb_uf,label=UF2), nudge_y =.4,label.size = 0.05)
  • + geom_text(aes(label=UF2))

但結果標籤顯得雜亂無章,而且定位看起來很奇怪。

我也試過ggrepel包中的geom_text_repel(aes(label=UF2)),但沒有顯示標籤。在過去,我過去使用過包directlabels,但在這種情況下不知道如何使用它。

+0

只是偶然回到這一點 - 如果我在下面的內容仍然不是你正在尋找的東西,我很想知道它缺少的是什麼。這是一個有趣的教自己一些'ggplot2'的東西,所以我可能會很想深入挖掘。 –

回答

0

最好的方法可能是使用facet_wrap設置爲1行來分隔出狀態。請注意,似乎有些州的丟失數據,因此他們需要被過濾掉(否則facet_wrap嘗試設置爲空地塊x軸限制時失敗:

d %>% 
    filter(!is.na(pop1b) 
     , !is.na(popNb)) %>% 
    ggplot(aes(x=popNb,y=tx_atendimento)) + 
    geom_rect(aes(xmin=pop1b,xmax=popNb, 
       ymin=tx0,ymax=tx_atendimento 
       )) + 
    geom_segment(aes(x=pop1b,xend=popNb, 
        y=tx_atendimento_UF,yend=tx_atendimento_UF)) + 
    theme(axis.text.x = element_blank()) + 
    ggtitle('Daycare provision rate per state and municipality in Brazil (2014)') + 
    facet_wrap(~UF, scales = "free_x", nrow = 1, switch = "x") + 
    theme_minimal() 

需要注意的是,如果你想更改排序,你會需要設置UF列到任何順序您希望他們在的因子水平。

the plot

如果你想它顯示的狀態的「大小」,你可以使用,facet_gridspace = "free"這樣的

d %>% 
    filter(!is.na(pop1b) 
     , !is.na(popNb)) %>% 
    ggplot(aes(x=popNb,y=tx_atendimento)) + 
    geom_rect(aes(xmin=pop1b,xmax=popNb, 
       ymin=tx0,ymax=tx_atendimento 
       )) + 
    geom_segment(aes(x=pop1b,xend=popNb, 
        y=tx_atendimento_UF,yend=tx_atendimento_UF)) + 
    ggtitle('Daycare provision rate per state and municipality in Brazil (2014)') + 
    # facet_wrap(~UF, scales = "free_x", nrow = 1, switch = "x") + 
    facet_grid(~UF, scales = "free_x", switch = "x", space = "free") + 
    theme_minimal() + 
    theme(axis.text.x = element_blank() 
     , panel.margin.x = unit(0,"in")) 

但請注意,如果標籤太窄而無法貼標籤,則可能需要填充一些狀態。

enter image description here

我繼續添加代碼墊所有國家的一個任意所需的寬度和值進行排序:

library(dplyr) 
library(ggplot2) 
library(magrittr) 
url <- 'https://www.dropbox.com/s/f046jroutvt8ctk/SO_example_data_put_labels_in_graph.csv?raw=1' 
# d <- read.csv(url) 

desiredWidth <- 350000 

toPlot <- 
    d %>% 
    filter(!is.na(pop1b) 
     , !is.na(popNb) 
     , !is.na(UF)) %>% 
    split(.$UF) %>% 
    lapply(function(thisState){ 
    # thisState <- d %>% filter(UF == "AC") 
    # Find current range: 
    currRange <- 
     thisState %>% 
     {max(.$popNb, na.rm = TRUE) - 
      min(.$pop1b, na.rm = TRUE)} 

    spacing <- (desiredWidth - currRange)/2 

    # Add the spacing 
    temp <- thisState[1:2,] 
    temp$pop1b <- 
     c(min(thisState$pop1b, na.rm = TRUE) - spacing 
     , max(thisState$popNb, na.rm = TRUE) + 1 
     ) 
    temp$popNb <- 
     c(min(thisState$pop1b, na.rm = TRUE) - 1 
     , max(thisState$popNb, na.rm = TRUE) + spacing 
    ) 
    temp$tx_atendimento <- 0 
    return(rbind(thisState , temp)) 
    }) %>% 
    bind_rows %>% 
    filter(!is.na(UF)) %>% 
    droplevels 

# summary values 
sumVal <- 
    toPlot %>% 
    group_by(UF) %>% 
    summarise(sumVal = tx_atendimento_UF[1]) 

# Sort the states: 
toPlot$UF <- 
    factor(
    toPlot$UF 
    , levels = as.character(sumVal$UF)[order(sumVal$sumVal)] 
) 


toPlot %>% 
    ggplot(aes(x=popNb,y=tx_atendimento)) + 
    geom_rect(aes(xmin=pop1b,xmax=popNb, 
       ymin=tx0,ymax=tx_atendimento 
       )) + 
    geom_segment(aes(x=pop1b,xend=popNb, 
        y=tx_atendimento_UF,yend=tx_atendimento_UF)) + 
    ggtitle('Daycare provision rate per state and municipality in Brazil (2014)') + 
    # facet_wrap(~UF, scales = "free_x", nrow = 1, switch = "x") + 
    facet_grid(~UF, scales = "free_x", switch = "x", space = "free") + 
    theme_minimal() + 
    theme(axis.text.x = element_blank() 
     , panel.margin.x = unit(0,"in")) 

enter image description here

+0

tks。這是一個有趣的想法,圖形看起來不錯。然而,它與原始圖表不同,因爲每個州的兒童人口的相對規模已經喪失(看起來很小的州)。 – LucasMation

+1

我添加了一個版本,每個州有不同的間距。問題在於標籤在較小的狀態下開始相互重疊。但是,如果你想要的話,你可以填充這些東西(例如,爲狀態添加一個額外的矩形,但是將它設置在0高度,在小國的任一端 - 你可以爲所有這些都做,並且效果會在大州最小) –