简体   繁体   English

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

[英]Replacing legend with labels in multilevel ggplot2 plot

I created this chart. 我创建了这张图表。 The labels take too much space and it is difficult to see which state is which. 标签占用太多空间,很难看到哪个状态。 So I would like to replace the legend by labels of State codes inside the graph, or bellow de x axis. 因此,我想用图形或波纹管x轴内的州代码标签代替图例。 Is there an easy way to do this? 是否有捷径可寻?

Chart: 图表: 在此处输入图片说明

Code to generate it: 生成它的代码:

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')

Explanation: 说明:

Note that this is not a normal bar plot. 请注意,这不是正常的条形图。 Each municipality (row in dataset) is represented by a rectangle with width corresponding to the number of children in that age and height corresponding to the provision rate. 每个自治市(数据集中的行)均由一个矩形表示,其宽度对应于该年龄段的儿童人数,高度对应于供应率。 I created the x values so municipalities are arranged first by the average provision rate in the state (UF) and second by the same rate among municipalities (cod_mun6) of the state. 我创建了x值,因此首先按州(UF)的平均供给率来安排市,然后按州的市(cod_mun6)中的相同率来安排市。 I also added bars showing the average of each municipality, although the data for these is only available in the first observation of each municipality. 我还添加了显示每个城市平均值的条形图,尽管这些数据仅在每个城市的首次观察中可用。

So this plot mixes information at municipal and state levels (although they are "denormalized" in just one data.frame. 因此,此图将市政和州级别的信息混合在一起(尽管它们只是在一个data.frame中被“非规范化”了)。

I know the legend can be removed with: + theme(legend.position = "none", ) I tried adding labels with: 我知道可以通过以下方式删除图例: + 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))

but the resulting labels look cluttered, and positioning looks weird. 但是结果标签看起来很混乱,而且定位看起来很奇怪。

I also tried geom_text_repel(aes(label=UF2)) from the ggrepel package, but no labels showed. 我还尝试了ggrepel软件包中的geom_text_repel(aes(label=UF2)) ,但未显示任何标签。 In the past, I have used the package directlabels in the past, but don't know how to use it in this case. 过去,我过去使用过包directlabels ,但在这种情况下不知道如何使用它。

The best approach may be to use facet_wrap set to 1 row to separate out the states. 最好的方法可能是将facet_wrap设置为1行以分离出状态。 Note that it appears that some of the states are missing data, so they need to be filtered out (otherwise facet_wrap fails when trying to set the x axis limits for the empty plots: 请注意,似乎某些状态缺少数据,因此需要将其过滤掉(否则,当尝试为空图设置x轴限制时, facet_wrap失败:

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()

Note that if you want to change the sort, you would need to set the factor levels of the UF column to whatever order you want them in. 请注意,如果要更改排序,则需要将UF列的因子级别设置为所需的任何顺序。

剧情

If you want it with the "size" of the states shown, you can use, facet_grid with space = "free" like this 如果需要显示状态的“大小”,可以使用facet_grid其中space = "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"))

though note that you may need to pad some of the states if they are too narrow for the labels to fit. 但是请注意,如果某些状态太窄而无法容纳标签,则可能需要填充一些状态。

在此处输入图片说明

I went ahead and added code to pad all of the States to an arbitrary desired width and to sort the values: 我继续并添加了代码以将所有状态填充到任意所需的宽度并对值进行排序:

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"))

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM