简体   繁体   English

将ggplot Legend标签直接放在其填充颜色上

[英]Position a ggplot Legend label directly over its fill colour

For a ggplot graph, I wish to have the values of the legend (here, 0 and 1) to be positioned over the colours they represent, and not to the side of them. 对于ggplot图,我希望将图例的值(此处为0和1)定位在它们所代表的颜色上,而不是它们的侧面。 By which I mean not to the left, right, above or below the coloured square, but within the square itself. 我的意思是不是在彩色正方形的左边,右边,上面或下面,而是在正方形内。 This would result in a number 0 inside a red square and the number 1 inside a blue square. 这将导致红色正方形内的数字0和蓝色正方形内的数字1。 How can this be done? 如何才能做到这一点?

ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) +
geom_bar() +
theme(legend.position = "top", 
    legend.direction = "horizontal") +
guides(color = guide_legend(title.position = "left", label.position = "top")) 

Since you're using fill you need to use fill within guides then play with label.vjust and title.vjust to get everything to line up. 由于你正在使用fill你需要在guides使用填充,然后使用label.vjusttitle.vjusttitle.vjust所有内容。

library(tidyverse)

ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) +
  geom_bar() +
  theme(legend.position = "top", 
        legend.direction = "horizontal") +
  guides(fill = guide_legend(label.vjust = -7, label.position = "top", title.vjust = 0.2))

Created on 2018-11-23 by the reprex package (v0.2.1) reprex包创建于2018-11-23(v0.2.1)

With minor adjustment, you can use the approach shown at change-geom-texts-default-a-legend-to-label-string-itself . 通过微调,您可以使用change-geom-texts-default-a-legend-to-label-string-their中显示的方法。 This changes the key generating function, and so allows ggplot2 to calculate the positions to place the labels for you. 这会更改键生成功能,因此允许ggplot2计算为您放置标签的位置。

Th idea is to keep the original rectGrob for the geom_bar legend key and use an additional textGrob to place the label on top. 我的想法是保留原始rectGrobgeom_bar图例键,并使用额外的textGrob将标签放在顶部。

library(ggplot2)
library(grid)

oldK <- GeomBar$draw_key # to save for later

# see other answer on how to tweak function based n manual colours
GeomBar$draw_key <- function (data, params, size, 
                              var=unique(mtcars$vs),
                              cols=scales::hue_pal()(length(var))) {

    # match labels to the fill colour
    txt <- if(is.factor(var)) levels(var) else sort(var)
    txt <- txt[match(data$fill, cols)]

    # This is from the original GeomBar$draw_key -------------------
    lwd <- min(data$size, min(size)/4)
    rg <- rectGrob(width = unit(1, "npc") - unit(lwd, "mm"), height = unit(1, 
        "npc") - unit(lwd, "mm"), gp = gpar(col = data$colour, 
        fill = alpha(data$fill, data$alpha), lty = data$linetype, 
        lwd = lwd * .pt, linejoin = "mitre"))
    # ---------------------------------------------------------------

    # Add text label: lifted from other answer
    # hard-coded text size multiplier -- got to be a better way!
    tg <- textGrob(txt, 0.5, 0.5,  
             just="center", 
             gp = gpar(col = "black", 
                       fontfamily = data$family, 
                       fontface = data$fontface, 
                       fontsize = 10*data$size * .pt)) 
    # ---------------------------------------------------------------

    grobTree(rg, tg) # output new key
}

You can then plot 然后你可以绘图

ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) +
  geom_bar() +
  theme(
    legend.position = "top", 
    legend.direction = "horizontal",
    legend.text = element_blank())

# reset key function to original
GeomBar$draw_key <- oldK

在此输入图像描述

This should be fairly robust to resizing your plot. 这应该相当稳健,以调整你的情节。

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

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