2017-01-16 9 views
2

Я строю очень простую диаграмму с двумя наблюдениями. Я хотел бы добавить к каждому пузырю добавку, чтобы добавить метки позже. Точка контакта должна находиться в верхней или нижней части каждого пузыря.Как добавить тангенсы в пузыри

Пример:

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 работал очень пятно. Вам нужно взять немного ухода с настройкой размера радиуса, и с тем, как вы разместите координаты х, но это, кажется, работает гладко:

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