Выровнять несколько графиков ggplot2 с сеткой
Контекст
Я хочу построить два ggplot2 на одной странице с той же легендой. http://code.google.com/p/gridextra/wiki/arrangeGrob раскрывает, как это сделать. Это уже выглядит хорошо. Но... В моем примере у меня есть два графика с одинаковой осью х и другой осью. Когда диапазон оси y по меньшей мере в 10 раз выше, чем у другого графика (например, 10000 вместо 1000), ggplot2 (или сетка?) Не выравнивает графики (см. Выход ниже).
Вопрос
Как также выровнять левую часть графика, используя две разные оси Y?
Пример кода
x = c(1, 2)
y = c(10, 1000)
data1 = data.frame(x,y)
p1 <- ggplot(data1) + aes(x=x, y=y, colour=x) + geom_line()
y = c(10, 10000)
data2 = data.frame(x,y)
p2 <- ggplot(data2) + aes(x=x, y=y, colour=x) + geom_line()
# Source: http://code.google.com/p/gridextra/wiki/arrangeGrob
leg <- ggplotGrob(p1 + opts(keep="legend_box"))
legend=gTree(children=gList(leg), cl="legendGrob")
widthDetails.legendGrob <- function(x) unit(3, "cm")
grid.arrange(
p1 + opts(legend.position="none"),
p2 + opts(legend.position="none"),
legend=legend, main ="", left = "")
Выход
![Example image]()
Ответы
Ответ 1
Если вы не против бесстыдного kludge, просто добавьте дополнительный символ к самой длинной метке в p1
, например:
p1 <- ggplot(data1) +
aes(x=x, y=y, colour=x) +
geom_line() +
scale_y_continuous(breaks = seq(200, 1000, 200),
labels = c(seq(200, 800, 200), " 1000"))
У меня есть два основных вопроса, которые, надеюсь, вы простите, если у вас есть причины:
1) Почему бы не использовать одну и ту же ось y на обоих? Я чувствую, что это более прямолинейный подход и легко достигается в приведенном выше примере, добавив scale_y_continuous(limits = c(0, 10000))
в p1
.
2) Является ли функция, предоставляемая facet_wrap
неадекватной здесь? Трудно понять, какова ваша структура данных, но вот игрушечный пример того, как я это сделаю:
library(ggplot2)
# Maybe your dataset is like this
x <- data.frame(x = c(1, 2),
y1 = c(0, 1000),
y2 = c(0, 10000))
# Molten data makes a lot of things easier in ggplot
x.melt <- melt(x, id.var = "x", measure.var = c("y1", "y2"))
# Plot it - one page, two facets, identical axes (though you could change them),
# one legend
ggplot(x.melt, aes(x = x, y = value, color = x)) +
geom_line() +
facet_wrap( ~ variable, nrow = 2)
Ответ 2
Более чистый способ сделать то же самое, но более общим способом - использовать форматтера arg:
p1 <- ggplot(data1) +
aes(x=x, y=y, colour=x) +
geom_line() +
scale_y_continuous(formatter = function(x) format(x, width = 5))
Сделайте то же самое для своего второго сюжета и убедитесь, что width >= самый широкий номер, который вы ожидаете на обоих графиках.
Ответ 3
1. Использование cowplot package:
library(cowplot)
plot_grid(p1, p2, ncol=1, align="v")
![введите описание изображения здесь]()
2. Используя tracks
из ggbio package:
Примечание: Кажется, что ошибка, х тики не выравниваются. (проверено 17/03/2016, ggbio_1.18.5)
library(ggbio)
tracks(data1=p1,data2=p2)
![enter image description here]()
Ответ 4
Решение в ggbio для вашей задачи состоит в том, чтобы зафиксировать координаты оси x для исходных графиков следующим образом:
library(ggbio)
p1 <- f()
fixed(p1) <- TRUE
p2 <- f()
fixed(p2) <- TRUE
tracks(p1,p2)
Бест,
Yatrosin