简体   繁体   English

ggplot2 填充图例未显示正确的“填充”颜色

[英]ggplot2 fill legend does not display the correct “fill” color

I am confused of this problem for a long time.我对这个问题困惑了很长时间。 A simple data frame is constructed as follows一个简单的数据框构造如下

data <- data.frame(
  x = 1:5,
  y = 5:1,
  fill = c(rep("pink", 3), rep("blue", 2)),
  shape = c(rep(21, 3), rep(22, 2))
)

Suppose I wand to show the legend of the fill假设我想显示填充图例

uniFill <- unique(data$fill)
p <- ggplot(data,
       mapping = aes(x = x,
                     y = y,
                     fill = fill)) + 
  geom_point(shape = data$shape) + 
  # show legend so that I do not call `scale_fill_identity()`
  scale_fill_manual(values = uniFill,
                    labels = uniFill,
                    breaks = uniFill)
p

The graphics are OK, however, the legend is not correct图形正常,但是图例不正确

在此处输入图片说明

I guess, maybe different shapes (21 to 25) cannot be merged?我想,也许不同的形状(21 到 25)不能合并? Then, I partition the data into two subsets where the first set has shape 21 and the second has shape 22.然后,我将数据划分为两个子集,其中第一组的形状为 21,第二组的形状为 22。

data1 <- data[1:3, ]
data2 <- data[4:5, ]
# > data1$shape
# [1] 21 21 21
# > data2$shape
# [1] 22 22
ggplot(mapping = aes(x = x,
                     y = y,
                     fill = fill)) + 
  geom_point(data = data1, shape = data1$shape) + 
  geom_point(data = data2, shape = data2$shape) + 
  scale_fill_manual(values = uniFill,
                    labels = uniFill,
                    breaks = uniFill)

Unfortunately, the legend does not change.不幸的是,传说没有改变。 Then, I changed the shape from a vector to a scalar, as in然后,我将形状从向量更​​改为标量,如

ggplot(mapping = aes(x = x,
                     y = y,
                     fill = fill)) + 
  geom_point(data = data1, shape = 21) + 
  geom_point(data = data2, shape = 22) + 
  scale_fill_manual(values = uniFill,
                    labels = uniFill,
                    breaks = uniFill)

The legend of the fill color is correct finally...填充颜​​色的传说终于正确了......

在此处输入图片说明

So what happens here?那么这里会发生什么呢? Is it a bug?这是一个错误吗? Is it possible to just add a single layer but with different shapes (21 to 25)?是否可以只添加单层但具有不同的形状(21 到 25)?

A possible solution is that one can add component guides() , as in一种可能的解决方案是可以添加组件guides() ,如

p + 
  guides(fill = guide_legend(override.aes = list(fill = uniFill,
                                                 shape = 21)))

But I am more interested in why p does not work (legend)但我更感兴趣的是为什么p不起作用(图例)

The main reason your legend is not working in your first example is because you did not put your shape in the aesthetics.你的图例在你的第一个例子中不起作用的主要原因是你没有把你的形状放在美学中。

I have a couple other suggestions: Do not define colors in your data frame;我还有其他一些建议:不要在数据框中定义颜色; instead define a column to change the aesthetics using a code.而是定义一列以使用代码更改美感。 Then define your fill and shape values explicitly.然后明确定义填充和形状值。 Each of the scales needs to have the same name - in this case "Legend."每个音阶都需要具有相同的名称 - 在本例中为“Legend”。

Give this edit a try.试试这个编辑。

data <- data.frame(
  x = 1:5,
  y = 5:1,
  fill = c(rep("p", 3), rep("b", 2))
 )

uniFill <- c("p"="pink", "b"="blue")
uniShape <- c("p" = 21, "b" = 22)

p <- ggplot(data,
            mapping = aes(x = x,
                          y = y,
                          fill = fill,
                          shape = fill)) + 
  geom_point() + 
  # show legend so that I do not call `scale_fill_identity()`
  scale_fill_manual("Legend",values = uniFill,
                    labels = uniFill)+
  scale_shape_manual("Legend",values = uniShape,
                     labels = uniFill)
p

(edit) If your fill and shape aesthetics do not match up, I don't see any other way than to use guides and two legends. (编辑)如果您的填充和形状美学不匹配,除了使用guides和两个图例之外,我看不到任何其他方法。 Notice that if your attribute column is descriptive, you do not need to set the labels and your code will be cleaner (see shape vs fill aesthetics).请注意,如果您的属性列是描述性的,则不需要设置标签,您的代码会更清晰(请参阅形状与填充美学)。

data <- data.frame(
  x = 1:5,
  y = 5:1,
  fill = c(rep("p", 3), rep("b", 2)),
  shape = c(rep("circles", 2), rep("squares", 3))
)

uniFill <- c("p"="pink", "b"="blue")
uniShape <- c("circles" = 21, "squares" = 22)

p <- ggplot(data,
            mapping = aes(x = x,
                          y = y,
                          fill = fill,
                          shape = shape)) + 
  geom_point() + 
  # show legend so that I do not call `scale_fill_identity()`
  scale_fill_manual("Legend fill",values = uniFill,
                    labels = uniFill)+
  scale_shape_manual("Legend shape",values = uniShape  )+
  guides(fill = guide_legend("Legend fill", override.aes = list(shape = 21)))
p

带有两个图例的点图

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

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