17

facetでラベルを数式に変更する方法を知りたいggplot2です。

d <- ggplot(diamonds, aes(carat, price, fill = ..density..)) +
  xlim(0, 2) + stat_binhex(na.rm = TRUE) + opts(aspect.ratio = 1)
d + facet_wrap(~ color, ncol = 4)

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

たとえば、ファセットラベルをからに変更したいとしDますY[1]。ここで、1は下付き文字です。よろしくお願いします。

私はこの答えを見つけましたが、それは私にはうまくいきません。私はとを使用R 2.15.1してggplot2 0.9.1います。

4

5 に答える 5

23

gtableでgrobsを編集できます。

ggplot(diamonds, aes(carat, price, fill = ..density..)) +
  xlim(0, 2) + stat_binhex(na.rm = TRUE) + facet_wrap(~ color, ncol = 4)


for(ii in 1:7)
grid.gedit(gPath(paste0("strip_t-", ii), "strip.text"), 
           grep=TRUE, label=bquote(gamma[.(ii)]))

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

または、grobを保存したい場合は、

g <- ggplotGrob(d)
gg <- g$grobs

strips <- grep("strip_t", names(gg))
for(ii in strips)
  gg[[ii]] <- editGrob(getGrob(gg[[ii]], "strip.text", 
                               grep=TRUE, global=TRUE), 
                       label=bquote(gamma[.(ii)]))

g$grobs <- gg

ggsaveを使用すると、クラスggplotのテストをだます必要があるため、余分な(醜い)作業が必要になります...pdf() ; grid.draw(g); dev.off()明示的に呼び出す方が簡単だと思います。


ローランドによる編集:

小さな修正を加えて、関数でラップしました。

facet_wrap_labeller <- function(gg.plot,labels=NULL) {
  #works with R 3.0.1 and ggplot2 0.9.3.1
  require(gridExtra)
  
  g <- ggplotGrob(gg.plot)
  gg <- g$grobs      
  strips <- grep("strip_t", names(gg))
    
  for(ii in seq_along(labels))  {
    modgrob <- getGrob(gg[[strips[ii]]], "strip.text", 
                       grep=TRUE, global=TRUE)
    gg[[strips[ii]]]$children[[modgrob$name]] <- editGrob(modgrob,label=labels[ii])
  }
  
  g$grobs <- gg
  class(g) = c("arrange", "ggplot",class(g)) 
  g
}

これにより、きれいに印刷ggsaveでき、使用することもできます。

于 2013-06-06T14:32:32.803 に答える
12

おそらく、誰かがedit-Grob関数の名前をある時点で変更したのでしょう。(編集:約8か月前に@hadleyによって削除されました。) pkg:gridからgeditGrobだけが 機能しているようです。editGrob

 d <- ggplot(diamonds, aes(carat, price, fill = ..density..)) +
              xlim(0, 2) + stat_binhex(na.rm = TRUE) + opts(aspect.ratio = 1)

 #Note: changes in ggplot2 functions cause this to fail from the very beginning now.
 # Frank Harrell's answer this year suggests `facet_warp` now accepts `labeller`


 d <- d + facet_wrap(~ color, ncol = 4)
 grob <- ggplotGrob(d)
 strip_elem <- grid.ls(getGrob(grob, "strip.text.x", grep=TRUE, global=TRUE))$name
#strip.text.x.text.1535
#strip.text.x.text.1541
#strip.text.x.text.1547
#strip.text.x.text.1553
#strip.text.x.text.1559
#strip.text.x.text.1565
#strip.text.x.text.1571
grob <- editGrob(grob, strip_elem[1], label=expression(Y[1]))
grid.draw(grob)
于 2012-08-16T01:33:35.170 に答える
9

ggplot22.1.0以降、labellerに実装されていfacet_wrapます。

于 2016-03-23T12:09:14.840 に答える
8

rolandとbaptisteからこの非常に便利な関数に出くわしましたが、元のラップヘッダーを固定値として提供するのではなく、関数によって変換する必要がある、わずかに異なるユースケースが必要でした。他の人に役立つ場合に備えて、元の関数のわずかに変更されたバージョンを投稿しています。これにより、ラップストリップに名前付き(固定値)式を使用できるだけでなく、カスタム関数と、facet_grid labellerパラメーター(label_parsedおよびなどlabel_bquote)に対してggplot2によって既に提供されている関数を使用することもできます。

