2017-10-24 18 views
4

ggplot密度プロットに幾何学を追加したいが、データの表示制限を変更せずに、カスタムコードで必要な制限を計算する必要もない。例与えるために:私はへのプロットをトリミングしたい Actual output :最初のプロットでggplot2:制限に影響を与えずにgeomを追加する

set.seed(12345) 
N = 1000 
d = data.frame(measured = ifelse(rbernoulli(N, 0.5), rpois(N, 100), rpois(N,1))) 
d$fit = dgeom(d$measured, 0.6) 
ggplot(d, aes(x = measured)) + geom_density() + geom_line(aes(y = fit), color = "blue") 

ggplot(d, aes(x = measured)) + geom_density() + geom_line(aes(y = fit), color = "blue") + coord_cartesian(ylim = c(0,0.025)) 

を、(かなりひどく「測定」データをフィット)適合曲線は、測定データの形状が不明瞭最初GEOMからのすべてのデータが含まれていますが、2番目のプロットのように、フィットカーブをトリミング:

    :私は coord_cartesianと2番目のプロットを生成することができますが Desired output

    が、これは2つの欠点を持っています

  1. 自分のコードで制限を計算する必要があります(面倒でエラーが発生しやすい)
  2. 自分のコードで制限を計算することは、面取りとは互換性がありません。ファセット単位の軸制限をcoord_cartesianと指定することはできません(AFAIK)。しかし私は、第二のgeomを制限座標計算時に考慮されなかった場合、facet_wrap(scales = "free")

所望の出力が達成されると、プロットを組み合わせることが必要 - カスタムRコードにおける限界を計算することなく可能ことですか?

質問 R: How do I use coord_cartesian on facet_grid with free-ranging axisは関連していますが、満足のいく回答はありません。

+1

私はそれがfacet_wrap' 'のコンテキストで行うことができるとは思いません。これを回避するには、事前にデータを手作業でトリミングして、必要なプロット制限を超えるデータがなく、したがって 'ggplot2'が軸のサイズを変更しようとしないことがあります。 Cludgy、しかし、私は 'facet_wrap'を使うときには別の方法を考えることができません。 – Lyngbakr

答えて

2

ことの一つは、fitを拡張し、geom_density(aes(y = ..scaled..)

スケーリングを使用することですfit0間と1

d$fit_scaled <- (d$fit - min(d$fit))/(max(d$fit) - min(d$fit)) 

使用fit_scaled..scaled..

ggplot(d, aes(x = measured)) + 
    geom_density(aes(y = ..scaled..)) + 
    geom_line(aes(y = fit_scaled), color = "blue") 

output_1

これはfacet_wrap()と組み合わせることができます。

d$group <- rep(letters[1:2], 500) #fake group 

ggplot(d, aes(x = measured)) + 
    geom_density(aes(y = ..scaled..)) + 
    geom_line(aes(y = fit_scaled), color = "blue") + 
    facet_wrap(~ group, scales = "free") 

ouput_2

データをスケーリングしないオプションを:

あなたはhttp://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/

から機能 multiplot()を使用することができます
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) { 
    library(grid) 
    plots <- c(list(...), plotlist) 

    numPlots = length(plots) 

    if (is.null(layout)) { 

    layout <- matrix(seq(1, cols * ceiling(numPlots/cols)), 
        ncol = cols, nrow = ceiling(numPlots/cols)) 
    } 

if (numPlots==1) { 
    print(plots[[1]]) 

    } else { 

    grid.newpage() 
    pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout)))) 

    for (i in 1:numPlots) { 

     matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE)) 

     print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row, 
             layout.pos.col = matchidx$col)) 
    } 
    } 
} 
それが簡単にそれらを読んですることができますが、二つのグラフを組み合わせることができ、この機能により、

output_3

をそして、あなたは隣のグループを比較する場合:

multiplot(
    ggplot(d, aes(x = measured)) + 
    geom_density() + 
    facet_wrap(~ group, scales = "free"), 
    ggplot(d, aes(x = measured)) + 
    geom_line(aes(y = fit), color = "blue") + 
    facet_wrap(~ group, scales = "free") 
) 

これはあなたを与えるだろうお互いにfacet_wrap()の代わりにfacet_grid()cols = 2を入力してmultiplot()

multiplot(
    ggplot(d, aes(x = measured)) + 
    geom_density() + 
    facet_grid(group ~ ., scales = "free"), 
    ggplot(d, aes(x = measured)) + 
    geom_line(aes(y = fit), color = "blue") + 
    facet_grid(group ~ ., scales = "free"), 
    cols = 2 
) 

そしてそれは次のようになります。

output_4

+0

私はトリックが好きですが、私はそれが2つの曲線の違いをあいまいにしていると思います - 私はそれらが異なっているのがわかりますが、実際の密度の上/下のどの領域が適合しているかを知ることはできません。 –

-1

最初にmax y-limitを計算できます。その後、プロットします。あなたが試みることができる

d1 <- d %>% 
    mutate(max_dens=round(max(density(measured)$y), 2)) 

ggplot(d1, aes(x=measured)) + 
    geom_line(aes(y=fit), color = "blue") + 
    geom_density() + 
    coord_cartesian(ylim = c(0, unique(d1$max_dens))) 
+0

申し訳ありませんが、それは私の質問から明らかではないが、これは厄介でファセットとの互換性がないので、私が避けたいものです。 –

+3

質問を更新し、ファセットの例を含めてください。 – Jimbou

+0

私は例にファセットを追加することで問題を定式化しようとしましたが、ポイントをあいまいにしてしまいます(コードが長くなり、 "望ましい"出力が得られません)。私はさらに明確にしようとしました。ファセットと互換性があり、自分自身で限界を計算することを避けるという要件は、質問の最初のバージョンにすでに存在していたので、私はあなたの答えが質問とは無関係であり、削除する価値があると信じています。 –

関連する問題