2012-11-15 16 views
22

ggplot2で作成したグリッドオブジェクトからlayer(この場合はgeom_ribbonの結果)を削除したいと思います。既にオブジェクトの一部になったら削除する方法はありますか?ggplot2グラフからレイヤーを削除する

library(ggplot2) 
dat <- data.frame(x=1:3, y=1:3, ymin=0:2, ymax=2:4) 
p <- ggplot(dat, aes(x=x, y=y)) + geom_ribbon(aes(ymin=ymin, ymax=ymax), alpha=0.3) 
    + geom_line() 

# This has the geom_ribbon 
p 

# This overlays another ribbon on top 
p + geom_ribbon(aes(ymin=ymin, ymax=ymax, fill=NA)) 

私はこの機能を使用して、より複雑でないものの上にさらに複雑なプロットを作成できるようにしたいと思います。グリッドオブジェクトを返す関数を使用していて、完全に組み立てられたら最後のプロットを印刷しています。ベースプロットには、対応するエラーバー(geom_ribbon)が1行あります。より複雑なプロットは複数の線を持ち、複数のオーバーラップするオブジェクトは気を散らす。私はそれらを複数の行でプロットから削除したいと思います。さらに、ファセットやその他のggplot2機能を使用して、代替バージョンをすばやく作成することができます。


編集:それが動作としての@ mnelの答えを受け入れます。今度は、geom_ribbonレイヤに動的にアクセスする方法を決定する必要があります。これは、SOの質問hereに取り込まれています。


編集2:完全性については、これは私がこの問題を解決するために作成した関数である:

remove_geom <- function(ggplot2_object, geom_type) { 
    layers <- lapply(ggplot2_object$layers, function(x) if(x$geom$objname == geom_type) NULL else x) 
    layers <- layers[!sapply(layers, is.null)] 

    ggplot2_object$layers <- layers 
    ggplot2_object 
} 
+0

これを使用するユースケースを教えてください。 – Andrie

+0

'p $ layers'の中の特定の層を見つけてそれに' NULL'を割り当てることによってそれを消滅させるのは、おそらくは "うまくいく"でしょうが、信頼性についての予測はしません。 – joran

+0

私はこの権利を理解していないと思います。あなたはそれを持っていなければならないが、それを見たくないのなら、なぜアルファ= 0でないのですか? – Mikko

答えて

5

ggplot2バージョン2.2の場合。1、私はこのような提案remove_geom機能変更する必要がありました:

remove_geom <- function(ggplot2_object, geom_type) { 
    # Delete layers that match the requested type. 
    layers <- lapply(ggplot2_object$layers, function(x) { 
    if (class(x$geom)[1] == geom_type) { 
     NULL 
    } else { 
     x 
    } 
    }) 
    # Delete the unwanted layers. 
    layers <- layers[!sapply(layers, is.null)] 
    ggplot2_object$layers <- layers 
    ggplot2_object 
} 

をここにそれを使用する方法の例です:

p 

plot with text labels

library(ggplot2) 

set.seed(3000) 
d <- data.frame(
    x = runif(10), 
    y = runif(10), 
    label = sprintf("label%s", 1:10) 
) 

p <- ggplot(d, aes(x, y, label = label)) + geom_point() + geom_text() 

はのは、オリジナルのプロットをお見せしましょう

ここで、ラベルを削除してプロットを再度表示してみましょう:

p <- remove_geom(p, "GeomText") 
p 

plot without text labels

16

あなたは

p$layers 
[[1]] 
mapping: ymin = ymin, ymax = ymax 
geom_ribbon: na.rm = FALSE, alpha = 0.3 
stat_identity: 
position_identity: (width = NULL, height = NULL) 

[[2]] 
geom_line: 
stat_identity: 
position_identity: (width = NULL, height = NULL) 

を見ればあなたが望むことがわかります最初のレイヤーを削除する

これを行うにはredeリスト内の2番目のコンポーネントとしてレイヤーを細分化します。

p$layer <- p$layer[2] 

p$layer[[1]] <- NULLも同様に動作することをp

p 

注意を構築し、プロット。私は@Andrieと@ Joranの意見に同意します。これは役に立つかもしれませんが、これが必ずしも信頼できるとは思わないでしょう。 enter image description here

+0

これは私の考えでもありましたが、削除しているレイヤーにスケールや伝説などが付いていたより複雑な状況ではテストしていません。 – joran

+0

'ggplot_build'の仕組みを見れば、プロットの 'layers'コンポーネントなので、(qplot'を使用していない限り、それはかなり頑強でなければなりません。私が調査していない内部動作です。) – mnel

+0

あなたが正しいかもしれないと思います。少なくとも私の最初のテストでは、もっと複雑なプロットを使ってみるとすべてうまくいくように思えました。 – joran

1

@Kamil Slowikowskiのおかげ!非常に便利。しかし、私は同じテーマで新しいバリエーションを作成するのを止めることはできませんでした。元の投稿や更新されたバージョンのKamilより理解しやすく、またいくつかの課題を避けることができればうれしく思います。

remove_geoms <- function(x, geom_type) { 
    # Find layers that match the requested type. 
    selector <- sapply(x$layers, 
        function(y) { 
         class(y$geom)[1] == geom_type 
        }) 
    # Delete the layers. 
    x$layers[selector] <- NULL 
    x 
} 
このバージョンは機能的にはKamilの機能と同じですので、上記の使用例をここで繰り返す必要はありません。

この機能は、geomのクラスの代わりにstatのクラスに基づいてレイヤーを選択するのに簡単に適応できます。

remove_stats <- function(x, stat_type) { 
    # Find layers that match the requested type. 
    selector <- sapply(x$layers, 
        function(y) { 
         class(y$stat)[1] == stat_type 
        }) 
    # Delete the layers. 
    x$layers[selector] <- NULL 
    x 
} 
2

この問題は面白そうだったので、ggplotオブジェクトのレイヤーを操作する関数を使って 'ggpmisc'パッケージを展開しました。関数は、この同じ質問に対する私の以前の答えの例のより洗練されたバージョンです。しかし、ほとんどの場合、これはグラフィックスの文法に違反するため、最良の作業方法ではないことに注意してください。ほとんどの場合、オペレータ+と通常の方法で同じ図形の異なるバリエーションを組み立てることができます。おそらく複雑な図のアセンブリを簡略化するビルディングブロックを組み合わせるためにレイヤーのグループをリストに「パッケージ化」します。例外的に、既存のプロットを編集するか、上位レベルの関数でプロットを出力することができます。その定義は変更できません。そのような場合、これらの層操作関数は有用であり得る。上記の例は次のようになります。

library(ggpmisc) 
p1 <- delete_layers(p, match_type = "GeomText") 

は、他の実施例のために、層の順序を変更するために有用なコンパニオン機能の詳細について、及び任意の位置に新たな層を挿入するためのパッケージのドキュメントを参照してください。

関連する問題