Я хочу построить тепловую карту, показывающую близость автобусных остановок в Чикаго, используя расстояние Манхэттена (L1) вместо евклидова и обратно-квадратный вес, используя среднесуточное пассажирское судно в качестве масштабирующего фактора.Как я могу нарисовать вручную рассчитанные плотности на карте с помощью ggmap?
Для загрузки карты, я использую ggmap
require(ggmap)
chicago_map = get_map(location = c(lon=-87.64,lat=41.8787),zoom=14)
Вот пример работы с:
require(foreach)
require(geosphere)
bounding_box = bb = list(c(41.96,-87.75),c(41.80,-87.6))
meter_per_lat = distVincentyEllipsoid(rev(bb[[1]]),
rev(bb[[1]] + c(1,0)))
meter_per_lon = distVincentyEllipsoid(rev(bb[[1]]),
rev(bb[[1]] + c(0,1)))
dist_converter = c(meter_per_lon, meter_per_lat)
dist_manhattan <- function(p1, p2){
#assume 20 meters is the smallest distance between points
pmax(20,abs(sweep(p2,2, p1)) %*% dist_converter)
}
set.seed(0)
sample_data = data.frame(longitude=runif(20,bb[[1]][2],bb[[2]][2]),
latitude =runif(20,bb[[2]][1],bb[[1]][1]),
mean_riders=4*rpois(20,500))
chicago_grid = expand.grid(latitude=seq(bb[[1]][1], bb[[2]][1],length.out=200),
longitude=seq(bb[[1]][2],bb[[2]][2],length.out=400))
mean_values = foreach(i=1:20, .combine='+') %do% {
row = sample_data[i,]
dists = dist_manhattan(c(row$longitude,row$latitude),
as.matrix(chicago_grid[,c('longitude','latitude')]))
return(row$mean_riders/dists^2)
}
chicago_data = chicago_grid
chicago_data$rider_weight = mean_values
И для черчения, я приблизительно с geom_point()
ggmap(chicago_map, extent='device') + geom_point(data=chicago_data,
aes(x=longitude,y=latitude,color=rider_weight,alpha=0.2,shape='15',size=4)) +
scale_alpha_identity() + scale_color_gradient(low='blue',high='red') +
scale_size_identity() + guides(shape='none') + ggtitle('Chicago Station Example Map')
Хотя вы можете видеть части «тепловой карты» несколько четко, это, очевидно, не оптимальное решение.
Если я пытаюсь использовать geom_tile
, я могу получить ладно выглядящий карту, но это занимает гораздо больше времени, чтобы произвести (что не желательно)
ggmap(chicago_map, extent='device') + geom_tile(data=chicago_data,
aes(x=longitude,y=latitude,fill=rider_weight,alpha=0.6)) +
scale_alpha_identity() + scale_fill_gradient(low='blue',high='red') +
scale_size_identity() + guides(shape='none') + ggtitle('Chicago Station Example Map')
Я также могу заменить geom_tile
на geom_raster
, но geom_raster
не работает вне декартовых координат. В частности, ошибка,
Ошибка: geom_raster работает только с декартовыми координатами
Есть ли лучший способ выполнить эту задачу?
В чем проблема с двумя методами, которые вы продемонстрировали? Я думаю, что странные строки над графиком - проблема с первым? и второй? –
Вы рисуете вес всадника как синий в областях без станций/данных? Если да, то не имеет смысла не путать какой-либо цвет, где нет станции/данных? –
Второй очень медленный, особенно для больших карт и более тонких гранулярностей. Я надеялся, что существует более быстрый способ создания интерполированной графики вместо медленного метода ggplot с этим. Например, первый график взял мой компьютер менее 1 секунды для генерации, а второй занял около 16 секунд. –