R: график плотности ggplot2 показывает неправильные цвета заливки - PullRequest
0 голосов
/ 24 января 2020

Я хотел бы построить плотности двух переменных ("red_variable", "green_variable") из двух независимых фреймов данных на одном графике плотности, используя красный и зеленый цвета для двух переменных.

Это моя попытка при кодировании:

library(ggplot2)

### Create dataframes
red_dataframe <- data.frame(red_variable = c(10,11,12,13,14))
green_dataframe <- data.frame(green_variable = c(6,7,8,9,10))
mean(red_dataframe$red_variable) # mean is 12
mean(green_dataframe$green_variable) # mean is 8

### Set colors
red_color= "#FF0000"
green_color= "#008000"

### Trying to plot densities with correct colors and correct legend entries
ggplot() +
geom_density(aes(x=red_variable, fill = red_color, alpha=0.5), data=red_dataframe) + 
geom_density(aes(x=green_variable, fill = green_color, alpha=0.5), data=green_dataframe) +
scale_fill_manual(labels = c("Density of red_variable", "Density of green_variable"), values = c(red_color, green_color)) +
xlab("X value") +
ylab("Density") +
labs(fill = "Legend") +
guides(alpha=FALSE)

Результат: легенда показывает правильные цвета, но цвета на графике неверны: переменная "red" отображается зеленым цветом, а переменная "green" красным. «Зеленая» плотность (среднее = 8) должна появиться слева, а «красная» плотность (среднее = 12) справа на оси X. Такое поведение сюжета не имеет для меня никакого смысла.

На самом деле я могу получить желаемый результат, переключив красный и зеленый в коде:

### load ggplot2
library(ggplot2)

### Create dataframes
red_dataframe <- data.frame(red_variable = c(10,11,12,13,14))
green_dataframe <- data.frame(green_variable = c(6,7,8,9,10))
mean(red_dataframe$red_variable) # mean is 12
mean(green_dataframe$green_variable) # mean is 8

### Set colors
red_color= "#FF0000"
green_color= "#008000"

### Trying to plot densities with correct colors and correct legend entries
ggplot() +
geom_density(aes(x=red_variable, fill = green_color, alpha=0.5), data=red_dataframe) + 
geom_density(aes(x=green_variable, fill = red_color, alpha=0.5), data=green_dataframe) +
scale_fill_manual(labels = c("Density of red_variable", "Density of green_variable"), values = c(red_color, green_color)) +
xlab("X value") +
ylab("Density") +
labs(fill = "Legend") +
guides(alpha=FALSE)

... Хотя сюжет имеет смысл сейчас, код - нет. Я не могу доверять коду, который делает то, что я ожидал. В чем здесь проблема? Я дальтоник?

Ответы [ 2 ]

2 голосов
/ 24 января 2020

В вашем коде, чтобы иметь цвет в правильном положении, вам нужно указать fill = red_color или fill = green_color (а также альфа, поскольку это константа - как указано @Gregor) вне aes, например:

...+ 
geom_density(aes(x=red_variable), alpha=0.5, fill = red_color, data=red_dataframe) + 
  geom_density(aes(x=green_variable), alpha=0.5, fill = green_color, data=green_dataframe) + ...

Кроме того, вы можете связать свои кадры данных, преобразовать их в более длинный формат (гораздо более подходящий для ggplot), а затем добавить цветной столбец, который можно использовать с scale_fill_identity функция (https://ggplot2.tidyverse.org/reference/scale_identity.html):

df <- cbind(red_dataframe,green_dataframe)

library(tidyr)
library(ggplot2)
library(dplyr)
df <- df %>% pivot_longer(.,cols = c(red_variable,green_variable), names_to = "var",values_to = "val") %>%
  mutate(Color = ifelse(grepl("red",var),red_color,green_color))

ggplot(df, aes(val, fill = Color))+
  geom_density(alpha = 0.5)+
  scale_fill_identity(guide = "legend", name = "Legend", labels = levels(as.factor(df$var)))+
  xlab("X value") +
  ylab("Density")

enter image description here

Это ответ на ваш вопрос?

1 голос
/ 24 января 2020

Вы пытаетесь использовать ggplot, как если бы это была базовая графика ... для изменения мышления может потребоваться некоторое время, чтобы привыкнуть. Ответ DC37 показывает, как вы должны это сделать. Я попытаюсь объяснить, что не так в вашей попытке:

Когда вы помещаете fill = green_color внутрь aes(), , потому что оно внутри aes() ggplot по существу создает новый столбец данных, заполненных значениями green_color в вашем green_data_frame, то есть "#008000", "#008000", "#008000", .... То же самое относится к значениям красного цвета в красном фрейме данных. Мы можем увидеть это, если мы изменим ваш график, просто удалив scale:

ggplot() +
  geom_density(aes(x = red_variable, fill = green_color, alpha = 0.5), data =
                 red_dataframe) +
  geom_density(aes(x = green_variable, fill = red_color, alpha = 0.5), data =
                 green_dataframe) +
  xlab("X value") +
  ylab("Density") +
  labs(fill = "Legend") +
  guides(alpha = FALSE)

enter image description here

Мы действительно можем получить то, что вы хотите, поставив identity шкала, предназначенная для (распространенного в base, редко встречающегося в ggplot2) случая, когда вы фактически помещаете значения цветов в данные.

ggplot() +
  geom_density(aes(x = red_variable, fill = green_color, alpha = 0.5), data =
                 red_dataframe) +
  geom_density(aes(x = green_variable, fill = red_color, alpha = 0.5), data =
                 green_dataframe) +
  scale_fill_identity() +
  xlab("X value") +
  ylab("Density") +
  labs(fill = "Legend") +
  guides(alpha = FALSE)

enter image description here

Когда вы добавили scale_fill_manual, ggplot выглядел как «хорошо, круто, вы хотите указать цвета и метки». Но вы думали в том порядке, в котором вы добавили слои на график (очень похоже на базовую графику), тогда как ggplot думал об этих вновь созданных переменных "#FF0000" и "#008000", которые он упорядочил в алфавитном порядке по умолчанию (как если бы они были factor или character столбцами во фрейме данных). И так как вы случайно добавили слои в обратном алфавитном порядке, он был переключен. Ответ

dc37 показывает пару лучших методов. С ggplot вы должны (а) по возможности работать с одним длинным форматом фрейма данных (б) не помещать константы в aes() (постоянный цвет, постоянная альфа и т. Д. c.), (c) установить цвета в функции scale_fill_* или scale_color_*, когда они не постоянны.

...