как добавить легенды из stat_summary и удалить легенды из основного сюжета? - PullRequest
0 голосов
/ 27 апреля 2020

Я хочу построить значения df1 по двум группам, т.е. product и start_date, а также построить поперечину со средним значением 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))

GROTH GRAPH

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) 

Есть ли способ убрать границы гистограмм и добавить условные обозначения двух перекладин в верхнем правом углу графика? enter image description here

Кроме того, я хотел бы знать, есть ли способ добавить просто "дату" из df1 под каждым столбцом на графике?

1 Ответ

2 голосов
/ 27 апреля 2020

Ваш вопрос о настройке сюжета состоит из нескольких частей. Подводя итог нескольким пунктам:

  • Измените с 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'))

enter image description here

Объяснение: Точка перехода на group=factor(start_date) такова, что вы поддерживаете разделение полос между различными продуктами - концепция, известная как «уклонение». Поскольку ваш исходный вызов color= был в aes(, он создал элемент легенды, а geom_col использовал его для уклонения, поскольку остальные эстетики уже были сопоставлены с x и y, а fill= Эстет c применялся. Если вы удалите color=, вы получите один столбец для каждого продукта. Даже если вы укажете position='dodge', geom_col не будет уклоняться от них, потому что нет информации о том, как это сделать. Вот почему вы включаете group= aestheti c - чтобы дать geom_col информацию о том, как он должен уклоняться.

Вы используете aes(..., чтобы указать ggplot, какие легенды создавать. Если эстетика c сопоставлена ​​с x или y, она просто использует это для построения. group= эстетика используется для уклонения и других групповых атрибутов, но в основном для любой другой эстетики (size, shape, color, fill, linetype ... et c et c) используются для создания легенд. Если мы укажем оба stat_summary вызовов для включения color aestheti c, будет создана легенда, которая будет объединена. Проблема здесь в том, что в наборе данных нет столбца (потому что у вас есть два), который можно использовать для сопоставления с цветом, поэтому мы создаем его, называя символ («mean1» и «mean2»).

Final точка: это может быть проще построить, если вы объединяете свои наборы данных. Вы все еще можете указать, откуда они пришли, поэтому что-то вроде этого работает:

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

Затем нанесите на график df, а не df1. Затем вы можете использовать один stat_summary звонок, где вы укажете color=origin_df.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...