У меня есть проблема, и я ничего не нашел в Интернете по этому поводу. Буду рад получить некоторые подсказки.
У меня есть набор данных, в котором ось x дискретна, но я хотел бы соединить точки друг с другом (что я могу сделать). Моя проблема заключается в том, что я добавляю параметр огранки. Я больше не могу связывать точки друг с другом. Я нашел альтернативу, НО она выглядит не очень.
Это простой воспроизводимый пример:
# Create a simple dataset
dat <- data.frame(Days = c(rep("Monday", 6), rep("Tuesday", 6), rep("Wednesday", 6)),
Shift = rep(c("Morning", "Evening", "Night"), 6),
Group = c(rep("Group1", 3), rep("Group2", 3), rep("Group1", 3), rep("Group2", 3), rep("Group1", 3), rep("Group2", 3)),
Amount = c(6, 5, 6, 2, 3, 1, 5, 4, 6, 1, 2, 2, 5, 4, 7, 3, 1, 2))
# Change into factor to have the order I need
dat$Days <- factor(dat$Days, levels = c("Monday", "Tuesday", "Wednesday"))
dat$Shift <- factor(dat$Shift, levels = c("Morning", "Evening", "Night"))
# The plot I am stuck with
# The last dot of Monday night should be linked to Tuesday morning
ggplot(data = dat, aes(x = Shift, y = Amount)) + geom_point() +
geom_line(aes(group = Group)) + facet_grid(.~Days) +
theme(panel.spacing = unit(0, "lines"))
# This is the alternative I found, but clearly not great
ggplot(data = dat, aes(x = interaction(Days, Shift, sep = "\n", lex.order = T), y = Amount)) + geom_point(aes(color = Group)) +
geom_line(aes(group = Group)) +
geom_vline(xintercept = c(3, 6, 9),
color = "darkred", linetype = 2)
а здесь почти дубликат stackoverflow.com/questions/66553823/…
Из этой ветки мудрый комментарий пользователя @gregorthomas: «Фасеты — это отдельные графы. Похоже, фасеты вам не нужны...»
@tjebo спасибо за публикацию этих тем! я их не нашел! Да, я согласен, что фасеты для отдельных графиков, но в моем случае я хотел разбить их по дням недели... Вот и запутался, как этого добиться.
Теперь я понимаю, что вы в основном ищете вложенные метки осей? Другой подход: stackoverflow.com/questions/20571306/… или stackoverflow.com/questions/44616530/…
@tjebo ВАУ! Это потрясающе! Это более простой вариант и чистый! Я не знал термина "вложенные метки осей"... Таким образом, это лучше всего решает мою проблему! Спасибо!
Я не думаю, что есть простой способ связать данные между фасетами, используя стандартный синтаксис ggplot2. Я видел подходы, которые впоследствии увеличивают его, проникая во внутренности, например. используя ggplot_build
или пакет grid
.
Ваш второй подход «подделки граней» кажется мне более простым. Это может выглядеть чище с большей настройкой. Например:
ggplot(data = dat, aes(x = interaction(Days, Shift, sep = "\n", lex.order = T),
y = Amount)) +
geom_point(aes(color = Group)) +
geom_vline(xintercept = c(3, 6, 9),
color = "darkred", linetype = 2) +
annotate("rect", xmin = c(0.5,3.5,6.5), xmax = c(3.5,6.5,9.5),
ymin = 6.4, ymax = 7, fill = "gray80", color = "gray90") +
annotate("text", x = c(2,5,8), y = 7, vjust = 1.5,
label = c("Monday", "Tuesday","Wednesday")) +
geom_vline(xintercept = c(0.5,3.5,6.5), color = "white", size = 2) +
geom_line(aes(group = Group)) +
scale_x_discrete(labels = dat$Shift, name = "Shift") +
coord_cartesian(ylim = c(0.5, 7), expand = FALSE)
Недостатком моего конкретного подхода здесь является то, что прямоугольники меток фасетов должны иметь размер в зависимости от вашего выходного разрешения, т. Е. Если вы изменяете размер вывода, вы можете, например, настроить ymin
аннотации "rect"
.
После обзора я думаю, что это считается довольно близким обманом ответа здесь. Я не приму на свой счет, если люди проголосуют за закрытие. :-) stackoverflow.com/questions/66553823/…
Спасибо! Извините, @Jon Spring, я не нашел тему, которую вы опубликовали... Я буду работать с обоими!
Другой вариант — использовать patchwork
для создания трех отдельных графиков, но установить ограничения с помощью coord_cartesian
, чтобы на график отображался только один день. К сожалению, я не нашел способа установить ограничения напрямую через coord_cartesian
, как это можно сделать через limits
аргумент шкалы, т.е. мы должны передать числовой диапазон. Как следствие, нам потребуется некоторая ручная работа, чтобы вручную вычислить числовые пределы.
library(ggplot2)
library(patchwork)
plot_fun <- function(limits) {
day <- unique(limits$Days)
breaks = as.character(limits$x)
limits <- as.numeric(unique(dat$x))[levels(dat$x) %in% limits$x]
theme_adjust <- if (!day %in% c("Monday")) {
theme(axis.text.y = element_blank(),
axis.title.y = element_blank(),
axis.line.y = element_blank(),
axis.ticks.length.y = unit(0, "pt")
)
}
labs <- if (!day == "Tuesday") labs(x = NULL) else labs(x = "Shift")
ggplot(data = dat, aes(x = x, y = Amount)) +
geom_point() +
geom_line(aes(group = Group)) +
facet_wrap(~as.character(day)) +
scale_x_discrete(breaks = breaks, labels = ~ gsub("^(.*)\\..*$", "\\1", .x), expand = c(0, .5)) +
coord_cartesian(xlim = range(limits)) +
theme_adjust +
theme(plot.margin = margin()) +
labs
}
dat$x <- interaction(dat$Shift, dat$Days)
xlims <- dat[!duplicated(dat$x), c("Days", "x")]
xlims <- split(xlims, xlims$Days)
p <- lapply(xlims, plot_fun)
p |>
wrap_plots() &
theme(panel.spacing.x = unit(0, "pt"))
Спасибо! Я никогда не использовал пакет пэчворк, но он выглядит довольно интересно! Буду копать глубже :)
связанные stackoverflow.com/questions/42151880/… и stackoverflow.com/questions/31690007/…