R:リーフレットパッケージでヒートマップを作成する方法


10

パッケージを使用して、Rを使用したインタラクティブマップに関する投稿を読みましたleaflet

この記事では、著者は次のようなヒートマップを作成しました。

X=cbind(lng,lat)
kde2d <- bkde2D(X, bandwidth=c(bw.ucv(X[,1]),bw.ucv(X[,2])))

x=kde2d$x1
y=kde2d$x2
z=kde2d$fhat
CL=contourLines(x , y , z)

m = leaflet() %>% addTiles() 
m %>% addPolygons(CL[[5]]$x,CL[[5]]$y,fillColor = "red", stroke = FALSE)

私はbkde2D関数に精通していないので、このコードをシェープファイルに一般化できるかどうか疑問に思っていますか?

各ノードにヒートマップで表現したい特定の重みがある場合はどうなりますか?

leafletRのマップでヒートマップを作成する他の方法はありますか?


bke2dを使用すると、一連のポイントに対して2dビニング(カーネル密度推定)を実行できます(そのため、lng / latのペアがうまく機能します)。ksパッケージは、1次元から6次元までのデータのカーネル平滑化をサポートしています。akimaパッケージは補間を行うことができます(通常のグリッドが必要な場合に便利です)。データを適切に表していない可能性のあるものを生成する前に、このための空間タスクビューを読む価値があります。
hrbrmstr 2015年

わかりました、リンクをありがとう、私は間違いなくこれを見ます。実際、bke2d関数は、例で機能するため、私のデータではうまく機能していません。その理由を理解できません。
フェリペ

回答:


10

これはcontourLines、Rを使用してLeafletでより一般化されたヒートマップを作成するための私のアプローチです。このアプローチは、前述のブログ投稿と同様にを使用lapplyしますが、すべての結果を反復処理して一般的なポリゴンに変換するために使用します。前の例では、各ポリゴンを個別にプロットするのはユーザー次第なので、これを「より一般化した」と呼びます(少なくとも、これはブログの投稿を読んだときに望んでいた一般化です)。

## INITIALIZE
library("leaflet")
library("data.table")
library("sp")
library("rgdal")
# library("maptools")
library("KernSmooth")

inurl <- "https://data.cityofchicago.org/api/views/22s8-eq8h/rows.csv?accessType=DOWNLOAD"
infile <- "mvthefts.csv"

## LOAD DATA
## Also, clean up variable names, and convert dates
if(!file.exists(infile)){
    download.file(url = inurl, destfile = infile)
}
dat <- data.table::fread(infile)
setnames(dat, tolower(colnames(dat)))
setnames(dat, gsub(" ", "_", colnames(dat)))
dat <- dat[!is.na(longitude)]
dat[ , date := as.IDate(date, "%m/%d/%Y")]

## MAKE CONTOUR LINES
## Note, bandwidth choice is based on MASS::bandwidth.nrd()
kde <- bkde2D(dat[ , list(longitude, latitude)],
              bandwidth=c(.0045, .0068), gridsize = c(100,100))
CL <- contourLines(kde$x1 , kde$x2 , kde$fhat)

## EXTRACT CONTOUR LINE LEVELS
LEVS <- as.factor(sapply(CL, `[[`, "level"))
NLEV <- length(levels(LEVS))

## CONVERT CONTOUR LINES TO POLYGONS
pgons <- lapply(1:length(CL), function(i)
    Polygons(list(Polygon(cbind(CL[[i]]$x, CL[[i]]$y))), ID=i))
spgons = SpatialPolygons(pgons)

## Leaflet map with polygons
leaflet(spgons) %>% addTiles() %>% 
    addPolygons(color = heat.colors(NLEV, NULL)[LEVS])

この時点で得られるものは次のとおりです。 ここに画像の説明を入力してください

## Leaflet map with points and polygons
## Note, this shows some problems with the KDE, in my opinion...
## For example there seems to be a hot spot at the intersection of Mayfield and
## Fillmore, but it's not getting picked up.  Maybe a smaller bw is a good idea?

leaflet(spgons) %>% addTiles() %>%
    addPolygons(color = heat.colors(NLEV, NULL)[LEVS]) %>%
    addCircles(lng = dat$longitude, lat = dat$latitude,
               radius = .5, opacity = .2, col = "blue")

そして、これはポイントを含むヒートマップは次のようになります。

ここに画像の説明を入力してください

これは、いくつかのパラメーターを調整するか、おそらく別のカーネルを使用する必要があることを示唆する領域です。

ここに画像の説明を入力してください

## Leaflet map with polygons, using Spatial Data Frame
## Initially I thought that the data frame structure was necessary
## This seems to give the same results, but maybe there are some 
## advantages to using the data.frame, e.g. for adding more columns
spgonsdf = SpatialPolygonsDataFrame(Sr = spgons,
                                    data = data.frame(level = LEVS),
                                    match.ID = TRUE)
