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

Zan*_*ane 3 r ggplot2

我对这个问题困惑了很长时间。一个简单的数据框构造如下

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))
)
Run Code Online (Sandbox Code Playgroud)

假设我想显示填充的图例

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
Run Code Online (Sandbox Code Playgroud)

图形没问题,但是图例不正确

在此输入图像描述

我猜,也许不同的形状(21到25)不能合并?然后,我将数据划分为两个子集,其中第一组的形状为 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)
Run Code Online (Sandbox Code Playgroud)

不幸的是,传说并没有改变。然后,我将形状从向量更​​改为标量,如下所示

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)
Run Code Online (Sandbox Code Playgroud)

填充颜​​色的传说终于正确了......

在此输入图像描述

那么这里会发生什么呢?这是一个错误吗?是否可以只添加一个具有不同形状(21 到 25)的单层?

一种可能的解决方案是可以添加组件guides(),如下所示

p + 
  guides(fill = guide_legend(override.aes = list(fill = uniFill,
                                                 shape = 21)))
Run Code Online (Sandbox Code Playgroud)

但我更感兴趣的是为什么p不起作用(图例)

Dan*_*one 6

您的图例在第一个示例中不起作用的主要原因是因为您没有将形状考虑到美学中。

我还有其他一些建议:不要在数据框中定义颜色;而是使用代码定义一个列来改变美观。然后明确定义您的填充和形状值。每个比例都需要有相同的名称 - 在本例中为“Legend”。

尝试一下这个编辑。

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
Run Code Online (Sandbox Code Playgroud)

(编辑)如果您的填充和形状美学不匹配,我看不到除了使用guides和两个图例之外的任何其他方法。请注意,如果您的属性列是描述性的,则无需设置标签,并且您的代码会更清晰(请参阅形状与填充美观)。

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
Run Code Online (Sandbox Code Playgroud)

具有两个图例的点图