बाएँ दो ग्राफ़ किनारों (ggplot) को संरेखित करें


105

मैं ggplot का उपयोग कर रहा हूं और दो ग्राफ़ हैं जिन्हें मैं एक दूसरे के ऊपर प्रदर्शित करना चाहता हूं। मैंने grid.arrangeउन्हें ढेर करने के लिए ग्रिडएक्स्ट्रा का इस्तेमाल किया । समस्या यह है कि मैं चाहता हूं कि ग्राफ के बाएं किनारों को संरेखित किया जाए और साथ ही अक्ष के लेबल की परवाह किए बिना सही किनारों को संरेखित किया जाए। (समस्या इसलिए पैदा होती है क्योंकि एक ग्राफ के लेबल छोटे होते हैं जबकि दूसरे लंबे होते हैं)।

प्रश्न:
मैं यह कैसे कर सकता हूं? मैं ग्रिड से शादी नहीं कर रहा हूं। लेकिन ggplot2 बहुत जरूरी है।

मैंने जो कोशिश की है:
मैंने चौड़ाई और ऊँचाई के साथ-साथ ncol और nrow से खेलने की कोशिश की और 2 x 2 ग्रिड बनाने के लिए और दृश्यों को विपरीत कोनों में रखा और फिर चौड़ाई के साथ खेला लेकिन मुझे विपरीत कोनों में दृश्य नहीं मिल सके ।

require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
grid.arrange(A, B, ncol=1)

यहां छवि विवरण दर्ज करें


2
यहां दो संभावित विकल्प हैं: यहां और यहां
१an

@Joran मैं बाएँ कुल्हाड़ियों को संरेखित करने के लिए देख रहा हूँ। मुझे नहीं लगता कि ये करेंगे। मैं हालांकि गलत होना चाहूंगा।
टायलर रिंचर

जवाबों:


132

इसे इस्तेमाल करे,

 gA <- ggplotGrob(A)
 gB <- ggplotGrob(B)
 maxWidth = grid::unit.pmax(gA$widths[2:5], gB$widths[2:5])
 gA$widths[2:5] <- as.list(maxWidth)
 gB$widths[2:5] <- as.list(maxWidth)
 grid.arrange(gA, gB, ncol=1)

संपादित करें

rbind.gtableइसमें शामिल एक संशोधित संस्करण का उपयोग करके एक अधिक सामान्य समाधान (किसी भी संख्या में भूखंडों के साथ काम करता है) किया गया हैgridExtra

gA <- ggplotGrob(A)
gB <- ggplotGrob(B)
grid::grid.newpage()
grid::grid.draw(rbind(gA, gB))

3
सुंदर और वास्तव में बहुत सीधे आगे। समाधान के लिए धन्यवाद।
टायलर रिंचर

1
सही समाधान! मैं कई अलग-अलग समय-श्रृंखला भूखंडों को संरेखित करने के लिए इस तरह की चीज की तलाश कर रहा हूं जो कि प्रत्येक भूखंड में प्रमुख अनुकूलन के कारण मैं ऐसा नहीं कर सकता।

यदि आप दो कॉलम हैं, तो क्या आप यह बताने के लिए दयालु होंगे कि हेग से मिलान करने का तरीका क्या होगा? जीए $ हाइट्स [2: 3] काम करने के लिए नहीं लगता है। क्या मुझे 2: 3 की तुलना में grob के किसी अन्य तत्व का चयन करना है? धन्यवाद!
एटिएन लो-डेकेरी

4
आप अपने समाधान बैपटिस्ट के लिए धन्यवाद। हालांकि, मुझे यह काम करने के लिए नहीं मिलता है जब भूखंडों में से एक है tableGrobgtable::cbindमुझे एक निराशाजनक त्रुटि देता है: nrow(x) == nrow(y) is not TRUE। कोई सुझाव?
गबरा

2
इस समाधान ने मेरे लिए काम किया, मैं इसे समझने की कोशिश कर रहा हूं। किसलिए [2:5]खड़ा है?
हर्लिकस

38

मैं किसी भी संख्या में भूखंडों के लिए इसका सामान्यीकरण करना चाहता था। यहां बैपटिस्ट द्वारा दृष्टिकोण का उपयोग करके एक चरण-दर-चरण समाधान है:

plots <- list(A, B, C, D)
grobs <- list()
widths <- list()

प्रत्येक भूखंड के प्रत्येक grob के लिए चौड़ाई एकत्र करें

for (i in 1:length(plots)){
    grobs[[i]] <- ggplotGrob(plots[[i]])
    widths[[i]] <- grobs[[i]]$widths[2:5]
}

अधिकतम चौड़ाई प्राप्त करने के लिए do.call का उपयोग करें

maxwidth <- do.call(grid::unit.pmax, widths)

प्रत्येक grob के लिए अधिकतम चौड़ाई असाइन करें

for (i in 1:length(grobs)){
     grobs[[i]]$widths[2:5] <- as.list(maxwidth)
}

भूखंड

do.call("grid.arrange", c(grobs, ncol = 1))

2
यहां तक ​​कि काम करता है जब भूखंडों में अलग-अलग चौड़ाई के किंवदंतियां होती हैं - बहुत अच्छा!
कीथ ह्यूजिट

