Я хотел бы использовать что-то вроде ggplot2
и ggmap
до , чтобы получить тепловую карту произвольных значений , таких как цены на квадратный метр по географическому району на уровне улицы(с высоким разрешением) .
К сожалению, задача представляется довольно сложной, поскольку, хотя ggplot2
может создать график с большой плотностью, он, похоже, не способен визуализировать пространственные данные, подобные этой, без предварительной интерполяции.
Для этого я использовал библиотеки akima
(двумерная интерполяция с сеткой для нерегулярных данных) и mgcv
(обобщенные аддитивные модели с интегрированной оценкой гладкости), однако мои знания методов интерполяции в лучшем случае посредственны ирезультаты, которые я смог получить, недостаточно удовлетворительны.
Рассмотрим следующий пример:
Данные
library(ggplot2)
library(ggmap)
## data simulation
set.seed(1945)
df <- tibble(x = rnorm(500, -0.7406, 0.03),
y = rnorm(500, 51.9976, 0.03),
z = abs(rnorm(500, 2000, 1000)))
Карта, диаграмма рассеяния, график плотности
## ggmap
map <- get_map("Bletchley Park, Bletchley, Milton Keynes", zoom = 13, source = "stamen", maptype = "toner-background")
q <- ggmap(map, extent = "device", darken = .5)
## scatterplot over map
q + geom_point(aes(x, y), data = df, colour = z)
## classic density heat map
q +
stat_density2d(aes(x=x, y=y, fill=..level..), data=df, geom="polygon", alpha = .2) +
geom_density_2d(aes(x=x, y=y), data=df, colour = "white", alpha = .4) +
scale_fill_distiller(palette = "Spectral")
Как видите, данные довольно плотны по выбранной области, и карта плотности плотности отлично смотрится с закругленными краями иd замкнутые кривые (за исключением некоторых внешних слоев).
Интерполяция и построение графиков с использованием akima
## akima interpolation
library(akima)
df_akima <-interp2xyz(interp(x=df$x, y=df$y, z=df$z, duplicate="mean", linear = T,
xo=seq(min(df$x), max(df$x), length=200),
yo=seq(min(df$y), max(df$y), length=200)), data.frame=TRUE)
## akima plot
q +
geom_tile(aes(x = x, y = y, fill = z), data = df_akima, alpha = .4) +
stat_contour(aes(x = x, y = y, z = z, fill = ..level..), data = df_akima, geom = 'polygon', alpha = .4) +
geom_contour(aes(x = x, y = y, z = z), data = df_akima, colour = 'white', alpha = .4) +
scale_fill_distiller(palette = "Spectral", na.value = NA)
Это приводит кплотная сетка интерполированных значений (для обеспечения достаточного разрешения), и в то время как нижний график является приемлемым, контурные графики слишком рваные, и многие кривые не закрыты.
Нелинейная интерполяция с использованием linear = F
является более плавной, но, по-видимому, жертвует разрешением и сходит с ума с числами (отрицательные значения z
).
Интерполяция и построение графиков с использованием mgcv
## mgcv interpolation
library(mgcv)
gam <- gam(z ~ s(x, y, bs = 'sos'), data = df)
df_mgcv <- data.frame(expand.grid(x = seq(min(df$x), max(df$x), length=200),
y = seq(min(df$y), max(df$y), length=200)))
resp <- predict(gam, df_mgcv, type = "response")
df_mgcv$z <- resp
## mgcv plot
q +
geom_tile(aes(x = x, y = y, fill = z), data = df_mgcv, alpha = .4) +
stat_contour(aes(x = x, y = y, z = z, fill = ..level..), data = df_mgcv, geom = 'polygon', alpha = .4) +
geom_contour(aes(x = x, y = y, z = z), data = df_mgcv, colour = 'white', alpha = .4) +
scale_fill_distiller(palette = "Spectral", na.value = NA)
Тот же процесс с использованием mgcv
приводит к красивому и плавному графику, но разрешение намного ниже, и практически все кривые не закрыты.
Вопросы
Не могли бы вы предложить лучший метод или изменить мою попытку получить график, похожий на первый (чистые, соединенные и плавные линии с высоким разрешением)?
Можно ли закрытькривые, например, на последнем графике (заштрихованная область должна быть рассчитана за пределами границ изображения)?
Спасибо за потраченное время!