[英]Spread overlapping points in a circle - R
I have a number of points in R which are overlapping -> my idea is to create a new coordinates column where I spread them out in a circle. 我在R中有许多重叠的点->我的想法是创建一个新的坐标列,在其中将它们散布成一个圆。
I don't want to jitter; 我不想抖动; it looks ugly and is misleading -> it makes the viewer think that the data is actually like that, rather than it has just been presented like that for visibility.
它看起来很丑陋,并且具有误导性->它使查看者认为数据实际上就是这样,而不是为了可视性而只是像这样呈现。
I think a circle or sunflower or star spread looks nice so that's what I want to do. 我认为圆圈,向日葵或星状散布看起来不错,所以这就是我想要做的。 What I have is not working great I think because of the geographic projections:
我认为,由于地理位置的原因,我的工作效果并不理想:
Example coordinates 坐标示例
(INPUT): (INPUT):
Latitude Longitude
51.52328 -0.1570965
51.52328 -0.1570965
51.52328 -0.1570965
51.52328 -0.1570965
51.52328 -0.1570965
OUTPUT: OUTPUT:
new_lat new_lng
51.50815 -0.1545583
51.53691 -0.1620067
51.51205 -0.1501359
51.53138 -0.1656516
51.51884 -0.1475074
My code at the moment: 我目前的代码:
#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
}
}
}
As I alluded to in the comments 正如我在评论中提到的
## 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)
Turns out I was just forgetting to convert to radians, and thus the below works (rawr's method also works well for me - so thank you!) 原来我只是忘了转换成弧度,因此下面的方法有效(原始方法对我也很有效-谢谢!)
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
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.