Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何在ggplot2中巧妙地将文本标签放置在不同大小的点旁边?_R_Ggplot2 - Fatal编程技术网

R 如何在ggplot2中巧妙地将文本标签放置在不同大小的点旁边?

R 如何在ggplot2中巧妙地将文本标签放置在不同大小的点旁边?,r,ggplot2,R,Ggplot2,我试图用R中的ggplot2制作一个带标签的气泡图。以下是简化的场景: 我有一个包含4个变量的数据框:3个定量变量,x,y和z,还有一个标记点的变量,lab 我想做一个散点图,其中位置由x和y确定,点的大小由z确定。然后,我希望在点旁边放置文本标签(例如,在点的右侧),而不与点顶部的文本重叠 如果点的大小没有变化,我可以尝试通过添加缩放常数(例如,aes(x=x+1,y=y+1))来简单地修改geom_文本层的美学效果。然而,即使是在这个简单的例子中,我在正确定位文本时也遇到了问题,因为这些点不

我试图用R中的
ggplot2
制作一个带标签的气泡图。以下是简化的场景:

我有一个包含4个变量的数据框:3个定量变量,
x
y
z
,还有一个标记点的变量,
lab

我想做一个散点图,其中位置由
x
y
确定,点的大小由
z
确定。然后,我希望在点旁边放置文本标签(例如,在点的右侧),而不与点顶部的文本重叠

如果点的大小没有变化,我可以尝试通过添加缩放常数(例如,
aes(x=x+1,y=y+1)
)来简单地修改
geom_文本
层的美学效果。然而,即使是在这个简单的例子中,我在正确定位文本时也遇到了问题,因为这些点不能与绘图的输出尺寸成比例。换句话说,在500x500绘图和1000x1000绘图中,点的大小保持不变-它们不随输出绘图的尺寸放大

因此,我认为我必须根据输出绘图的大小(例如尺寸)缩放标签的位置,或者我必须以某种方式从
ggplot
获取点的半径,并移动文本标签。在
ggplot2
中是否有这样做的方法

下面是一些代码:

# Stupid data
df <- data.frame(x=c(1,2,3), 
                 y=c(1,2,3), 
                 z=c(1,2,1),
                 lab=c("a","b","c"), stringsAsFactors=FALSE)

# Plot with bad label placement
ggplot(aes(x=x, y=y), data=df) + 
  geom_point(aes(size=z)) + 
  geom_text(aes(label=lab), 
            colour="red") +
  scale_size_continuous(range=c(5, 50), guide="none")
编辑:多亏了亨里克和舒贾,我现在终于找到了一款有效的产品。我将把这个问题留待讨论,以防有人有一个更普遍的解决方案


这只是我使用它的一个简介:我正在绘制一张地图,并用一个与观测到的降水量成比例的点指示某些台站的降水量。我想在每个点旁边添加一个站标签,以一种美观的方式。我将为不同的区域绘制更多的这些图,并且我的输出图对于每个图可能具有不同的分辨率或比例(例如,由于不同的投影),因此需要一个通用的解决方案。如果我周末有时间的话,我可能会像巴蒂斯特建议的那样尝试创建一个自定义的
位置抖动。

这不是一个非常通用的解决方案,因为你每次都需要调整它,但是你应该能够为文本的
x
值添加一些线性值,这取决于
z

我和他交了好运

ggplot(aes(x=x, y=y), data=df) + 
    geom_point(aes(size=z)) + 
    geom_text(aes(label=lab, x = x + .06 + .14 * (z - min(z))), 
              colour="red") +
    scale_size_continuous(range=c(5, 50), guide="none")

但是,由于字体大小取决于窗口大小,因此需要决定输出大小并进行相应调整。我从
x=x+.05+0*(z-min(z))
开始,并根据最小点校准了截距,然后当我对此满意时,我调整了最大点的线性项。

另一种选择。测试数据看起来还可以,但您需要检查它的通用性

dodge <- abs(scale(df$z))/4

ggplot(data = df, aes(x = x, y = y)) + 
  geom_point(aes(size = z)) +
  geom_text(aes(x = x + dodge), label = df$lab, colour = "red") +
  scale_size_continuous(range = c(5, 50), guide = "none")

似乎位置_***无法使用其他图层使用的刻度,因此无法使用。您可以复制GeomText,根据映射的大小移动标签, 但要找到一个非常笨拙和脆弱的解决方案需要付出很大的努力

