Saya memiliki dua ggplots yang saya sejajarkan secara horizontal grid.arrange
. Saya telah melihat-lihat banyak posting forum, tetapi semua yang saya coba tampaknya merupakan perintah yang sekarang diperbarui dan diberi nama yang lain.
Data saya terlihat seperti ini;
# Data plot 1
axis1 axis2
group1 -0.212201 0.358867
group2 -0.279756 -0.126194
group3 0.186860 -0.203273
group4 0.417117 -0.002592
group1 -0.212201 0.358867
group2 -0.279756 -0.126194
group3 0.186860 -0.203273
group4 0.186860 -0.203273
# Data plot 2
axis1 axis2
group1 0.211826 -0.306214
group2 -0.072626 0.104988
group3 -0.072626 0.104988
group4 -0.072626 0.104988
group1 0.211826 -0.306214
group2 -0.072626 0.104988
group3 -0.072626 0.104988
group4 -0.072626 0.104988
#And I run this:
library(ggplot2)
library(gridExtra)
groups=c('group1','group2','group3','group4','group1','group2','group3','group4')
x1=data1[,1]
y1=data1[,2]
x2=data2[,1]
y2=data2[,2]
p1=ggplot(data1, aes(x=x1, y=y1,colour=groups)) + geom_point(position=position_jitter(w=0.04,h=0.02),size=1.8)
p2=ggplot(data2, aes(x=x2, y=y2,colour=groups)) + geom_point(position=position_jitter(w=0.04,h=0.02),size=1.8)
#Combine plots
p3=grid.arrange(
p1 + theme(legend.position="none"), p2+ theme(legend.position="none"), nrow=1, widths = unit(c(10.,10), "cm"), heights = unit(rep(8, 1), "cm")))
Bagaimana cara mengekstrak legenda dari salah satu plot ini dan menambahkannya ke bagian bawah / tengah plot gabungan?
Jawaban:
Perbarui 2015-Feb
Lihat jawaban Steven di bawah
df1 <- read.table(text="group x y group1 -0.212201 0.358867 group2 -0.279756 -0.126194 group3 0.186860 -0.203273 group4 0.417117 -0.002592 group1 -0.212201 0.358867 group2 -0.279756 -0.126194 group3 0.186860 -0.203273 group4 0.186860 -0.203273",header=TRUE) df2 <- read.table(text="group x y group1 0.211826 -0.306214 group2 -0.072626 0.104988 group3 -0.072626 0.104988 group4 -0.072626 0.104988 group1 0.211826 -0.306214 group2 -0.072626 0.104988 group3 -0.072626 0.104988 group4 -0.072626 0.104988",header=TRUE) library(ggplot2) library(gridExtra) p1 <- ggplot(df1, aes(x=x, y=y,colour=group)) + geom_point(position=position_jitter(w=0.04,h=0.02),size=1.8) + theme(legend.position="bottom") p2 <- ggplot(df2, aes(x=x, y=y,colour=group)) + geom_point(position=position_jitter(w=0.04,h=0.02),size=1.8) #extract legend #https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs g_legend<-function(a.gplot){ tmp <- ggplot_gtable(ggplot_build(a.gplot)) leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box") legend <- tmp$grobs[[leg]] return(legend)} mylegend<-g_legend(p1) p3 <- grid.arrange(arrangeGrob(p1 + theme(legend.position="none"), p2 + theme(legend.position="none"), nrow=1), mylegend, nrow=2,heights=c(10, 1))
Berikut adalah plot yang dihasilkan:
sumber
arrangeGrob()
. Anda juga perlu membalik ketinggian (yaituheights=c(1,10)
Anda juga dapat menggunakan ggarrange dari paket ggpubr dan menyetel "common.legend = TRUE":
library(ggpubr) dsamp <- diamonds[sample(nrow(diamonds), 1000), ] p1 <- qplot(carat, price, data = dsamp, colour = clarity) p2 <- qplot(cut, price, data = dsamp, colour = clarity) p3 <- qplot(color, price, data = dsamp, colour = clarity) p4 <- qplot(depth, price, data = dsamp, colour = clarity) ggarrange(p1, p2, p3, p4, ncol=2, nrow=2, common.legend = TRUE, legend="bottom")
sumber
print(ggarrangeobject)
salah satuggarrange
objek saya ketika saya membutuhkannya untuk diplot oleh beberapa fungsi lain, yang mungkin mirip dengan solusi untuk AndarenderPlot()
?common.legend = TRUE
hanya itu yang saya butuhkan!Jawaban Roland perlu diperbarui. Lihat: https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
Metode ini telah diperbarui untuk ggplot2 v1.0.0.
library(ggplot2) library(gridExtra) library(grid) grid_arrange_shared_legend <- function(...) { plots <- list(...) g <- ggplotGrob(plots[[1]] + theme(legend.position="bottom"))$grobs legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]] lheight <- sum(legend$height) grid.arrange( do.call(arrangeGrob, lapply(plots, function(x) x + theme(legend.position="none"))), legend, ncol = 1, heights = unit.c(unit(1, "npc") - lheight, lheight)) } dsamp <- diamonds[sample(nrow(diamonds), 1000), ] p1 <- qplot(carat, price, data=dsamp, colour=clarity) p2 <- qplot(cut, price, data=dsamp, colour=clarity) p3 <- qplot(color, price, data=dsamp, colour=clarity) p4 <- qplot(depth, price, data=dsamp, colour=clarity) grid_arrange_shared_legend(p1, p2, p3, p4)
Perhatikan kekurangan
ggplot_gtable
danggplot_build
.ggplotGrob
digunakan sebagai gantinya. Contoh ini sedikit lebih berbelit-belit daripada solusi di atas tetapi masih menyelesaikannya untuk saya.sumber
grid_arrange_shared_legend
? Terima kasih!ncol = 1
?Solusi baru yang menarik sedang digunakan
patchwork
. Sintaksnya sangat sederhana:library(ggplot2) library(patchwork) p1 <- ggplot(df1, aes(x = x, y = y, colour = group)) + geom_point(position = position_jitter(w = 0.04, h = 0.02), size = 1.8) p2 <- ggplot(df2, aes(x = x, y = y, colour = group)) + geom_point(position = position_jitter(w = 0.04, h = 0.02), size = 1.8) combined <- p1 + p2 & theme(legend.position = "bottom") combined + plot_layout(guides = "collect")
Dibuat pada 2019-12-13 oleh paket reprex (v0.2.1)
sumber
combined <- p1 + p2 + plot_layout(guides = "collect") & theme(legend.position = "bottom")
Saya sarankan menggunakan cowplot. Dari sketsa R mereka :
# load cowplot library(cowplot) # down-sampled diamonds data set dsamp <- diamonds[sample(nrow(diamonds), 1000), ] # Make three plots. # We set left and right margins to 0 to remove unnecessary spacing in the # final plot arrangement. p1 <- qplot(carat, price, data=dsamp, colour=clarity) + theme(plot.margin = unit(c(6,0,6,0), "pt")) p2 <- qplot(depth, price, data=dsamp, colour=clarity) + theme(plot.margin = unit(c(6,0,6,0), "pt")) + ylab("") p3 <- qplot(color, price, data=dsamp, colour=clarity) + theme(plot.margin = unit(c(6,0,6,0), "pt")) + ylab("") # arrange the three plots in a single row prow <- plot_grid( p1 + theme(legend.position="none"), p2 + theme(legend.position="none"), p3 + theme(legend.position="none"), align = 'vh', labels = c("A", "B", "C"), hjust = -1, nrow = 1 ) # extract the legend from one of the plots # (clearly the whole thing only makes sense if all plots # have the same legend, so we can arbitrarily pick one.) legend_b <- get_legend(p1 + theme(legend.position="bottom")) # add the legend underneath the row we made earlier. Give it 10% of the height # of one plot (via rel_heights). p <- plot_grid( prow, legend_b, ncol = 1, rel_heights = c(1, .2)) p
sumber
annotate_figure(ggarrange())
, menggunakan legend_b (). Terima kasih banyak, tuhan memberkati Anda!@Giuseppe, Anda mungkin ingin mempertimbangkan ini untuk spesifikasi yang fleksibel dari pengaturan plot (dimodifikasi dari sini ):
library(ggplot2) library(gridExtra) library(grid) grid_arrange_shared_legend <- function(..., nrow = 1, ncol = length(list(...)), position = c("bottom", "right")) { plots <- list(...) position <- match.arg(position) g <- ggplotGrob(plots[[1]] + theme(legend.position = position))$grobs legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]] lheight <- sum(legend$height) lwidth <- sum(legend$width) gl <- lapply(plots, function(x) x + theme(legend.position = "none")) gl <- c(gl, nrow = nrow, ncol = ncol) combined <- switch(position, "bottom" = arrangeGrob(do.call(arrangeGrob, gl), legend, ncol = 1, heights = unit.c(unit(1, "npc") - lheight, lheight)), "right" = arrangeGrob(do.call(arrangeGrob, gl), legend, ncol = 2, widths = unit.c(unit(1, "npc") - lwidth, lwidth))) grid.newpage() grid.draw(combined) }
Argumen tambahan
nrow
danncol
kontrol tata letak plot yang diatur:dsamp <- diamonds[sample(nrow(diamonds), 1000), ] p1 <- qplot(carat, price, data = dsamp, colour = clarity) p2 <- qplot(cut, price, data = dsamp, colour = clarity) p3 <- qplot(color, price, data = dsamp, colour = clarity) p4 <- qplot(depth, price, data = dsamp, colour = clarity) grid_arrange_shared_legend(p1, p2, p3, p4, nrow = 1, ncol = 4) grid_arrange_shared_legend(p1, p2, p3, p4, nrow = 2, ncol = 2)
sumber
Jika Anda memplot variabel yang sama di kedua plot, cara paling sederhana adalah menggabungkan bingkai data menjadi satu, lalu gunakan facet_wrap.
Sebagai contoh Anda:
big_df <- rbind(df1,df2) big_df <- data.frame(big_df,Df = rep(c("df1","df2"), times=c(nrow(df1),nrow(df2)))) ggplot(big_df,aes(x=x, y=y,colour=group)) + geom_point(position=position_jitter(w=0.04,h=0.02),size=1.8) + facet_wrap(~Df)
Contoh lain menggunakan kumpulan data berlian. Ini menunjukkan bahwa Anda bahkan dapat membuatnya berfungsi jika Anda hanya memiliki satu variabel yang sama di antara plot Anda.
diamonds_reshaped <- data.frame(price = diamonds$price, independent.variable = c(diamonds$carat,diamonds$cut,diamonds$color,diamonds$depth), Clarity = rep(diamonds$clarity,times=4), Variable.name = rep(c("Carat","Cut","Color","Depth"),each=nrow(diamonds))) ggplot(diamonds_reshaped,aes(independent.variable,price,colour=Clarity)) + geom_point(size=2) + facet_wrap(~Variable.name,scales="free_x") + xlab("")
Hanya hal rumit dengan contoh kedua adalah bahwa variabel faktor dipaksa menjadi numerik saat Anda menggabungkan semuanya ke dalam satu bingkai data. Jadi idealnya, Anda akan melakukan ini terutama ketika semua variabel yang Anda minati memiliki tipe yang sama.
sumber
@Bayu_joo
Saya tidak tahu Grobs dll apa pun, tetapi saya meretas solusi untuk dua plot, harus memungkinkan untuk diperluas ke nomor arbitrer tetapi tidak dalam fungsi seksi:
plots <- list(p1, p2) g <- ggplotGrob(plots[[1]] + theme(legend.position="bottom"))$grobs legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]] lheight <- sum(legend$height) tmp <- arrangeGrob(p1 + theme(legend.position = "none"), p2 + theme(legend.position = "none"), layout_matrix = matrix(c(1, 2), nrow = 1)) grid.arrange(tmp, legend, ncol = 1, heights = unit.c(unit(1, "npc") - lheight, lheight))
sumber
Jika legenda sama untuk kedua plot, ada solusi sederhana yang digunakan
grid.arrange
(dengan asumsi Anda ingin legenda Anda sejajar dengan kedua plot baik secara vertikal maupun horizontal). Cukup pertahankan legenda untuk plot paling bawah atau paling kanan sambil menghilangkan legenda untuk plot lainnya. Namun, menambahkan legenda ke satu plot saja, mengubah ukuran satu plot relatif terhadap plot lainnya. Untuk menghindari hal ini, gunakanheights
perintah untuk menyesuaikan secara manual dan menyimpannya dalam ukuran yang sama. Anda bahkan dapat menggunakangrid.arrange
untuk membuat judul sumbu yang umum. Perhatikan bahwa ini akan membutuhkanlibrary(grid)
tambahanlibrary(gridExtra)
. Untuk plot vertikal:y_title <- expression(paste(italic("E. coli"), " (CFU/100mL)"))
grid.arrange(arrangeGrob(p1, theme(legend.position="none"), ncol=1), arrangeGrob(p2, theme(legend.position="bottom"), ncol=1), heights=c(1,1.2), left=textGrob(y_title, rot=90, gp=gpar(fontsize=20)))
Berikut adalah hasil untuk grafik serupa untuk proyek yang saya kerjakan:
sumber