Порядок изменения уровней факторов при построении слоев с подмножествами данных
Я пытаюсь контролировать порядок элементов в легенде на графике ggplot2
в R. Я искал некоторые другие подобные вопросы и узнал об изменении порядка уровней факторной переменной, которую я рисую. Я собираю данные за 4 месяца, декабрь, январь, июль и июнь.
Если я делаю только одну команду за все месяцы, она работает так, как ожидалось, с месяцами, упорядоченными в легенде, появляющимися в порядке уровней фактора. Тем не менее, мне нужно иметь другое значение dodge
для летних (июнь и июль) и зимних (Dec и Jan) данных. Я делаю это с помощью двух команд geom_pointrange
. Когда я делю его на 2 шага, порядок легенды возвращается в алфавитном порядке. Вы можете продемонстрировать, комментируя команду "plot summer" или "plot winter".
Что я могу изменить, чтобы сохранить порядок моего фактора в легенде?
Пожалуйста, проигнорируйте нечетные аналитические данные - реальные данные выглядят отлично в этом формате.
#testdata
hour <- rep(seq(from=1,to=24,by=1),4)
avg_hou <- sample(seq(0,0.5,0.001),96,replace=TRUE)
lower_ci <- avg_hou - sample(seq(0,0.05,0.001),96,replace=TRUE)
upper_ci <- avg_hou + sample(seq(0,0.05,0.001),96,replace=TRUE)
Month <- c(rep("December",24), rep("January",24), rep("June",24), rep("July",24))
testdata <- data.frame(Month,hour,avg_hou,lower_ci,upper_ci)
testdata$Month <- factor(alldata$Month,levels=c("June", "July", "December","January"))
#basic plot setup
plotx <- ggplot(testdata, aes(x = hour, y = avg_hou, ymin = lower_ci, ymax = upper_ci, color = Month, shape = Month))
plotx <- plotx + scale_color_manual(values = c("June" = "#FDB863", "July" = "#E66101", "December" = "#92C5DE", "January" = "#0571B0"))
#plot summer
plotx <- plotx + geom_pointrange(data = testdata[testdata$Month == "June" | testdata$Month == "July",], size = 1, position=position_dodge(width=0.3))
#plot winter
plotx <- plotx + geom_pointrange(data = testdata[testdata$Month == "December" | testdata$Month == "January",], size = 1, position=position_dodge(width=0.6))
print(plotx)
Ответы
Ответ 1
Еще один способ подумать о "доке" - это смещение от значений х на основе группы (в данном случае месяца). Поэтому, если мы добавим столбец dodge (x-offset) к вашим исходным данным, в зависимости от месяца:
# your original sample data
# note the use of set.seed(...) so "random" data is reproducible
set.seed(1)
hour <- rep(seq(from=1,to=24,by=1),4)
avg_hou <- sample(seq(0,0.5,0.001),96,replace=TRUE)
lower_ci <- avg_hou - sample(seq(0,0.05,0.001),96,replace=TRUE)
upper_ci <- avg_hou + sample(seq(0,0.05,0.001),96,replace=TRUE)
Month <- c(rep("December",24), rep("January",24), rep("June",24), rep("July",24))
testdata <- data.frame(Month,hour,avg_hou,lower_ci,upper_ci)
testdata$Month <- factor(testdata$Month,levels=c("June", "July", "December","January"))
# add offset column for dodge
testdata$dodge <- -2.5+(as.integer(testdata$Month))
# create ggplot object and default mappings
ggp <- ggplot(testdata, aes(x=hour, y = avg_hou, ymin = lower_ci, ymax = upper_ci, color = Month, shape = Month))
ggp <- ggp + scale_color_manual(values = c("June" = "#FDB863", "July" = "#E66101", "December" = "#92C5DE", "January" = "#0571B0"))
# plot the point range
ggp + geom_pointrange(aes(x=hour+0.2*dodge), size=1)
Производит следующее:
![]()
Для поддержания порядка масштабирования не требуется geom_blank(...)
, и для него не требуется два вызова geom_pointrange(...)
Ответ 2
Одна из возможностей заключается в том, чтобы добавить geom_blank
в качестве первого слоя на графике. От ?geom_blank
: "Пустая геометрия ничего не рисует, но может быть полезным способом обеспечения общих масштабов между разными сюжетами". Мы говорим слою geom_blank
, чтобы использовать весь набор данных. Таким образом, этот слой устанавливает масштаб, который включает все уровни "Месяц", правильно упорядоченные. Затем добавьте два слоя geom_pointrange
, каждый из которых использует подмножество данных.
Возможно, речь идет о вкусе в этом конкретном случае, но я предпочитаю готовить наборы данных, прежде чем использовать их в ggplot
.
df_sum <- testdata[testdata$Month %in% c("June", "July"), ]
df_win <- testdata[testdata$Month %in% c("December", "January"), ]
ggplot(data = testdata, aes(x = hour, y = avg_hou, ymin = lower_ci, ymax = upper_ci,
color = Month, shape = Month)) +
geom_blank() +
geom_pointrange(data = df_sum, size = 1, position = position_dodge(width = 0.3)) +
geom_pointrange(data = df_win, size = 1, position = position_dodge(width = 0.6)) +
scale_color_manual(values = c("June" = "#FDB863", "July" = "#E66101",
"December" = "#92C5DE", "January" = "#0571B0"))
![enter image description here]()