用多级ggplot2图中的标签替换图例

时间:2016-06-23 14:02:48

标签: r ggplot2 labels

我创建了这个图表。标签占用太多空间,很难看出哪个状态是哪个。所以我想用图表中的状态代码标签替换图例,或者用de x轴代替。有一个简单的方法吗?

图表: 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)的相同率。我还添加了显示每个市镇平均值的条形图,尽管这些数据仅在每个市政当局的第一次观察中可用。

所以这个情节混合了市级和州级的信息(尽管它们只在一个数据框架中被“非规范化”。

我知道可以使用+ 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))

但是生成的标签看起来很混乱,定位看起来很奇怪。

我还尝试了geom_text_repel(aes(label=UF2))包中的ggrepel,但没有标签显示。在过去,我过去曾使用过包directlabels,但在这种情况下不知道如何使用它。

1 个答案:

答案 0 :(得分: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

如果你想要&#34;尺寸&#34;在显示的状态中,您可以使用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