2つのグラフエッジを左揃え(ggplot)


105

ggplotを使用しており、2つのグラフを重ねて表示したいと思います。私grid.arrangeはそれらをスタックするためにgridExtraから使用しました。問題は、グラフの左端と軸ラベルに関係なく右端を揃えたいことです。(問題は、1つのグラフのラベルが短く、もう1つのグラフが長いために発生します)。

質問:
これを行うにはどうすればよいですか?私は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
ここに2つの可能なオプションがあります。ここここです。
joran

@Joran左の軸が揃うのを探しています。これらはそれを行うとは思わない。私は間違っていますが。
Tyler Rinker

回答:


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
美しく、本当にかなり簡単です。解決していただきありがとうございます。
Tyler Rinker

1
完璧なソリューション!各プロットの大幅なカスタマイズのため、ファセットでは実行できない複数の個別の時系列プロットを整列させるために、このようなものを探していました。
wahalulu 2013年

2つの列がある場合、高さを一致させる方法を提供できるように親切ですか?gA $ heights [2:3]が機能していないようです。2:3以外のグロブの要素を選択する必要がありますか?ありがとうございました!
エティエンヌローデカリー2013年

4
ソリューションBaptisteをありがとう。ただし、プロットの1つがの場合、これは機能しませんtableGrob。これgtable::cbindは私に失望するエラーを与えます:nrow(x) == nrow(y) is not TRUE。助言がありますか?
Gabra、2015

2
この解決策は私にとってうまくいきました、私はそれを理解しようとしています。何の[2:5]略ですか?
Hurlikus

38

これをいくつものプロットに一般化したかった。これは、Baptisteによるアプローチを使用した段階的なソリューションです。

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

各プロットの各グロブの幅を収集する

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)

各グロブに最大幅を割り当てます

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

プロット

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

2
プロットにさまざまな幅の凡例がある場合でも機能します-とてもいいです!
Keith Hughitt、2016

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
using size="first"は、2番目のプロットが最初のプロットよりも大きい場合、配置があまりよく見えないことを意味します
baptiste

10

このeggパッケージは、ggplotオブジェクトを標準化されたgtableにラップし、3x3ファセットされたものを含む任意のggplot間のプロットパネルの配置を可能にします。

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)。しかし、cowplotかgridExtra::grid.arrangeさえも元を行うことができなかったので、これはこれまでの最高の作品
deeenes

8

次にmelt、reshape2パッケージから使用する別の可能なソリューションを示します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ではそれは真実ですが、現実ではありません。
Tyler Rinker

理解できません。CO2$ PlantとCO2 $ Typeはたまたま同じ長さですが、実際のデータはそうではありませんか?
bdemarest

1つの変数を共有するのは2つの異なるデータセットであるため、行数は同じではありません。
Tyler Rinker

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

reprexパッケージ(v0.3.0)によって2019-12-08に作成されました


0

せいぜいこれはハックです:

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

それは本当に間違っていると感じています。


-1

これは古い投稿であり、既に回答済みであることは知っていますが、@ baptisteのアプローチを組み合わせpurrrて見栄えを良くすることをお勧めします。

library(purrr)
list(A, B) %>% 
  map(ggplotGrob) %>% 
  do.call(gridExtra::gtable_rbind, .) %>% 
  grid::grid.draw()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.