Arhn - архитектура программирования

Как показать ориентацию кривой в ggplot2?

У меня есть параметризованный контур, который я рисую в R. Я пытаюсь добавить стрелки вдоль кривой, чтобы показать зрителю, в каком направлении идет кривая.

Вот код, который я использую для создания кривой:

library(ggplot2)
library(grid)
set.seed(9)
T<-sort(runif(2^12,min=2^-5, max=16))

U<-function(t) exp(4*log(t) - 4*t)*(cos(log(t) + 3*t))
#Re(t^(4+1i)*t)*exp(-(4-3i)*t))
V<-function(t) exp(4*log(t) - 4*t)*(sin(log(t) + 3*t)) 
#Im(t^(4+1i)*t)*exp(-(4-3i)*t))


X<-sapply(T,U)
Y<-sapply(T,V)

df<-data.frame(X=X,Y=Y)

p<-ggplot(data=df,aes(x = df$X, y = df$Y))

p+theme_bw()+
geom_path(size=1,color='blue',linetype=1) #+
#geom_segment(aes(xend=c(tail(X, n=-1), NA), yend=c(tail(Y, n=-1), NA)),
#arrow=arrow(length=unit(0.2,"cm")),color='blue')
dev.off()

Последняя часть, которую я закомментировал:

#+
#geom_segment(aes(xend=c(tail(X, n=-1), NA), yend=c(tail(Y, n=-1), NA)),
#arrow=arrow(length=unit(0.2,"cm")),color='blue') 

делает что-то похожее на то, что я хочу, но стрелки расположены очень близко друг к другу, и кривая в конечном итоге выглядит «нечеткой», а не направленной.

Вот нечеткая и нечеткая версия кривой:

Нечеткая кривая

введите здесь описание изображения

Спасибо!

02.12.2016

Ответы:


1

Было бы лучше, если бы стрелки были более равномерно распределены вдоль изогнутого пути, например

введите здесь описание изображения

library(ggplot2)
library(grid)
set.seed(9)
T <- sort(runif(2^12,min=2^-5, max=16))
U <- function(t) exp(4*log(t) - 4*t)*(cos(log(t) + 3*t))
V <- function(t) exp(4*log(t) - 4*t)*(sin(log(t) + 3*t)) 
drough <- data.frame(x=sapply(T,U), y=sapply(T,V))


p <- ggplot(data = drough, aes(x = x, y = y))  + 
       geom_path() 

## because the parametric curve was generated with uneven spacing
## we can try to resample more evenly along the path
parametric_smoothie <- function(x, y, N=1e2, phase=1, offset=0) {

  lengths <- c(0, sqrt(diff(x)^2 + diff(y)^2))
  l <- cumsum(lengths)
  lmax <- max(l)
  newpos <- seq(phase*lmax/N, lmax-phase*lmax/N, length.out = N) + offset*lmax/N
  xx <- approx(l, x, newpos)$y
  yy <- approx(l, y, newpos)$y
  data.frame(x = xx, y = yy)
}

## this is a finer set of points
dfine <- parametric_smoothie(X, Y, 20)

gridExtra::grid.arrange(p + geom_point(data = drough, col="grey"),
                        p + geom_point(data = dfine, col="grey"), ncol=2)

введите здесь описание изображения

## now we use this function to create N start points for the arrows
## and another N end points slightly apart to give a sense of direction
relay_arrow <- function(x, y, N=10, phase = 0.8, offset = 1e-2, ...){

  start <- parametric_smoothie(x, y, N, phase)
  end <- parametric_smoothie(x, y, N, phase, offset)

  data.frame(xstart = start$x, xend = end$x, 
             ystart = start$y, yend = end$y)

}

breaks <- relay_arrow(drough$x, drough$y, N=20)

p + geom_point(data = breaks, aes(xstart, ystart), col="grey98", size=2) +
  geom_segment(data = breaks, aes(xstart, ystart, xend = xend, yend = yend), 
               arrow = arrow(length = unit(0.5, "line")),
               col="red", lwd=1)
03.12.2016
  • Эта идея динамического склона очень умна! Я приму это, если вы прокомментируете это больше, чтобы такие нубы, как я, могли это понять. 04.12.2016

  • 2

    Один из способов сделать это — нарисовать их после. Вероятно, вы можете лучше определить направление, используя эстетику угла (если это достаточно легко решить):

    p<-ggplot(data=df,aes(x = X, y = Y)) 
    p + 
      geom_path(size=1,color='blue',linetype=1)+ 
      geom_segment(data = df[seq(1, nrow(df), 20), ], aes(x = X, y = Y, xend=c(tail(X, n=-1), NA), yend=c(tail(Y, n=-1), NA)), 
      arrow=arrow(length=unit(0.2,"cm"), type = "closed"), color="blue", linetype = 0, inherit.aes = FALSE) 
    

    введите здесь описание изображения

    Обратите внимание на закрытую стрелку. Я должен был сделать это, чтобы они не интерпретировались как линии и, следовательно, исчезали, когда linetype = 0.

    02.12.2016

    3

    Попробуйте это с небольшой модификацией вашего кода (вы не хотите ставить под угрозу качество кривой, имея меньшее количество точек, и в то же время вы хотите иметь меньшее количество сегментов для рисования стрелок для лучшего качества стрелок). ):

    library(ggplot2)
    library(grid)
    set.seed(9)
    T<-sort(runif(2^12,min=2^-5, max=16))
    
    U<-function(t) exp(4*log(t) - 4*t)*(cos(log(t) + 3*t))
    #Re(t^(4+1i)*t)*exp(-(4-3i)*t))
    V<-function(t) exp(4*log(t) - 4*t)*(sin(log(t) + 3*t)) 
    #Im(t^(4+1i)*t)*exp(-(4-3i)*t))
    
    
    X<-sapply(T,U)
    Y<-sapply(T,V)
    
    df<-data.frame(X=X,Y=Y)
    df1 <- df[seq(1,length(X), 8),]
    
    p<-ggplot(data=df,aes(x = df$X, y = df$Y))
    
    p+theme_bw()+
      geom_path(size=1,color='blue',linetype=1) +
      geom_segment(data=df1,aes(x=X, y=Y, xend=c(tail(X, n=-1), NA), yend=c(tail(Y, n=-1), NA)),
                 arrow=arrow(length=unit(0.3,"cm"),type='closed'),color='blue')
    #dev.off()
    

    введите здесь описание изображения

    02.12.2016
  • Стрелки здесь хороши, но есть ли способ сделать линии, соединяющие наконечники, невидимыми? Хотя это определенно улучшение! Спасибо! 02.12.2016
  • может быть, вы можете попробовать df1 ‹- df[seq(1,length(X), 7),] или df1 ‹- df[seq(1,length(X), 6),] сегменты будут более неотличимы от кривая при уменьшении параметра 'by' функции seq(), но в то же время стрелки будут ближе. 02.12.2016
  • @GFauxPas Вы можете попробовать мою технику создания типа линии = 0. 05.12.2016
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..