6

の最近の質問をフォローアップすると、これは少し異なり、より簡単な例を使用して問題をより完全に示しています。以下は、2 つのデータセットと 3 つの関数です。最初のものは、期待どおりにいくつかの点と円を描きます:

library("ggplot2")
library("grid")

td1 <- data.frame(x = rnorm(10), y = rnorm(10))

tf1 <- function(df) { # works as expected
    p <- ggplot(aes(x = x, y = y), data = df)
    p <- p + geom_point(color = "red")
    p <- p + annotation_custom(circleGrob())
    print(p)
}

tf1(td1)

この次のものは、正確なサンプル プロットを要求しているように見えますが、コードはわずかに異なります。エラーは発生しませんが、円は描画されません。

tf2 <- function(df) { # circle isn't draw, but no error either
    p <- ggplot()
    p <- p + geom_point(data = df, aes(x = x, y = y), color = "red")        
    p <- p + annotation_custom(circleGrob())
    print(p)
    }

tf2(td1)

最後に、これにはより複雑な美学が含まれており、円を作成しようとすると空のレイヤーが表示されます。

td3 <- data.frame(r = c(rnorm(5, 5, 1.5), rnorm(5, 8, 2)),
    f1 = c(rep("L", 5), rep("H", 5)), f2 = rep(c("A", "B"), 5))

tf3 <- function(df) {
    p <- ggplot()
    p <- p + geom_point(data = df, 
        aes(x = f1, y = r, color = f2, group = f2))     
#   p <- p + annotation_custom(circleGrob()) # comment out and it works
    print(p)
    }

tf3(td3)

さて、ここでの問題はコードではなく、ggplot2 の内部の仕組みを把握できていないことにあると思います。 2番目のケースで円が描かれていない理由と、3番目のケースでレイヤーが空である理由の説明を確実に使用できます。 コードを調べたところannotation_custom、ハードワイヤードinherit.aes = TRUEがあり、これが問題だと思います。この関数に美学が必要な理由がまったくわかりません (ドキュメントを参照してください)。オーバーライドして設定する方法をいくつか試しましたinherit.aes = FALSEが、名前空間を完全に貫通して固定することはできませんでした。ggplot2 によって作成されたオブジェクトを例にしようとしましたが、これらのprotoオブジェクトは非常に深くネストされており、解読が困難です。

4

1 に答える 1

2

これに答えるには:

「なぜこの機能に美学が必要なのか、まったくわかりません」。

実際annotation_custom には、そのグロブをスケーリングし、ユニットの後に使用するには、x と y aes が必要nativeです。基本的にこれを行いました:

  x_rng <- range(df$x, na.rm = TRUE)                            ## ranges of x :aes x
  y_rng <- range(df$y, na.rm = TRUE)                            ## ranges of y :aes y
  vp <- viewport(x = mean(x_rng), y = mean(y_rng),              ##  create a viewport
                 width = diff(x_rng), height = diff(y_rng),
                 just = c("center","center"))
  dd <- editGrob(grod =circleGrob(), vp = vp)                  ##plot the grob in this vp 

これを説明するために、グロブのスケールとして使用されるダミー プロットにグロブを追加します。前者は大規模で、後者は小規模です。

base.big   <- ggplot(aes(x = x1, y = y1), data = data.frame(x1=1:100,y1=1:100))
base.small <- ggplot(aes(x = x1, y = y1), data = data.frame(x1=1:20,y1=1:1))

グロブを定義します。xmin、xmax、ymin、ymax にネイティブ スケールを使用していることを確認してください。

annot <- annotation_custom(grob = circleGrob(),  xmin = 0, 
                                                 xmax = 20, 
                                                 ymin = 0, 
                                                 ymax = 1)

( ) と ( )の縮尺の違い (小さな点/大きな円) を見てください。base.big +annotbase.small + annot

library(gridExtra)
grid.arrange(base.big+annot,
             base.small+annot)

ここに画像の説明を入力

于 2013-01-19T15:09:31.547 に答える