facet_wrap_labeller <- function(gg.plot, labels = NULL, labeller = label_value) {
  #works with R 3.1.2 and ggplot2 1.0.1
  require(gridExtra)

  # old labels
  g <- ggplotGrob(gg.plot)
  gg <- g$grobs      
  strips <- grep("strip_t", names(gg))
  modgrobs <- lapply(strips, function(i) {
    getGrob(gg[[i]], "strip.text", grep=TRUE, global=TRUE)
  })
  old_labels <- sapply(modgrobs, function(i) i$label)

  # find new labels
  if (is.null(labels)) # no labels given, use labeller function
    new_labels <- labeller(names(gg.plot$facet$facets), old_labels)
  else if (is.null(names(labels))) # unnamed list of labels, take them in order
    new_labels <- as.list(labels)
  else { # named list of labels, go by name where provided, otherwise keep old
    new_labels <- sapply(as.list(old_labels), function(i) {
      if (!is.null(labels[[i]])) labels[[i]] else i
    })
  }

  # replace labels
  for(i in 1:length(strips))  {
    gg[[strips[i]]]$children[[modgrobs[[i]]$name]] <- 
       editGrob(modgrobs[[i]], label=new_labels[[i]])
  }

  g$grobs <- gg
  class(g) = c("arrange", "ggplot",class(g))
  return(g) 
}

更新/警告

gridExtraパッケージの新しいバージョンでは、Error: No layers in plotこの関数を実行するとエラーが発生します。これarrangeは、が含まれなくなり、gridExtraRがそれを。として解釈しようとするためggplotです。これは、クラスのprint関数を(再)導入することで修正できます。arrange

print.arrange <- function(x){
    grid::grid.draw(x)
}

これでプロットがレンダリングできるようになり、ggsave()たとえば次のように使用できます。ggsave("test.pdf", plot = facet_wrap_labeller(p, labeller = label_parsed))

いくつかのユースケースの例:

# artificial data frame
data <- data.frame(x=runif(16), y=runif(16), panel = rep(c("alpha", "beta", "gamma","delta"), 4))
p <- ggplot(data, aes(x,y)) + geom_point() + facet_wrap(~panel)

# no changes, wrap panel headers stay the same
facet_wrap_labeller(p) 

# replace each panel title statically
facet_wrap_labeller(p, labels = expression(alpha^1, beta^1, gamma^1, delta^1)) 

# only alpha and delta are replaced
facet_wrap_labeller(p, labels = expression(alpha = alpha^2, delta = delta^2)) 

# parse original labels
facet_wrap_labeller(p, labeller = label_parsed) 

# use original labels but modifying them via bquote
facet_wrap_labeller(p, labeller = label_bquote(.(x)^3)) 

# custom function (e.g. for latex to expression conversion)
library(latex2exp)
facet_wrap_labeller(p, labeller = function(var, val) { 
  lapply(paste0("$\\sum\\", val, "$"), latex2exp)
}) 
于 2015-11-02T22:50:21.283 に答える
1

言及してくれた他の回答とコメントに感謝しますlabel_parsed。ラベルパーサーの使用方法はまだはっきりしていなかったので、ここに簡単な再現可能な例を追加します。

library(dplyr)
library(ggplot2)

# Create a first facet variable with examples of math formulas
iris2 <- iris %>%
    mutate(species_math = factor(Species,
                            levels = c("setosa", "versicolor", "virginica"),
                            labels = c("m^2",
                                       expression(bar(x) == sum(frac(x[i], n), i==1, n) * beta * Q[t-1]),
                                       bquote(pi == .(pi)))))

# Create a second facet variable with mean lengths
# This illustrates how to pass a numeric vector inside a formula
iris_mean <- iris2 %>%
    group_by(Species) %>%
    summarise(across(ends_with("Length"), mean), .groups="drop")

iris2$mean_length <- factor(iris2$Species,
                           levels =  c("setosa", "versicolor", "virginica"),
                           labels = mapply(function(p, s) bquote(bar(p) == .(p) ~ bar(s) ==.(s)),
                                            round(iris_mean$Petal.Length,3), round(iris_mean$Sepal.Length,3)))


iris2 %>%
    ggplot(aes(x = Petal.Length, y = Petal.Width)) +
    geom_point() +
    facet_wrap(species_math ~ mean_length + Species, labeller = labeller(species_math = label_parsed, mean_length = label_parsed))

ggsave("~/downloads/formula_in_facet.png",
       width = 12, height = 8, units = "cm")

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

上記の例に示されているように、ラベラーは以下を解析できます。

  1. 簡単な数式の場合は「m^2」などの文字ベクトル
  2. インデックスを使用したexpressionより複雑な数学の場合
  3. の出力にbquoteは、数式に数値が含まれます。複数の値の数値ベクトルを使用する方法については、この回答も参照してください。bquote
  4. ラベラーをファセット変数の1つにのみ適用する方法については、この他の回答を参照してください。この場合、species_math変数にのみ適用します。

label_parsed構文は、ラベルを式として解釈するため、LaTeXの数式とは異なりますplotmath。たとえば、インデックスはx_iラテックスとx[i]プロットの数式で記述され、ギリシャ文字はラテックスではalphaなく直接記述され\alphaます。plotmath関数のヘルプページに多くの数式があり ます。例で頑張ってplotmathください。

于 2021-04-12T15:55:36.503 に答える