Расставить перекрывающиеся точки по кругу - R

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

Я не хочу дрожать; это выглядит некрасиво и вводит в заблуждение -> это заставляет зрителя думать, что данные на самом деле такие, а не просто так представлены для наглядности.

Я думаю, что разворот в виде круга, подсолнуха или звезды выглядит красиво, поэтому я хочу сделать это. То, что у меня есть, работает не очень хорошо, я думаю, из-за географических проекций:

До

После

Пример координат

(ВХОД):

Latitude    Longitude
51.52328    -0.1570965
51.52328    -0.1570965
51.52328    -0.1570965
51.52328    -0.1570965
51.52328    -0.1570965

ВЫХОД:

new_lat new_lng
51.50815    -0.1545583
51.53691    -0.1620067
51.51205    -0.1501359
51.53138    -0.1656516
51.51884    -0.1475074

Мой код на данный момент:

#http://geepeeex.com/LongitudesAndLatitudes.htm
#UK (122/78)
radius_size = 0.001
lat_radius_size = radius_size*(122/78)
many_stations$new_lat <- many_stations$Latitude
many_stations$new_lng <- many_stations$Longitude

for (i in unique(many_stations$Station)) {
# Get group-length = N
group_length = length(which(many_stations$Station == i))
#Cos/Sin take degrees not radians
circle_chunk = (360/group_length)
angle = circle_chunk
# If duplicates:
  if(group_length>1) {
    print(paste('group_length: ',group_length))
    # Loop within the group
    for (j in which(many_stations$Station == i)) {
      print(paste('row: ',j))

      many_stations[j,]$new_lng <- many_stations[j,]$Longitude + sin(angle)*radius_size
      many_stations[j,]$new_lat <- many_stations[j,]$Latitude + cos(angle)*lat_radius_size

      angle = angle + circle_chunk
    }
  }
}

person Ilia Karmanov    schedule 15.10.2015    source источник
comment
если бы вы перевели свой псевдокод в реальный код, я думаю, у вас не было бы всех закрытых и отрицательных голосов. почему бы просто не добавить случайный шум с помощью jitter вдоль x или y или обоих? или, если вы склоняетесь к идее круга, подумайте о своих точках как о полярных координатах с центром в {0,0}, добавьте случайный шум к радиусу и тета, преобразуйте обратно в x, y, используя полярные координаты. это кажется довольно простым для реализации   -  person rawr    schedule 16.10.2015
comment
@rawr Спасибо за ответ. Я сделал именно это и разместил пример изображения результата. Вы знаете, почему они не выходят как идеальный круг?   -  person Ilia Karmanov    schedule 17.10.2015
comment
можете ли вы dput образец данных, использованных для построения этого графика, т. е. воспроизводимый пример   -  person rawr    schedule 17.10.2015
comment
@rawr Я добавил группу координат, где вывод не является идеальным кругом - извините, я не уверен, как вывести таблицу   -  person Ilia Karmanov    schedule 17.10.2015
comment
до сих пор не могу следить, я не знаю, как выглядят данные вашей станции. Просто кажется, что вы не равномерно распределили градусы от 0 до 360 для x количества точек. Я обновил свой ответ, чтобы показать равномерное распределение по кругу   -  person rawr    schedule 18.10.2015


Ответы (2)


Как я уже упоминал в комментариях

## convert polar to cartesian
p2c <- function(radius, theta, deg = FALSE) {
  if (deg)
    theta <- theta * (pi / 180)
  list(x = radius * cos(theta),
       y = radius * sin(theta))
}

## convert cartesian to polar
c2p <- function(x, y, deg = FALSE) {
  list(radius = sqrt(x ** 2 + y ** 2),
       theta = atan2(y, x) * if (deg) 180 / pi else 1)
}

## convert to polar, add rad to radius and spread points, convert back
pdodge <- function(x, y, rad = 1) {
  stopifnot((lx <- length(x)) == length(y))
  p <- c2p(x, y)
  p <- within(p, {
    radius <- radius + rad
    theta  <- theta + rescaler(seq.int(lx + 1), c(0,359))[-(lx + 1)]
  })
  p2c(p$radius, p$theta, TRUE)
}

rescaler <- function(x, to = c(0, 1), from = range(x, na.rm = TRUE))
  (x - from[1]) / diff(from) * diff(to) + to[1]

set.seed(1)
par(mfrow = c(2,2), mar = c(5,5,2,1), las = 1)
pts <- rep(0, 10)
pl <- function(...) plot(..., xlim = c(-.5,.5), ylim = c(-.5,.5))

pl(pts, pts)
pl(jitter(pts), pts)
# pl(pts, jitter(pts))
pl(jitter(pts), jitter(pts))

pts <- pdodge(pts, pts, rad = .15)
pl(pts$x, pts$y)

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

person rawr    schedule 16.10.2015

Оказывается, я просто забыл преобразовать в радианы, и поэтому приведенное ниже работает (метод rawr также хорошо работает для меня - так что спасибо!)

radius_size = 0.001
many_stations$new_lat <- many_stations$Latitude
many_stations$new_lng <- many_stations$Longitude

for (i in unique(many_stations$Station)) {
# Get group-length = N
group_length = length(which(many_stations$Station == i))
circle_chunk = (360/group_length)
angle = circle_chunk
# If duplicates:
  if(group_length>1) {
    print(paste('group_length: ',group_length))
    # Loop within the group
    for (j in which(many_stations$Station == i)) {
      print(paste('row: ',j))

      many_stations[j,]$new_lng <- many_stations[j,]$Longitude + sin((pi/180)*angle)*radius_size
      many_stations[j,]$new_lat <- many_stations[j,]$Latitude + cos((pi/180)*angle)*radius_size

      angle = angle + circle_chunk
    }
  }
}
person Ilia Karmanov    schedule 19.10.2015