23

コンテクスト

いくつかのデータセット/変数があり、それらをプロットしたいのですが、これをコンパクトに実行したいと思います。これを行うには、同じy軸で異なるx軸を共有する必要があります。また、分布が異なるため、x軸の1つを対数スケーリングし、もう1つを線形スケーリングする必要があります。

ロングテール変数があるとします(プロット時にx軸をログスケールにしたい):

library(PtProcess)
library(ggplot2)

set.seed(1)
lambda <- 1.5
a <- 1
pareto <- rpareto(1000,lambda=lambda,a=a)
x_pareto <- seq(from=min(pareto),to=max(pareto),length=1000)
y_pareto <- 1-ppareto(x_pareto,lambda,a)
df1 <- data.frame(x=x_pareto,cdf=y_pareto)

ggplot(df1,aes(x=x,y=cdf)) + geom_line() + scale_x_log10()

ロングテール

そして正規変数:

set.seed(1)
mean <- 3
norm <- rnorm(1000,mean=mean)
x_norm <- seq(from=min(norm),to=max(norm),length=1000)
y_norm <- pnorm(x_norm,mean=mean)
df2 <- data.frame(x=x_norm,cdf=y_norm)

ggplot(df2,aes(x=x,y=cdf)) + geom_line()

普通

同じy軸を使用してそれらを並べてプロットしたいと思います。

試行#1

ファセットを使用してこれを行うことができます。これは見栄えがしますが、各x軸を異なるスケールで作成する方法がわかりません(scale_x_log10()両方を対数スケールにします)。

df1 <- cbind(df1,"pareto")
colnames(df1)[3] <- 'var'
df2 <- cbind(df2,"norm")
colnames(df2)[3] <- 'var'
df <- rbind(df1,df2)

ggplot(df,aes(x=x,y=cdf)) + geom_line() + 
       facet_wrap(~var,scales="free_x") + scale_x_log10()

ファセットの試み

試行#2

を使用grid.arrangeしますが、両方のプロット領域を同じアスペクト比に保つ方法がわかりません。

library(gridExtra)
p1 <- ggplot(df1,aes(x=x,y=cdf)) + geom_line() + scale_x_log10() +
      theme(plot.margin = unit(c(0,0,0,0), "lines"),
            plot.background = element_blank()) +
      ggtitle("pareto")
p2 <- ggplot(df2,aes(x=x,y=cdf)) + geom_line() + 
      theme(axis.text.y = element_blank(), 
            axis.ticks.y = element_blank(), 
            axis.title.y = element_blank(),
            plot.margin = unit(c(0,0,0,0), "lines"),
            plot.background = element_blank()) +
      ggtitle("norm")
grid.arrange(p1,p2,ncol=2)

グリッドの試み

PS:プロットの数は変わる可能性があるので、特に2つのプロットの答えを探しているわけではありません

4

3 に答える 3

11

あなたの試み#2を延長するgtableことは、あなたを助けることができるかもしれません。2つのグラフでマージンが同じである場合、2つのプロットで変化する幅は(私が思うに)y軸の目盛りラベルと軸のテキストが占めるスペースだけであり、これによりパネルの幅が変化します。 。ここからのコードを使用すると、軸テキストがとるスペースは同じである必要があります。したがって、2つのパネル領域の幅は同じである必要があり、したがってアスペクト比は同じである必要があります。ただし、結果(右側に余白がない)はきれいに見えません。そこで、p2の右側に少しマージンを追加し、p2の左側に同じ量を削除しました。p1についても同様です。左側に少し追加しましたが、右側に同じ量を削除しました。

library(PtProcess)
library(ggplot2)
library(gtable)
library(grid)
library(gridExtra)

set.seed(1)
lambda <- 1.5
a <- 1
pareto <- rpareto(1000,lambda=lambda,a=a)
x_pareto <- seq(from=min(pareto),to=max(pareto),length=1000)
y_pareto <- 1-ppareto(x_pareto,lambda,a)
df1 <- data.frame(x=x_pareto,cdf=y_pareto)

set.seed(1)
mean <- 3
norm <- rnorm(1000,mean=mean)
x_norm <- seq(from=min(norm),to=max(norm),length=1000)
y_norm <- pnorm(x_norm,mean=mean)
df2 <- data.frame(x=x_norm,cdf=y_norm)

