0

我想按两组(即产品和开始日期)绘制 df1 的值,并绘制一个带有 df1(蓝色)平均值和 df2(红色)平均值的横线,如附图所示。

df1 <- data.frame(product = c("A","A","A","A","A","A","A","B","B","B","B","B","B","B","C","C","C","C","C","C","C","D","D","D","D","D","D","D"), 
                  start_date =as.Date(c('2020-02-01', '2020-02-02', '2020-02-03', '2020-02-04', '2020-02-05', '2020-02-06', '2020-02-07')),
                  value = c(15.71,17.37,19.93,14.28,15.85,10.5,8.58,5.62,5.19,5.44,4.6,7.04,6.29,3.3,20.35,27.92,23.07,12.83,22.28,21.32,31.46,34.82,23.68,29.11,14.48,25.2,16.91,27.79))

df2 <- data.frame(product = c("A","A","A","A","A","A","B","B","B","B","B","B","C","C","C","C","C","C","D","D","D","D","D","D"), 
                  start_date =as.Date(c('2019-07-09', '2019-07-10', '2019-07-11', '2019-07-12', '2019-07-13', '2019-07-14')),
                  value = c(9.06,10.74,14.64,7.67,8.72,11.21,4.76,4.53,3.81,4.32,3.95,5.2,20.36,21.17,19.51,16.25,17.93,16.94,14.51,14.65,23.28,10.84,16.71,12.48))

绘图图

graph1 <- ggplot(df1, aes(
    y = value, x = product, fill = product, color = factor(start_date))) +
  geom_col(data = df1, stat = "identity",position = position_dodge(width = 0.8), width = 0.7, inherit.aes = TRUE, size = 0) + 
  xlab("Product") + ylab("Values")  + ylim(c(0,40)) + 
  scale_fill_manual(values=c("#008FCC", "#FFAA00", "#E60076", "#B00000")) +
  stat_summary(data = df1, aes(x = factor(product),y = value),fun = "mean",geom = "crossbar", color = "blue", size = 1, width = 0.8, inherit.aes = FALSE) +
  stat_summary(data = df2, aes(x = factor(product),y = value),fun = "mean",geom = "crossbar", color = "red", size = 1, width = 0.8, inherit.aes = FALSE) 

有没有办法删除条形图的边界并在图的右上角添加两个横杆的图例? 在此处输入图像描述

此外,我想知道是否有办法在图中的每个条形下方添加来自 df1 的“日期”?

4

1 回答 1

2

您关于调整情节的问题有多个部分。总结几点:

  • 从 更改color=factor(start_date)group=以删除条形周围的颜色,但通过 start_date 保持各个条形的分隔

  • 在绘图区域内使用theme(legend.position=...并指定图例的精确位置。适当时也使用theme(legend.direction='horizontal')

  • color=属性添加到stat_summary(geom='crossbar'...)调用中,以便将它们都“添加”到图例中,然后scale_color_manual如果您不喜欢默认值,则使用它来指定颜色。

  • 次要建议:使用ylim(X,Y)而不是ylim(c(X,Y)). 没有必要将限制放入向量中,因为ylim可以接受它并且更简单。请注意,无论哪种方式它仍然有效,所以这就是为什么这一点是次要的。

  • data=df1第一次调用不需要stat_summary,因为它是基于 中data=设置的值的默认映射ggplot(...。不过,您仍然需要该y=值,因为它是必需的。

这是实现上述注释的调整代码:

ggplot(df1, aes(y = value, x = product, fill = product, group = factor(start_date))) +
    geom_col(data = df1, position = position_dodge(width = 0.8),
        width = 0.7, inherit.aes = TRUE, size = 0) +
    xlab("Product") + ylab("Values") + ylim(0,60) +
    scale_fill_manual(values=c("#008FCC", "#FFAA00", "#E60076", "#B00000")) +
    stat_summary(aes(x = factor(product), y=value, color='mean1'),
        fun = "mean", geom = "crossbar",
        size = 1, width = 0.8, inherit.aes = FALSE) +
    stat_summary(data = df2, aes(x = factor(product),y=value, color='mean2'),
        fun = "mean", geom = "crossbar",
        size = 1, width = 0.8, inherit.aes = FALSE) +
    theme(legend.position=c(0.75,0.8), legend.direction = 'horizontal') +
    scale_color_manual(values=c('blue', 'red'))

在此处输入图像描述

说明:更改为的group=factor(start_date)目的是为了让您保持不同产品之间的条形分割——一个称为“躲避”的概念。由于您最初的调用color=是在 中aes(,因此它创建了一个图例项目并将其geom_col用于躲避,因为其他美学已经映射到xand y,并且fill=正在应用美学。如果您删除color=,您会为每个产品获得一个条形图。即使您指定position='dodge',geom_col也不会躲避它们,因为没有关于如何做到这一点的信息。这就是为什么你包括group=美学 - 提供geom_col有关它应该如何躲避的信息。

您用于aes(...指示要ggplot创建哪些图例。如果美学被映射到xor y,它只是使用它来绘图。 group=美学用于躲避和其他组属性,但基本上任何其他美学(size, shape, color, fill, linetype... 等)都用于创建图例。如果我们指定两个stat_summary调用都包含color美学,则将创建一个组合的图例。这里的问题是数据集中没有列(因为你有两个)用于映射到颜色,所以我们通过命名一个字符(“mean1”和“mean2”)来创建一个。

最后一点:如果您结合数据集,可能会更容易绘制此图。你可能仍然想指出它们来自哪里,所以这样的事情是有效的:

df1$origin_df <- 'df1'
df2$origin_df <- 'df2'
df <- rbind(df1, df2)

然后绘制 withdf和 not df1。然后,您可以在您指定的地方使用一个stat_summary调用color=origin_df

于 2020-04-27T13:18:05.847 回答