2017-01-16 33 views
2

我正在构建一个非常简单的气泡图,只有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()目前无法帮到我...

任何想法?

+0

'geom_point'将规模剧情大小变化时。一种解决方案是使用'geom_polygon'来代替圆圈,然后可以可靠地计算出接触点(中心+ - 半径)。 – Axeman

+0

mh ...如果不能用'geom_point'完成,也许'ggforce :: geom_circle()'是比'geom_polygon'更简单的方法' –

+0

是的。这比处理不断变化的结垢要少得多。 – Axeman

回答

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

如果你有超过两点,您可能需要在ggplot之外设置xend,方法是添加指定位置的列。同样,你也可以直接在数据中做半径和位置。

下面是计算这些指标的示例,然后将数据传递给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