leaflet() %>% addTiles() %>%
    addPolygons(data = spgonsdf,
                color = heat.colors(NLEV, NULL)[spgonsdf@data$level])

これを理解しようとするインターウェブをひっくり返し、これは私が見つけた最も優れた例でした。それを私のコードに接続すると、「うまくいった」だけです。驚くばかり。ありがとうございました!
ジェフアレン

ありがとう!私は実際に他の人に役立つかもしれない他のいくつかのマップ例でリポジトリを作成しましたgithub.com/geneorama/wnv_map_demo
geneorama

このミニチュートリアルをありがとう。でどのように選択しbandwidthましたbkde2d()か?
the_darkside 2018

2
@the_darkside素晴らしい質問です。実際には、好きなものを手に入れるまでそれをいじっています。私は当初、帯域幅の仮定を調べるためにこのマップを特別に開発しました。この場合、私は実際に、出発点として使用MASS::bandwidth.nrd(dat$latitude)MASS::bandwidth.nrd(dat$longitude)ました。に?MASS::kde2dリンクするドキュメントを参照してくださいbandwith.nrd。また?KernSmooth::dpik、別のアプローチに興味があるかどうかも確認してください。
ジェネラマ2018

それ gridsize = c(100,100)は合計で10,000個のセルがあることを意味しますか?
the_darkside

4

上記のgenoramaの答えを基にして、fk値をラスターセル値として使用して、bkde2Dの出力を等高線ではなくラスターに変換することもできます。

library("leaflet")
library("data.table")
library("sp")
library("rgdal")
# library("maptools")
library("KernSmooth")
library("raster")

inurl <- "https://data.cityofchicago.org/api/views/22s8-eq8h/rows.csv?accessType=DOWNLOAD"
infile <- "mvthefts.csv"

## LOAD DATA
## Also, clean up variable names, and convert dates
if(!file.exists(infile)){
  download.file(url = inurl, destfile = infile)
}
dat <- data.table::fread(infile)
setnames(dat, tolower(colnames(dat)))
setnames(dat, gsub(" ", "_", colnames(dat)))
dat <- dat[!is.na(longitude)]
dat[ , date := as.IDate(date, "%m/%d/%Y")]

## Create kernel density output
kde <- bkde2D(dat[ , list(longitude, latitude)],
              bandwidth=c(.0045, .0068), gridsize = c(100,100))
# Create Raster from Kernel Density output
KernelDensityRaster <- raster(list(x=kde$x1 ,y=kde$x2 ,z = kde$fhat))

#create pal function for coloring the raster
palRaster <- colorNumeric("Spectral", domain = KernelDensityRaster@data@values)

## Leaflet map with raster
leaflet() %>% addTiles() %>% 
  addRasterImage(KernelDensityRaster, 
                 colors = palRaster, 
                 opacity = .8) %>%
  addLegend(pal = palRaster, 
            values = KernelDensityRaster@data@values, 
            title = "Kernel Density of Points")

これはあなたの出力です。低密度の値は、引き続きラスターに色付きで表示されることに注意してください。

ラスター出力

これらの低密度セルは、次のようにして削除できます。

#set low density cells as NA so we can make them transparent with the colorNumeric function
 KernelDensityRaster@data@values[which(KernelDensityRaster@data@values < 1)] <- NA

#create pal function for coloring the raster
palRaster <- colorNumeric("Spectral", domain = KernelDensityRaster@data@values, na.color = "transparent")

## Redraw the map
leaflet() %>% addTiles() %>% 
  addRasterImage(KernelDensityRaster, 
                 colors = palRaster, 
                 opacity = .8) %>%
  addLegend(pal = palRaster, 
            values = KernelDensityRaster@data@values, 
            title = "Kernel Density of Points")

これで、値が1未満のラスターセルは透明になります。

最終マップ

ビニングラスターが必要な場合は、colorNumeric関数ではなくcolorBin関数を使用します。

palRaster <- colorBin("Spectral", bins = 7, domain = KernelDensityRaster@data@values, na.color = "transparent")

## Leaflet map with raster
leaflet() %>% addTiles() %>% 
  addRasterImage(KernelDensityRaster, 
                 colors = palRaster, 
                 opacity = .8) %>%
  addLegend(pal = palRaster, 
            values = KernelDensityRaster@data@values, 
            title = "Kernel Density of Points")

ビン化されたラスターカーネル密度

スムーズにするには、関数bkde2Dのグリッドサイズを大きくするだけです。これにより、生成されるラスターの解像度が向上します。(私はそれを

gridsize = c(1000,1000)

出力:

平滑化ラスター


凡例の説明「カーネル密度のポイント」を「直方体あたりの盗難」などのより直感的なものに変換するにはどうすればよいですか?帯域幅、グリッドサイズ、射影、または単位を表すkdf $ fhatをリンクする方程式があると思います。
5

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.