r - 当 hjust 和 vjust 是字符串时,为什么 geom_text() 会抛出强制错误?

标签 r ggplot2

我注意到 ggplot2geom_text() geom 中存在意外行为。如果将属性 hjustvjust 指定为字符串,R 将返回强制错误,尽管绘图看起来正常。问题出现在 ggplot2-based package我正在发展。为了简单起见,我创建了仍然会产生错误的精简示例。

首先,我尝试使用qplot()

##qplot version
library(ggplot2)
p <- qplot(cty, hwy, 
           label = drv, 
           hjust = "right", 
           geom  = "text", 
           data  = mpg
)

print(p)

我得到了这个错误:

Warning message:
In validDetails.text(x) : NAs introduced by coercion

然后我用ggplot()尝试了它:

##ggplot version
library(ggplot2)
p <- ggplot(
          aes(x   = cty,
              y   = hwy
          ), data = mpg
)

p <- p + geom_text(
           aes(label = drv),
           hjust     = "right"
)

print(p)

并得到了相同的情节,以及相同的错误:

Warning message:
In validDetails.text(x) : NAs introduced by coercion

然后我尝试设置 hjust 和 vjust:

library(ggplot2)
p <- ggplot(
          aes(x   = cty,
              y   = hwy
          ), data = mpg
)

p <- p + geom_text(
           aes(label = drv),
           hjust     = "right",
           vjust     = "top"
)

print(p)

使用字符串设置两个参数时,R 返回两个强制错误:

Warning messages:
1: In validDetails.text(x) : NAs introduced by coercion
2: In validDetails.text(x) : NAs introduced by coercion

但是,当参数是数字时,R 不会返回强制错误:

## Using numbers instead of strings
library(ggplot2)
p <- ggplot(
          aes(x   = cty,
              y   = hwy
          ), data = mpg
)

p <- p + geom_text(
           aes(label = drv),
           hjust     = 0,
           vjust     = 0,
           data      = mpg
)

print(p)

我不太确定为什么会发生这种情况,或者它是否重要,但我没想到会发生这种情况。

ggplot2 文档不同意

Hadley's book (第 196 页)hjustvjust 说 可以接受字符串参数:

Justification of a string (or legend) defines the location within the string that is placed at the given position. There are two values for horizontal and vertical justification. The values can be:

  • A string: "left", "right", "centre", "center", "bottom", and "top".
  • A number between 0 and 1, giving the position within the string (from bottom-left corner).

但是 0.8.9 版本中 geom_text() 的 man 文件说 hjust 和 vjust 是数字,尽管它没有说它们可以 只能为数字:

Aesthetics

The following aesthetics can be used with geom_text. Aesthetics are mapped to variables in the data with the aes function: geom_text(aes(x = var))

  • x: x position (required)
  • y: y position (required)
  • label: text label (required)
  • colour: border colour
  • size: size
  • angle: angle
  • hjust: horizontal justification, between 0 and 1
  • vjust: vertical justification, between 0 and 1
  • alpha: transparency

最佳答案

所以,我不太了解什么代码定义或消耗 hjust/vjust,但是使用 TextMate 的“在项目中查找”(在 ggplot2/R/目录中)作为 hjust,我没有看到任何看起来像的行就像它们是 hjust 的定义或实现一样...只是将其列为有效 aes 并传递的位置。

这让我想去阅读网格......

http://stat.ethz.ch/R-manual/R-patched/library/grid/html/grid.text.html

这让我想了解更多有关 grid.text 是如何定义的

R> grid.text

function (label, x = unit(0.5, "npc"), y = unit(0.5, "npc"), 
    just = "centre", hjust = NULL, vjust = NULL, rot = 0, check.overlap = FALSE, 
    default.units = "npc", name = NULL, gp = gpar(), draw = TRUE, 
    vp = NULL) 
{
    tg <- textGrob(label = label, x = x, y = y, just = just, 
        hjust = hjust, vjust = vjust, rot = rot, check.overlap = check.overlap, 
        default.units = default.units, name = name, gp = gp, 
        vp = vp)
    if (draw) 
        grid.draw(tg)
    invisible(tg)
}
<environment: namespace:grid>

所以,它是一个 textGrob,而 just、hjust 和 vjust 只是被传递到其中...传递给 textGrob

R> textGrob
function (label, x = unit(0.5, "npc"), y = unit(0.5, "npc"), 
    just = "centre", hjust = NULL, vjust = NULL, rot = 0, check.overlap = FALSE, 
    default.units = "npc", name = NULL, gp = gpar(), vp = NULL) 
{
    if (!is.unit(x)) 
        x <- unit(x, default.units)
    if (!is.unit(y)) 
        y <- unit(y, default.units)
    grob(label = label, x = x, y = y, just = just, hjust = hjust, 
        vjust = vjust, rot = rot, check.overlap = check.overlap, 
        name = name, gp = gp, vp = vp, cl = "text")
}
<environment: namespace:grid>

所以,这是一个grob............去grob......

R> grob
function (..., name = NULL, gp = NULL, vp = NULL, cl = NULL) 
{
    g <- list(..., name = name, gp = gp, vp = vp)
    if (!is.null(cl) && !is.character(cl)) 
        stop("Invalid 'grob' class")
    class(g) <- c(cl, "grob", "gDesc")
    validGrob(g)
}
<environment: namespace:grid>

那里没有什么太大帮助,所以我谷歌

R网格hjust vjust

在覆盖 Google 对我的搜索的自动更正后,我发现

