Как назначить цвета для категориальных переменных в ggplot2, имеющих устойчивое отображение?
Я забирал скорость с R в прошлом месяце.
Вот мой вопрос:
Каким образом можно назначить цвета для категориальных переменных в ggplot2, имеющих устойчивое сопоставление? Мне нужны согласованные цвета по набору графиков, которые имеют разные подмножества и различное количество категориальных переменных.
Например,
plot1 <- ggplot(data, aes(xData, yData,color=categoricaldData)) + geom_line()
где categoricalData
имеет 5 уровней.
И затем
plot2 <- ggplot(data.subset, aes(xData.subset, yData.subset,
color=categoricaldData.subset)) + geom_line()
где categoricalData.subset
имеет 3 уровня.
Однако определенный уровень, который находится в обоих наборах, будет иметь другой цвет, что затрудняет чтение графиков вместе.
Нужно ли создавать вектор цветов в кадре данных? Или есть другой способ назначить определенные цвета для категорий?
Ответы
Ответ 1
Для простых ситуаций, таких как пример в OP, я согласен с тем, что ответ Тьерри является лучшим. Тем не менее, я считаю полезным отметить другой подход, который становится проще, когда вы пытаетесь поддерживать согласованные цветовые схемы в нескольких кадрах данных, которые не все получены путем подмножества одного большого кадра данных. Управление уровнями факторов в нескольких кадрах данных может стать утомительным, если их извлекают из отдельных файлов, и не все уровни факторов отображаются в каждом файле.
Один из способов решения этой проблемы - создать пользовательскую ручную цветовую шкалу следующим образом:
#Some test data
dat <- data.frame(x=runif(10),y=runif(10),
grp = rep(LETTERS[1:5],each = 2),stringsAsFactors = TRUE)
#Create a custom color scale
library(RColorBrewer)
myColors <- brewer.pal(5,"Set1")
names(myColors) <- levels(dat$grp)
colScale <- scale_colour_manual(name = "grp",values = myColors)
а затем добавьте цветовую гамму на график по мере необходимости:
#One plot with all the data
p <- ggplot(dat,aes(x,y,colour = grp)) + geom_point()
p1 <- p + colScale
#A second plot with only four of the levels
p2 <- p %+% droplevels(subset(dat[4:10,])) + colScale
Первый сюжет выглядит следующим образом:
![enter image description here]()
а второй график выглядит следующим образом:
![enter image description here]()
Таким образом, вам не нужно запоминать или проверять каждый фрейм данных, чтобы увидеть, что у них есть соответствующие уровни.
Ответ 2
В той же ситуации, указанной в malcook в его комментарии: к сожалению, < ответ href= "https://stackoverflow.com/a/6924503/15485" > Thierry не работает с ggplot2 версии 0.9.3.1.
png("figure_%d.png")
set.seed(2014)
library(ggplot2)
dataset <- data.frame(category = rep(LETTERS[1:5], 100),
x = rnorm(500, mean = rep(1:5, 100)),
y = rnorm(500, mean = rep(1:5, 100)))
dataset$fCategory <- factor(dataset$category)
subdata <- subset(dataset, category %in% c("A", "D", "E"))
ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point()
Здесь это первая цифра:
![ggplot A-E, mixed colors]()
а вторая цифра:
![ggplot ADE, mixed colors]()
Как мы видим, цвета не остаются фиксированными, например, E переключается с пурпурного на blu.
Как было предложено malcook в его комментарии и hadley в его комментарии код, который использует limits
, работает правильно:
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) +
geom_point() +
scale_colour_discrete(drop=TRUE,
limits = levels(dataset$fCategory))
дает следующий рисунок, который является правильным:
![correct ggplot]()
Это вывод из sessionInfo()
:
R version 3.0.2 (2013-09-25)
Platform: x86_64-pc-linux-gnu (64-bit)
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] methods stats graphics grDevices utils datasets base
other attached packages:
[1] ggplot2_0.9.3.1
loaded via a namespace (and not attached):
[1] colorspace_1.2-4 dichromat_2.0-0 digest_0.6.4 grid_3.0.2
[5] gtable_0.1.2 labeling_0.2 MASS_7.3-29 munsell_0.4.2
[9] plyr_1.8 proto_0.3-10 RColorBrewer_1.0-5 reshape2_1.2.2
[13] scales_0.2.3 stringr_0.6.2
Ответ 3
Самое простое решение - преобразовать вашу категориальную переменную в коэффициент до подмножества. Суть в том, что вам нужна переменная фактора с точно такими же уровнями во всех ваших подмножествах.
library(ggplot2)
dataset <- data.frame(category = rep(LETTERS[1:5], 100),
x = rnorm(500, mean = rep(1:5, 100)), y = rnorm(500, mean = rep(1:5, 100)))
dataset$fCategory <- factor(dataset$category)
subdata <- subset(dataset, category %in% c("A", "D", "E"))
С символьной переменной
ggplot(dataset, aes(x = x, y = y, colour = category)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = category)) + geom_point()
С фактор-переменной
ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point()
Ответ 4
Основываясь на очень полезном ответе на joran, я смог придумать это решение для стабильной цветовой шкалы для булева коэффициента (TRUE
, FALSE
).
boolColors <- as.character(c("TRUE"="#5aae61", "FALSE"="#7b3294"))
boolScale <- scale_colour_manual(name="myboolean", values=boolColors)
ggplot(myDataFrame, aes(date, duration)) +
geom_point(aes(colour = myboolean)) +
boolScale
Так как ColorBrewer не очень полезен с бинарными цветовыми шкалами, два необходимых цвета определяются вручную.
Здесь myboolean
- это имя столбца в myDataFrame
, содержащего коэффициент TRUE/FALSE. date
и duration
- это имена столбцов, которые должны отображаться на оси x и y графика в этом примере.
Ответ 5
Это старый пост, но я искал ответа на этот же вопрос,
Почему бы не попробовать что-то вроде:
scale_color_manual(values = c("foo" = "#999999", "bar" = "#E69F00"))
Если у вас есть категориальные ценности, я не вижу причины, почему это не должно работать.