p1 <- ggplot(df1,aes(x=x,y=cdf)) + geom_line() + scale_x_log10() +
      theme(plot.margin = unit(c(0,-.5,0,.5), "lines"),
            plot.background = element_blank()) +
      ggtitle("pareto")
p2 <- ggplot(df2,aes(x=x,y=cdf)) + geom_line() + 
      theme(axis.text.y = element_blank(), 
            axis.ticks.y = element_blank(), 
            axis.title.y = element_blank(),
            plot.margin = unit(c(0,1,0,-1), "lines"),
            plot.background = element_blank()) +
      ggtitle("norm")

gt1 <- ggplotGrob(p1)
gt2 <- ggplotGrob(p2)

newWidth = unit.pmax(gt1$widths[2:3], gt2$widths[2:3])

gt1$widths[2:3] = as.list(newWidth)
gt2$widths[2:3] = as.list(newWidth)

grid.arrange(gt1, gt2, ncol=2)

ここに画像の説明を入力してください

編集 右側に3番目のプロットを追加するには、プロットキャンバスをさらに制御する必要があります。1つの解決策は、3つのプロット用のスペースと右マージン用の追加スペースを含む新しいgtableを作成することです。ここでは、プロットの余白にプロット間の間隔を考慮させます。

p1 <- ggplot(df1,aes(x=x,y=cdf)) + geom_line() + scale_x_log10() +
      theme(plot.margin = unit(c(0,-2,0,0), "lines"),
            plot.background = element_blank()) +
      ggtitle("pareto")
p2 <- ggplot(df2,aes(x=x,y=cdf)) + geom_line() + 
      theme(axis.text.y = element_blank(), 
            axis.ticks.y = element_blank(), 
            axis.title.y = element_blank(),
            plot.margin = unit(c(0,-2,0,0), "lines"),
            plot.background = element_blank()) +
      ggtitle("norm")

gt1 <- ggplotGrob(p1)
gt2 <- ggplotGrob(p2)

newWidth = unit.pmax(gt1$widths[2:3], gt2$widths[2:3])

gt1$widths[2:3] = as.list(newWidth)
gt2$widths[2:3] = as.list(newWidth)

 # New gtable with space for the three plots plus a right-hand margin
gt = gtable(widths = unit(c(1, 1, 1, .3), "null"), height = unit(1, "null"))

# Instert gt1, gt2 and gt2 into the new gtable
gt <- gtable_add_grob(gt, gt1, 1, 1)
gt <- gtable_add_grob(gt, gt2, 1, 2)
gt <- gtable_add_grob(gt, gt2, 1, 3)

grid.newpage()
grid.draw(gt)

ここに画像の説明を入力してください

于 2013-02-07T12:29:39.913 に答える
7

受け入れられた答えは、Rを使用してプロットすることになると、まさに人々を走らせるものです!これが私の解決策です:

library('grid')
g1 <- ggplot(...)  # however you draw your 1st plot
g2 <- ggplot(...)  # however you draw your 2nd plot
grid.newpage()
grid.draw(cbind(ggplotGrob(g1), ggplotGrob(g2), size = "last"))

これにより、y軸(マイナーおよびメジャー)のガイドラインが処理され、複数のプロットに簡単に配置できます。

いくつかの軸テキストの削除、凡例の統合、...は、個々のプロットを作成するとき、またはグリッドまたはgridExtraパッケージによって提供される他の手段を使用することによって処理できる他のタスクです。

于 2019-08-10T23:47:04.147 に答える
1

受け入れられた答えは私には少し気が遠くなるように見えます。だから私はより少ない労力でそれを回避する2つの方法を見つけます。grid.arrange()どちらも、試行#2の方法に基づいています。

1.プロット1をy軸なしにします
theme(axis.text.y = element_blank(), 
      axis.ticks.y = element_blank(), 
      axis.title.y = element_blank()

したがって、すべてのプロットは同じになります。さまざまなアスペクト比で問題が発生することはありません。Rまたはお気に入りの画像編集アプリを使用して別のy軸を生成する必要があります。

2.アスペクト比を修正して尊重する

個々のプロットaspect.ratio = 1に、または任意の比率を追加します。theme()その後、あなたので使用respect=TRUEしますgrid.arrange()

このようにして、plot1でy軸を維持し、すべてのプロットでアスペクト比を維持できます。この答えに触発されました。

これらがお役に立てば幸いです。

于 2020-12-24T02:33:25.883 に答える