如何在气泡中添加切线

时间:2017-01-16 14:03:35

标签: r ggplot2 bubble-chart

我正在构建一个非常简单的气泡图,只有2个观测值。 我想为每个气泡添加一个tanget,以便稍后添加标签。接触点应位于每个气泡的顶部或底部。

示例:

library("ggplot2") 
df <- data.frame(group=c(FALSE,TRUE),
                 value=c(5,30))

ggplot(df) +
  geom_point(aes(x=group, 
                 y=0,
                 size=value,
                 fill=group),
             shape=21) +
  scale_size_area(max_size=25) +
  theme_void() +
  theme(legend.position = "none")

without tangents

我想要实现的目标是:

with tangents

我最好的猜测是如何做到这一点会增加:

...  
annotate("segment",
           x = 0.2, xend = 1, 
           y = pointOfContact_1, yend = pointOfContact_1) +
annotate("segment",
           x = 2.8, xend = 2, 
           y = pointOfContact_2, yend = pointOfContact_2) 

但是,我不知道如何计算接触点(y值)。 到目前为止,调查ggplot_build()对我没有帮助......

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我认为你是对的,ggforce::geom_circle是要走的路。我尝试了几种选择,包括一些标签方法,我无法取得进展。但是,geom_circle非常灵活。你需要注意设置半径大小,以及放置x坐标的方式,但这似乎很顺利:

ggplot(df) +
  geom_circle(aes(x0=as.numeric(group), 
                  y0=0,
                  r=value/100,
                  fill=group)) +
  coord_fixed() +
  geom_segment(aes(x = as.numeric(group),
                   xend = as.numeric(group) + ifelse(as.numeric(group) == 1, 0.5, -0.5),
                   y = 0 + value/100,
                   yend = 0 + value/100
                   )) +
  theme_void() +
  theme(legend.position = "none")

给出

enter image description here

如果您有两个以上的积分,则可能需要在xend之外设置ggplot,方法是添加一个列给出该位置。同样,您可能也想直接在数据中进行半径和位置。

以下是在将数据传递给ggplot之前计算这些指标的示例。我只是因为我可以移动东西,并展示你可以设置的东西类型。

data.frame(xloc = c(1, 2, 1, 2)
           , yloc = c(1, 1, 2, 2)
           , value = 1:4) %>%
  mutate(radius = value / 10
         , xend = ifelse(xloc < 1.5, xloc - 0.5, xloc + 0.5)
         , ystart = ifelse(yloc < 1.5, yloc - radius, yloc + radius)
         , yend = ifelse(yloc < 1.5
                         , ystart - 0.25
                         , ystart + 0.25)) %>%
  ggplot() +
  geom_circle(aes(x0=xloc, 
                  y0=yloc,
                  r=radius,
                  fill= paste(xloc, yloc)) ) +
  coord_fixed() +
  geom_segment(aes(x = xloc,
                   xend = xend,
                   y = ystart,
                   yend = yend
  )) +
  theme_void() +
  theme(legend.position = "none")

给出

enter image description here