Wyrównaj obszary wykresu w ggplot
Próbuję użyć siatki.zorganizuj wyświetlanie wielu wykresów na tej samej stronie wygenerowanych przez ggplot. Wykresy używają tych samych danych x, ale z różnymi zmiennymi y. Wykresy wychodzą z różnych wymiarów ze względu na Y-dane o różnych skalach.
Próbowałem użyć różnych opcji motywu w ggplot2, aby zmienić rozmiar wykresu i przenieść Etykietę osi Y, ale żadna nie zadziałała, aby wyrównać wykresy. Chcę, aby działki ułożone były w kwadracie 2 x 2 tak, aby każda działka była tej samej wielkości i / align = "left" /
Oto kilka danych testowych:
A <- c(1,5,6,7,9)
B <- c(10,56,64,86,98)
C <- c(2001,3333,5678,4345,5345)
D <- c(13446,20336,24333,34345,42345)
L <- c(20,34,45,55,67)
M <- data.frame(L, A, B, C, D)
I Kod, którego używam do wykreślenia:
x1 <- ggplot(M, aes(L, A,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x2 <- ggplot(M, aes(L, B,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x3 <- ggplot(M, aes(L, C,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x4 <- ggplot(M, aes(L, D,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
grid.arrange(x1,x2,x3,x4,nrow=2)
Jeśli uruchomisz ten kod, zobaczysz, że dwie dolne działki mają mniejszy obszar działki ze względu na większą długość jednostek osi Y.
Jak sprawić, by rzeczywiste okna działkowe były takie same?
5 answers
Użyłbym fasetowania do tego problemu:
library(reshape2)
dat <- melt(M,"L") # When in doubt, melt!
ggplot(dat, aes(L,value)) +
geom_point() +
stat_smooth(method="lm") +
facet_wrap(~variable,ncol=2,scales="free")
Uwaga: laik może nie zauważyć, że skale różnią się między aspektami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-01 05:55:28
Edit
Prostsze rozwiązania to: 1) użyj pakietu cowplot
(Zobacz odpowiedź tutaj); lub 2) Użyj pakietu egg
dostępnego na GitHubie.
# devtools::install_github("baptiste/egg")
library(egg)
library(grid)
g = ggarrange(x1, x2, x3, x4, ncol = 2)
grid.newpage()
grid.draw(g)
Oryginalny
Minor edit: Aktualizacja kodu.
Jeśli chcesz zachować etykiety osi, to z pewnymi modyfikacjami i zapożyczeniem kodu z tutaj , to wystarczy.
library(ggplot2)
library(gtable)
library(grid)
library(gridExtra)
# Get the widths
gA <- ggplotGrob(x1)
gB <- ggplotGrob(x2)
gC <- ggplotGrob(x3)
gD <- ggplotGrob(x4)
maxWidth = unit.pmax(gA$widths[2:3], gB$widths[2:3],
gC$widths[2:3], gD$widths[2:3])
# Set the widths
gA$widths[2:3] <- maxWidth
gB$widths[2:3] <- maxWidth
gC$widths[2:3] <- maxWidth
gD$widths[2:3] <- maxWidth
# Arrange the four charts
grid.arrange(gA, gB, gC, gD, nrow=2)
ALTERNATYWNE ROZWIĄZANIA:
Istnieją funkcje rbind
i cbind
w gtable
pakiet do łączenia grobów w jeden grob. Dla Wykresów tutaj, szerokości powinny być ustawione za pomocą size = "max"
, ale wersja CRAN gtable
rzuca błąd.
Jedną z opcji jest sprawdzenie wykresu grid.arrange
, a następnie użycie opcji size = "first"
lub size = "last":
# Get the ggplot grobs
gA <- ggplotGrob(x1)
gB <- ggplotGrob(x2)
gC <- ggplotGrob(x3)
gD <- ggplotGrob(x4)
# Arrange the four charts
grid.arrange(gA, gB, gC, gD, nrow=2)
# Combine the plots
g = cbind(rbind(gA, gC, size = "last"), rbind(gB, gD, size = "last"), size = "first")
# draw it
grid.newpage()
grid.draw(g)
Drugą opcją jest bind
ing funkcji z gridExtra
pakietu.
# Get the ggplot grobs
gA <- ggplotGrob(x1)
gB <- ggplotGrob(x2)
gC <- ggplotGrob(x3)
gD <- ggplotGrob(x4)
# Combine the plots
g = cbind.gtable(rbind.gtable(gA, gC, size = "max"), rbind.gtable(gB, gD, size = "max"), size = "max")
# Draw it
grid.newpage()
grid.draw(g)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:00:34
To jest dokładnie ten rodzaj problemu, dla którego napisałem cowplot Pakiet. Można to zrobić w jednej linii w tym pakiecie:
require(cowplot) # loads ggplot2 as dependency
# re-create the four plots
A <- c(1,5,6,7,9)
B <- c(10,56,64,86,98)
C <- c(2001,3333,5678,4345,5345)
D <- c(13446,20336,24333,34345,42345)
L <- c(20,34,45,55,67)
M <- data.frame(L, A, B, C, D)
x1 <- ggplot(M, aes(L, A,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x2 <- ggplot(M, aes(L, B,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x3 <- ggplot(M, aes(L, C,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x4 <- ggplot(M, aes(L, D,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
# arrange into grid and align
plot_grid(x1, x2, x3, x4, align='vh')
Oto wynik: (Zauważ, że cowplot zmienia domyślny motyw ggplot2. Możesz odzyskać szarą, jeśli naprawdę chcesz.)
Jako bonus Możesz również dodać etykiety wykresu w lewym górnym rogu każdego wykresu:
plot_grid(x1, x2, x3, x4, align='vh', labels=c('A', 'B', 'C', 'D'))
Wynik:
Używam opcji labels
na praktycznie każdym grafie wieloczęściowym I make.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-04 06:24:00
Patchwork {[3] } to nowy pakiet, który ułatwia formatowanie i układ wielu ggplotów. Jedną z najlepszych rzeczy jest to, że automatycznie wyrównuje obszary działki. Dodatkowo składnia jest naprawdę łatwa.
devtools::install_github("thomasp85/patchwork")
library(patchwork)
x1 + x2 + x3 + x4 + plot_layout(ncol = 2)
Sprawdź stronę GitHub, aby uzyskać więcej przykładów: https://github.com/thomasp85/patchwork
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-10 22:53:16
Jeśli używasz RMarkdown i knitting do PDF, mam alternatywne podejście. Knitr oferuje funkcjonalność subfigurki wykresu podczas tworzenia pliku PDF, co pozwala na umieszczenie wielu figur na wykresie, z których każda ma własny podpis.
Aby to zadziałało, każda fabuła musi być wyświetlona osobno. Łącząc ze sobą kilka funkcji z pakietu cowplot
, stworzyłem następującą funkcję, która wyrównuje wykresy, zachowując je jako oddzielne obiekty:
plot_grid_split <- function(..., align = "hv", axis= "tblr"){
aligned_plots <- cowplot::align_plots(..., align=align, axis=axis)
plots <- lapply(1:length(aligned_plots), function(x){
cowplot::ggdraw(aligned_plots[[x]])
})
invisible(capture.output(plots))
}
Tutaj jest przykładem, porównując układ normalnie vs używając funkcji:
---
output: pdf_document
header-includes:
- \usepackage{subfig}
---
```{r}
plot_grid_split <- function(..., align = "hv", axis= "tblr"){
aligned_plots <- cowplot::align_plots(..., align=align, axis=axis)
plots <- lapply(1:length(aligned_plots), function(x){
cowplot::ggdraw(aligned_plots[[x]])
})
invisible(capture.output(plots))
}
```
```{r fig-sub, fig.cap='Four Plots Not Aligned', fig.subcap=c('Plot One', 'Plot Two', 'Plot Three', 'Plot Four'), out.width='.49\\linewidth', fig.asp=1, fig.ncol = 2}
library(ggplot2)
plot <- ggplot(iris, aes(Sepal.Length, Sepal.Width, colour = Species)) +
geom_point()
plot + labs(title = "A nice title")
plot + labs(caption = "A sample caption")
plot + theme(legend.position = "none")
plot + theme(legend.position = "top")
```
```{r fig-sub-2, fig.cap='Four Plots Aligned', fig.subcap=c('Plot One', 'Plot Two', 'Plot Three', 'Plot Four'), out.width='.49\\linewidth', fig.asp=1, fig.ncol = 2}
x1 <- plot + labs(title = "A nice title")
x2 <- plot + labs(caption = "A sample caption")
x3 <- plot + theme(legend.position = "none")
x4 <- plot + theme(legend.position = "top")
plot_grid_split(x1, x2, x3, x4)
```
- możesz dowiedzieć się więcej o podfigurkach w R w ten post .
- ponadto możesz sprawdzić opcje dzianiny, aby dowiedzieć się więcej o opcjach części dla podfigurek: https://yihui.name/knitr/options/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-08 13:36:25