ggplot2: 顶部图例关键符号大小随图例关键标签而变化

7

问题

我希望将图例放在图的上方。我还希望将图例键符号(彩色正方形)放在图例键标签(图例文本)上方。但是,当我这样做时,图例键符号会“拉伸”以适应标签的大小。我想ggplot2工作得很好,但我如何手动覆盖此功能?

如何在顶部保持具有可变长度标签的一致的图例键符号?

可重现的示例

这不一定是最小的示例,以防实际代码的结构(例如coord_flipfill调用)产生影响

library(dplyr)
library(ggplot2)

dataFrame <- diamonds %>%
              group_by(color, cut) %>%
              summarise(count = n()) %>%
              group_by(color) %>%
              mutate(percent = count/sum(count),
                    pretty_label = paste0(round(percent*100, 1), "%")) %>%
              ungroup()

p <- ggplot(data = dataFrame, mapping = aes(x=color, y = percent, group = cut))+
      geom_bar(aes(fill = cut), stat = "identity", position = "fill")+
      geom_text(aes(label = pretty_label), position=position_fill(vjust=0.5), colour="white", stat = "identity")+
      coord_flip()+
      theme(legend.position="top")+
      guides(fill = guide_legend(label.position = "bottom", reverse = TRUE))

plot(p)

legend symbols stretch with labels

注意每个图例符号的大小都不同,这取决于标签的长度。 我已经尝试过的方法 我想这与指南有关,但我似乎无法做到。使用上面的绘图(p),我已经尝试了以下内容以及其他内容:
  1. 这里这里p + guides(colour = guide_legend(override.aes = list(size=3)))

  2. 这里p + guides(colour = guide_legend(keywidth = .5, keyheight = .5))p + guides(colour = guide_legend(keywidth = unit(.5, "cm"), keyheight = unit(.5, "cm")))

  3. 这里:(尝试包装标签)p + guides(color = guide_legend(nrow = 2))

我尝试了其他一些不太“合乎逻辑”的尝试,但都没有成功。

最终想法

我可能只是不知道该搜索什么而已。如果您能指出正确的方向,我总是愿意自己解决问题。欢迎提供任何额外的资源。
提前感谢!
会话输出
> sessionInfo()
R version 3.5.1 (2018-07-02)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] bindrcpp_0.2.2 ggplot2_3.0.0  dplyr_0.7.6   

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.18      bindr_0.1.1       magrittr_1.5      tidyselect_0.2.4  munsell_0.5.0     colorspace_1.3-2  viridisLite_0.3.0
 [8] R6_2.2.2          rlang_0.2.1       plyr_1.8.4        tools_3.5.1       grid_3.5.1        gtable_0.2.0      withr_2.1.2      
[15] yaml_2.1.19       lazyeval_0.2.1    assertthat_0.2.0  digest_0.6.17     tibble_1.4.2      purrr_0.2.5       glue_1.2.0       
[22] labeling_0.3      compiler_3.5.1    pillar_1.2.3      scales_0.5.0      pkgconfig_2.0.1  

在“What I have already tried”下的所有选项,在你将colour替换为fill时都能在某种程度上起作用,例如:p + guides(fill = guide_legend(override.aes = list(size=3)))。你有一个填充比例尺,而不是颜色比例尺。 - Marius
我也认为可能是这种情况。我在我的实际数据上尝试了一下,但是我的标签太长了,而且我增加的大小不够。如果大小小于最长的标签,则没有影响(至少对我来说)。我忽略了在我所给出的示例中尝试这些可能性,但这可能会让我朝着正确的方向前进。谢谢! - Christian Million
1个回答

8

我不知道是否有一种方法可以单独控制图例颜色框的宽度而不影响文本(除非通过修改图例 grobs 进行黑客攻击)。不过,如果在您的主题语句中添加 legend.key.width=unit(1.5, "cm") ,所有颜色框都将扩展到相同的宽度(您可能需要微调 1.5 的值以获得所需的框宽度)。

library(scales)

ggplot(dataFrame, aes(x=color, y = percent))+
  geom_bar(aes(fill = cut), stat = "identity") +
  geom_text(aes(label = pretty_label), position=position_fill(vjust=0.5), 
            colour="white", size=3)+
  coord_flip()+
  theme(legend.position="top",
        legend.key.width=unit(1.5, "cm"))+
  guides(fill = guide_legend(label.position = "bottom", reverse = TRUE)) +
  scale_y_continuous(labels=percent)

在这里输入图片描述

将“非常好”分成两行,可以节省一些空间:

library(forcats)

ggplot(dataFrame, aes(x=color, y = percent, fill = fct_recode(cut, "Very\nGood"="Very Good")))+
  geom_bar(stat = "identity") +
  geom_text(aes(label = pretty_label), position=position_fill(vjust=0.5), 
            colour="white", size=3)+
  coord_flip()+
  theme(legend.position="top",
        legend.key.width=unit(1.2, "cm"))+
  guides(fill = guide_legend(label.position = "bottom", reverse = TRUE)) +
  labs(fill="Cut") +
  scale_y_continuous(labels=percent)

enter image description here


1
谢谢!我相信我在我的实际数据上尝试了你的解决方案,但标签太长了,而且我没有设置足够长的宽度。因此,如果标签比您提供的宽度更长,则不会产生影响,这是有道理的。此外,fct_recode非常有帮助,我能够缩写一些标签。感谢您的帮助。 - Christian Million

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接