geom_shiftedtext <- function (mapping = NULL, data = NULL, stat = "identity", 
                       position = "identity", 
                       parse = FALSE, ...) { 
  GeomShiftedtext$new(mapping = mapping, data = data, stat = stat, position = position, 
               parse = parse, ...)
}
require(proto)
GeomShiftedtext <- proto(ggplot2:::GeomText, {
  objname <- "shiftedtext"
  draw <- function(., data, scales, coordinates, ..., parse = FALSE, na.rm = FALSE) {
    data <- remove_missing(data, na.rm, 
                           c("x", "y", "label"), name = "geom_shiftedtext")

    lab <- data$label
    if (parse) {
      lab <- parse(text = lab)
    }

    with(coord_transform(coordinates, data, scales),
         textGrob(lab, unit(x, "native") + unit(0.375* size, "mm"), 
                  unit(y, "native"), 
                  hjust=hjust, vjust=vjust, rot=angle, 
                  gp = gpar(col = alpha(colour, alpha), 
                            fontfamily = family, fontface = fontface, lineheight = lineheight))

         )
  }

})


df <- data.frame(x=c(1,2,3), 
                 y=c(1,2,3), 
                 z=c(1.2,2,1),
                 lab=c("a","b","c"), stringsAsFactors=FALSE)

ggplot(aes(x=x, y=y), data=df) + 
  geom_point(aes(size=z), shape=1) + 
  geom_shiftedtext(aes(label=lab, size=z),
            hjust=0, colour="red") +
  scale_size_continuous(range=c(5, 100), guide="none")


geom_shiftedtext hjust和vjust将文本偏移一段与fontsize链接的距离,因此它的缩放效果应优于数据coordinates@baptiste对不起,我应该提到我尝试了
hjust
vjust
,但没有产生预期的结果。当我尝试将文本定位到点的右侧(hjust=0,vjust=0.5)时,文本仍然与点重叠,因为它从点的中间开始。我现在看到了问题,因为我已经运行了您的代码,也许可以基于位置_jitter()编写一个新函数@baptiste是否知道输出绘图尺寸?这可能是一个很好的解决方案。这(类)的可能重复适用于问题中提供的我的玩具数据,但我希望有一个更通用的解决方案,以便我可以在我的数据中使用它。如果结果太难,我可能会实现一种类似于您的方法,并在绘图时缩放x变量。我将您的想法与@shujaa的答案混合在一起,以获得某种在特定分辨率下适用于我的数据的方法。现在必须这样做,但是为将来的绘图找到一个通用的解决方案真的很好。谢谢,我将用我的数据尝试一下。从示例图上看,它很有希望。你能澄清一下你所说的“混乱而脆弱的解决方案”是什么意思吗?首先,它有一个0.375的常数,这对其他点形状来说不太合适。它的范围非常有限,因为偏移量硬连接到东部,它不优雅,因为它破坏了其预期用途的尺寸美学,它复制了很多ggplot2的内部代码,可能会在将来进行更改,等等。尽管如此,这非常有帮助,您的解决方案解决了我的问题。非常感谢你。
df3 <- mtcars[1:10, ]
ggplot(data = df3, aes(x = wt, y = mpg)) +
  geom_point(aes(size = qsec), alpha = 0.1) +
  geom_text(label = df3$carb, position = position_jitter(width = 0.1, height = 0)) +
  scale_size_continuous(range = c(5, 50), guide = "none")
geom_shiftedtext <- function (mapping = NULL, data = NULL, stat = "identity", 
                       position = "identity", 
                       parse = FALSE, ...) { 
  GeomShiftedtext$new(mapping = mapping, data = data, stat = stat, position = position, 
               parse = parse, ...)
}
require(proto)
GeomShiftedtext <- proto(ggplot2:::GeomText, {
  objname <- "shiftedtext"
  draw <- function(., data, scales, coordinates, ..., parse = FALSE, na.rm = FALSE) {
    data <- remove_missing(data, na.rm, 
                           c("x", "y", "label"), name = "geom_shiftedtext")

    lab <- data$label
    if (parse) {
      lab <- parse(text = lab)
    }

    with(coord_transform(coordinates, data, scales),
         textGrob(lab, unit(x, "native") + unit(0.375* size, "mm"), 
                  unit(y, "native"), 
                  hjust=hjust, vjust=vjust, rot=angle, 
                  gp = gpar(col = alpha(colour, alpha), 
                            fontfamily = family, fontface = fontface, lineheight = lineheight))

         )
  }

})


df <- data.frame(x=c(1,2,3), 
                 y=c(1,2,3), 
                 z=c(1.2,2,1),
                 lab=c("a","b","c"), stringsAsFactors=FALSE)

ggplot(aes(x=x, y=y), data=df) + 
  geom_point(aes(size=z), shape=1) + 
  geom_shiftedtext(aes(label=lab, size=z),
            hjust=0, colour="red") +
  scale_size_continuous(range=c(5, 100), guide="none")