30

काउप्लॉट पैकेज का उपयोग करना :

A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 

library(cowplot)
plot_grid(A, B, ncol=1, align="v")

यहां छवि विवरण दर्ज करें


12

पर http://rpubs.com/MarkusLoew/13295 एक बहुत आसान समाधान उपलब्ध (अंतिम आइटम) इस समस्या का एप्लाइड है:

require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
grid.draw(rbind(ggplotGrob(A), ggplotGrob(B), size="first"))

आप इसका उपयोग चौड़ाई और ऊंचाई दोनों के लिए भी कर सकते हैं:

require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
C <- ggplot(CO2, aes(x=conc)) + geom_bar() +coord_flip()
D <- ggplot(CO2, aes(x=uptake)) + geom_bar() +coord_flip() 
grid.draw(cbind(
            rbind(ggplotGrob(A), ggplotGrob(B), size="first"),
            rbind(ggplotGrob(C), ggplotGrob(D), size="first"),
            size='first'))

2
size="first"यदि दूसरा प्लॉट पहले से बड़ा है तो एलाइनमेंट का उपयोग बहुत अच्छा नहीं लगेगा
बपतिस्मा देने वाला

10

eggपैकेज wraps ggplot एक मानकीकृत में वस्तुओं 3x3gtable, facetted भी शामिल होते हैं मनमाना ggplots, के बीच साजिश पैनल के संरेखण सक्षम करने से।

library(egg) # devtools::install_github('baptiste/egg')
library(ggplot2)

p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point() 

p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point() + facet_wrap( ~ cyl, ncol=2, scales = "free") +
  guides(colour="none") +
  theme()

ggarrange(p1, p2)

यहां छवि विवरण दर्ज करें


मेरे लिए यह ठीक से क्षैतिज रूप से एक साधारण हीटमैप ( geom_tile) तल पर किंवदंती और एक बहुमुखी हीटमैप ( facet_gridसाथ geom_tile) की व्यवस्था कर सकता है , लेकिन तीसरे प्लॉट की ऊंचाई को संरेखित करने में विफल रहा, जो एक डेंड्रोग्राम ( geom_segment) था। हालाँकि, काउप्लॉट या gridExtra::grid.arrangeपूर्व भी नहीं कर पाए थे, इसलिए यह अब तक का सबसे अच्छा काम करता है
'

8

यहाँ meltreshape2 पैकेज का उपयोग कर एक और संभावित समाधान है , और facet_wrap:

library(ggplot2)
library(reshape2)

dat = CO2[, c(1, 2)]
dat$id = seq(nrow(dat))
mdat = melt(dat, id.vars="id")

head(mdat)
#   id variable value
# 1  1    Plant   Qn1
# 2  2    Plant   Qn1
# 3  3    Plant   Qn1
# 4  4    Plant   Qn1
# 5  5    Plant   Qn1
# 6  6    Plant   Qn1

plot_1 = ggplot(mdat, aes(x=value)) + 
         geom_bar() + 
         coord_flip() +
         facet_wrap(~ variable, nrow=2, scales="free", drop=TRUE)

ggsave(plot=plot_1, filename="plot_1.png", height=4, width=6)

यहां छवि विवरण दर्ज करें


यह समाधान मानता है कि आपके पास प्रत्येक कॉलम में समान पंक्तियाँ हैं। मेरे MRWE में यह सच है लेकिन वास्तविकता में नहीं।
टायलर रिंकर

मुझे यकीन नहीं है मैं समझता हूं: क्या आपका मतलब है कि सीओ 2 $ प्लांट और सीओ 2 $ प्रकार एक ही लंबाई के होते हैं, लेकिन यह कि आपका वास्तविक डेटा ऐसा नहीं है?
बेडेमारेस्ट 21

यह दो अलग-अलग डेटा सेट हैं जो एक चर को साझा करते हैं इसलिए पंक्तियों की संख्या समान नहीं है।
टायलर रिंकर

2

पैचवर्क पैकेज डिफ़ॉल्ट रूप से इस संभालता है:

library(ggplot2)
library(patchwork)

A <- ggplot(CO2, aes(x = Plant)) + geom_bar() + coord_flip() 
B <- ggplot(CO2, aes(x = Type)) + geom_bar() + coord_flip() 

A / B

2019-12-08 को रेप्रेक्स पैकेज (v0.3.0) द्वारा बनाया गया


0

सबसे अच्छा यह एक हैक है:

library(wq)
layOut(list(A, 1, 2:16),  list(B, 2:3, 1:16))

हालांकि यह वास्तव में गलत लगता है।


-1

मुझे पता है कि यह एक पुरानी पोस्ट है, और यह पहले ही उत्तर दिया जा चुका है, लेकिन क्या मैं @ बैपटिस्ट के दृष्टिकोण के साथ संयोजन करने का सुझाव दे सकता हूं purrr इसे इसे अच्छा बनाने :

library(purrr)
list(A, B) %>% 
  map(ggplotGrob) %>% 
  do.call(gridExtra::gtable_rbind, .) %>% 
  grid::grid.draw()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.