Это очень интересный вопрос.Вот один из способов подойти к этому: вместо использования вертикально расположенного столбчатого графика и последующего переворачивания его по горизонтали, мы можем просто создать «обычный» график, где столбцы располагаются рядом друг с другом и имеют одинаковую высоту, но каждый столбец имеетпеременная ширина, которая равна продолжительности желаемых интервалов времени.Мы можем «обрезать» фон, используя coord_fixed(expand = FALSE)
.
. Вероятно, будет лучше, если мы напрямую укажем положение оси x на ggplot()
, чтобы мы могли использовать их для размещения меток (более подробно очто позже) - вот как расположить интервалы для вашей временной шкалы:
Пусть X i обозначает расстояние (вдоль оси x) от начала координат доцентр каждого временного интервала i .Для каждого интервала i , X i представляет собой сумму длин предыдущих интервалов времени X 0 : X i - 1 , плюс половина длины X i .Мы можем сделать так, чтобы R автоматически генерировал эти значения для нас, добавив столбец, который использует накопленную накопленную сумму, как вы увидите ниже.
Я оставил panel.background = element_blank()
закомментированным, чтобы вы могли подтвердить, что мы делаемдействительно получить «только временную шкалу», без фона.
Код:
library("tidyverse")
mytheme <- theme(
axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.title.y=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
#panel.background = element_blank()
)
Name <- c("One", "Two", "Three", "Four")
Value <- c(2, 5, 7, 8)
df <- data.frame(Name, Value) %>%
mutate(Name = factor(Name, levels = Name),
xPos = cumsum(lag(Value, default = 0)) + Value/2) # calculate interval position
ggplot(data = df, aes(x = xPos, y = 1, width = Value, fill = Name)) +
geom_col(position = "identity",
show.legend = FALSE) +
geom_text(aes(label = Name),
position = position_fill(vjust = 0.5)) +
coord_fixed(expand = FALSE) + # crop background around geom_col()
mytheme
Вывод:
Почему это работает:
Начиная с ggplot2
версии 3.1.0, мы изначально оказались между молотом и наковальней: если мы решим использовать coord_flip()
, мы можем получить горизонтальную временную шкалу, но мыне может (легко) изменить размеры нашей области построения, чтобы получить нужные размеры.Если вместо этого мы используем coord_fixed(expand = FALSE)
, у нас есть желаемые поля рисования, но мы не можем легко сделать горизонтальный «стек» баров, так как coord_fixed()
несовместим с coord_flip()
.
Есть интересный аргументназывается position_dodge2()
, который вы можете использовать с geom_col()
для размещения стержней переменной ширины рядом друг с другом.Если вы установите padding = 0
, вы можете получить график, который выглядит очень похоже на то, что вы видите выше, но фактические "x-координаты" каждого интервала будут начинаться с левого края каждого бара, в отличие от центра.
Это делает центрирование текстовых меток очень трудным, поскольку нам нужно было бы отрегулировать их расположение в зависимости от ширины каждого интервала, но параметры ggplot2
, такие как position_nudge()
, позволяют нам регулировать только все этикеток на некоторое постоянное количество.Следовательно, мы указываем центр каждого временного интервала напрямую.Надеемся, что по мере улучшения ggplot2
мы увидим, что такие опции, как position_nudge()
, расширят функциональные возможности для более простого решения этой проблемы!