http://rwiki.sciviews.org/doku.php?id=tips:graphics-grid:hvjust

回顾 Hadley 的书,我注意到第 196 页的引用文献实际上并没有提及 hjust 或 vjust...只是证明。

阅读文档

R> ?textGrob

我看到了

just     The justification of the text relative to its (x, y) location. If there are two values, the first value specifies horizontal justification and the second value specifies vertical justification. Possible string values are: "left", "right", "centre", "center", "bottom", and "top". For numeric values, 0 means left alignment and 1 means right alignment.
hjust    A numeric vector specifying horizontal justification. If specified, overrides the just setting.
vjust    A numeric vector specifying vertical justification. If specified, overrides the just setting.

所以,这是我的想法。

  • just 参数可以是字符串或数字
  • hjust 和 vjust 仅为数字,可以覆盖 just
  • 如果您尝试对它们使用字符串,它可能会“起作用”,但会抛出警告

那么,让我们看一下 grid.text 演示代码,特别是 draw.text 函数,它们仅使用字符串值,并且似乎成功地使用了字符串值:

grid.newpage()
x <- stats::runif(20)
y <- stats::runif(20)
rot <- stats::runif(20, 0, 360)
grid.text("SOMETHING NICE AND BIG", x=x, y=y, rot=rot,
          gp=gpar(fontsize=20, col="grey"))
grid.text("SOMETHING NICE AND BIG", x=x, y=y, rot=rot,
          gp=gpar(fontsize=20), check=TRUE)
grid.newpage()

draw.text <- function(just, i, j) {
  grid.text("ABCD", x=x[j], y=y[i], just=just)
  grid.text(deparse(substitute(just)), x=x[j], y=y[i] + unit(2, "lines"),
            gp=gpar(col="grey", fontsize=8))
}

x <- unit(1:4/5, "npc")
y <- unit(1:4/5, "npc")
grid.grill(h=y, v=x, gp=gpar(col="grey"))
draw.text(c("bottom"), 1, 1)
draw.text(c("left", "bottom"), 2, 1)
draw.text(c("right", "bottom"), 3, 1)
draw.text(c("centre", "bottom"), 4, 1)
draw.text(c("centre"), 1, 2)
draw.text(c("left", "centre"), 2, 2)
draw.text(c("right", "centre"), 3, 2)
draw.text(c("centre", "centre"), 4, 2)
draw.text(c("top"), 1, 3)
draw.text(c("left", "top"), 2, 3)
draw.text(c("right", "top"), 3, 3)
draw.text(c("centre", "top"), 4, 3)
draw.text(c(), 1, 4)
draw.text(c("left"), 2, 4)
draw.text(c("right"), 3, 4)
draw.text(c("centre"), 4, 4)

现在请注意,如果我将 draw.text 更改为使用 hjust 和 vjust AS STRINGS

grid.newpage()
x <- stats::runif(20)
y <- stats::runif(20)
rot <- stats::runif(20, 0, 360)
grid.text("SOMETHING NICE AND BIG", x=x, y=y, rot=rot,
          gp=gpar(fontsize=20, col="grey"))
grid.text("SOMETHING NICE AND BIG", x=x, y=y, rot=rot,
          gp=gpar(fontsize=20), check=TRUE)
grid.newpage()

draw.text <- function(just, i, j) {
  grid.text("ABCD", x=x[j], y=y[i], hjust=just[1], vjust=just[2])
  grid.text(deparse(substitute(just)), x=x[j], y=y[i] + unit(2, "lines"),
            gp=gpar(col="grey", fontsize=8))
}  

x <- unit(1:4/5, "npc")
y <- unit(1:4/5, "npc")
grid.grill(h=y, v=x, gp=gpar(col="grey"))
draw.text(c("bottom"), 1, 1)
draw.text(c("left", "bottom"), 2, 1)
draw.text(c("right", "bottom"), 3, 1)
draw.text(c("centre", "bottom"), 4, 1)
draw.text(c("centre"), 1, 2)
draw.text(c("left", "centre"), 2, 2)
draw.text(c("right", "centre"), 3, 2)
draw.text(c("centre", "centre"), 4, 2)
draw.text(c("top"), 1, 3)
draw.text(c("left", "top"), 2, 3)
draw.text(c("right", "top"), 3, 3)
draw.text(c("centre", "top"), 4, 3)
draw.text(c(), 1, 4)
draw.text(c("left"), 2, 4)
draw.text(c("right"), 3, 4)
draw.text(c("centre"), 4, 4)

长话短说:我认为当您使用 hjust 或 vjust 作为字符串时,您违反了文档(它的值应该是数字 0 <= x <= 1),并且如果您想使用字符串,你必须使用 just 参数......

关于r - 当 hjust 和 vjust 是字符串时,为什么 geom_text() 会抛出强制错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5072841/

相关文章:

R 在 XTS 对象上逐月增长的百分比

r - 如何在保留 R 中的某些变量的同时将长整形为宽

r - 将列表中的 data.frames 堆叠到单个 data.frame 中,将名称(列表)保留为额外的列

r - map-ggplot2 上的比例尺和指北针

r - 如何使用 geom_bar 在 ggplot2 中制作连接条形图?

r - 如何在条形图上使用 gganimate 以便在动画结束之前出现的每个条形都不会消失?

R ggplot2 与 shapefile 和 csv 数据合并以填充多边形 - 特定

r - 如何用R删除括号内的 "p.485"?

r - 按行计算平均日期

r - 如何理解哪个图例是哪个图例并在 R 的 ggplot 中删除其中一个?