ggplot2 добавление динамических аннотаций стрелок, указывающих на определенные точки данных, которые остаются пропорциональными масштабу всего графика - PullRequest
0 голосов
/ 15 мая 2018

Я хотел бы создать шаблон, который позволил бы мне создать линейный график цен на акции с возможностью добавления стрелок, указывающих на конкретные даты.Функция аннотации на ggplot2 не позволяет изменять размеры с масштабом графика.Есть ли обходной путь?

Например, на этом графике только с 6 датами стрелки имеют правильный размер с диаграммой:

prices<-c(3,5,28,17,62,10)
prices2<-prices-1
prices3<-prices-11
dates<-seq.Date(from=as.Date("2018-1-1"),to=as.Date("2018-1-6"),"days")

ggplot()+
geom_line(aes(dates,prices))+
annotate(
"segment",
x=dates,
xend=dates,
y=prices3,
yend=prices2,
color="blue",
arrow=arrow(length=unit(0.5,"cm")
            ))

enter image description here

Однако когдаЯ увеличиваю период до 15 дат, стрелки не пропорционально масштабируются и выглядят так:

enter image description here

1 Ответ

0 голосов
/ 15 мая 2018

Я не уверен, что именно вы подразумеваете под пропорциональным, это по существу такая же пропорциональная длина, что и первая цифра?Если это так, так как длина стрелки контролируется prices2 и prices3, вы можете просто выяснить, сколько места они занимают пропорционально на первом рисунке, а затем вычислить для второго.Объедините с npc для наконечника стрелы, и это должно примерно дать вам то, что вы хотите.Сама стрелка не идеальна из-за оси х, но я думаю, что она ближе, чем у вас прежде.

Итак, используя ваши данные:

# original data
prices<-c(3,5,28,17,62,10)
dates<-seq.Date(from=as.Date("2018-1-1"),to=as.Date("2018-1-6"),"days")

# original plot (with 0.05 npc)
ggplot()+
    geom_line(aes(dates,prices))+
    annotate(
        "segment",
        x=dates,
        xend=dates,
        y=prices-11,
        yend=prices-1,
        color="blue",
        arrow=arrow(length=unit(0.05,"npc")
        ))

enter image description here

# new data
prices2<-c(prices,c(20,250,30,60,40))
dates2 <- seq.Date(from=as.Date("2018-1-1"),to=as.Date("2018-1-11"),"days")

# compute length of arrow
p1 <- abs(min(prices)-11)+max(prices)
fs1<-function(x) { (abs(min(prices2)-x)+max(prices2))*11/p1-x }
y1<-uniroot(fs2,lower=0,upper=100)$root

p2 <- abs(min(prices)-1)+max(prices)
fs2<-function(x) { (abs(min(prices2)-x)+max(prices2))*1/p2-x }
y2<-uniroot(fs1,lower=0,upper=100)$root

# new plot
ggplot()+
geom_line(aes(dates2,prices2))+
annotate(
    "segment",
    x=dates2,
    xend=dates2,
    y=prices2-y1,
    yend=prices2-y2,
    color="blue",
    arrow=arrow(length=unit(0.05,"npc")
    ))

enter image description here

...