使用 leaflet 创建交互式地图
使用标记、弹出窗口和图块图层渲染交互式网络地图
使用 leaflet 创建交互式地图 是 CoddyKit 上的免费 R Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。
leaflet 简介
leaflet 软件包封装了 Leaflet.js 库,可以直接从 R 创建可交互、可缩放的网页地图。地图是 HTML 小部件,可在 RStudio 的 Viewer、R Markdown 和 Shiny 应用中渲染,无需了解 JavaScript。
library(leaflet)
# Minimal leaflet map: tiles + one marker
leaflet() |>
addTiles() |> # OpenStreetMap base layer
setView(
lng = -74.006,
lat = 40.713,
zoom = 12
) |>
addMarkers(
lng = -74.006,
lat = 40.713,
popup = '<b>New York City</b>'
)addTiles:底图图层
addTiles() 会添加默认的 OpenStreetMap 瓦片图层。使用 addProviderTiles(providers$ 可以切换到卫星影像、CartoDB、Esri、Stamen 或其他瓦片提供商。图层名称位于内置的 providers 列表中。
library(leaflet)
# Default OpenStreetMap
map1 <- leaflet() |> addTiles()
# CartoDB light theme (great for data overlay)
map2 <- leaflet() |>
addProviderTiles(providers$CartoDB.Positron)
# Satellite imagery
map3 <- leaflet() |>
addProviderTiles(providers$Esri.WorldImagery)
# Custom tile URL
custom <- leaflet() |>
addTiles(
urlTemplate = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution = '(c) OpenStreetMap contributors'
)
map2使用 addMarkers 添加弹出窗口
addMarkers(lng, lat, popup) 会向地图添加图钉标记。popup 参数接受 HTML 字符串,因此您可以加入粗体文本、链接或图像。label 参数会在鼠标悬停时显示文本,无需点击。
library(leaflet)
cities <- data.frame(
name = c('New York', 'Los Angeles', 'Chicago'),
lon = c(-74.006, -118.244, -87.629),
lat = c( 40.713, 34.052, 41.878),
pop = c(8336817, 3979576, 2693976)
)
leaflet(cities) |>
addTiles() |>
addMarkers(
lng = ~lon,
lat = ~lat,
popup = ~paste0(
'<b>', name, '</b><br>',
'Population: ', format(pop, big.mark = ',')
),
label = ~name
)addCircleMarkers
addCircleMarkers() 绘制大小固定为屏幕像素的圆(不同于会随缩放级别变化的 addCircles())。它们非常适合表示比例符号——将 radius 映射到某个数据变量。
library(leaflet)
cities <- data.frame(
name = c('New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix'),
lon = c(-74.006, -118.244, -87.629, -95.369, -112.074),
lat = c( 40.713, 34.052, 41.878, 29.760, 33.449),
pop = c(8336817, 3979576, 2693976, 2304580, 1608139)
)
leaflet(cities) |>
addProviderTiles(providers$CartoDB.Positron) |>
addCircleMarkers(
lng = ~lon,
lat = ~lat,
radius = ~sqrt(pop / 50000),
color = 'steelblue',
fill = TRUE,
fillOpacity = 0.6,
popup = ~paste0(name, ': ', format(pop, big.mark = ','))
)addPolygons:分级设色地图
addPolygons() 直接从 sf 对象绘制多边形几何图形。可以使用 colorNumeric() 或 colorBin() 调色板函数,将填充颜色映射到数据列。highlight 选项可以添加悬停效果。
library(leaflet)
library(sf)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 4326
)
# Colour palette based on birth count
pal <- colorNumeric('YlOrRd', domain = nc$BIR74)
leaflet(nc) |>
addProviderTiles(providers$CartoDB.Positron) |>
addPolygons(
fillColor = ~pal(BIR74),
fillOpacity = 0.7,
color = 'white',
weight = 1,
popup = ~paste0('<b>', NAME, '</b><br>Births 1974: ', BIR74),
highlight = highlightOptions(
weight = 3,
color = '#333',
bringToFront = TRUE
)
) |>
addLegend('bottomright', pal = pal, values = ~BIR74, title = 'Births 1974')setView 和 fitBounds
setView(lng, lat, zoom) 将地图中心设置在固定位置,并设定缩放级别。fitBounds(lng1, lat1, lng2, lat2) 会自动缩放地图,以适应地理边界框;当您事先不知道数据范围时,这一功能非常有用。
library(leaflet)
library(sf)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 4326
)
bbox <- st_bbox(nc)
# fitBounds: auto-zoom to data extent
leaflet() |>
addTiles() |>
fitBounds(
lng1 = bbox['xmin'], lat1 = bbox['ymin'],
lng2 = bbox['xmax'], lat2 = bbox['ymax']
) |>
addPolygons(
data = nc,
fillColor = 'lightblue',
fillOpacity = 0.4,
color = 'steelblue',
weight = 1
)addLayersControl:切换图层
addLayersControl() 添加单选按钮或复选框控件,用于打开或关闭底图和叠加图层。对于互斥的瓦片图层,请使用 baseGroups;对于可以独立切换的数据图层,请使用 overlayGroups。
library(leaflet)
library(sf)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 4326
)
high_birth <- nc[nc$BIR74 > 3000, ]
low_birth <- nc[nc$BIR74 <= 3000, ]
leaflet() |>
addProviderTiles(providers$CartoDB.Positron, group = 'Light') |>
addProviderTiles(providers$Esri.WorldImagery, group = 'Satellite') |>
addPolygons(data = high_birth, color = 'red', group = 'High Births (>3000)') |>
addPolygons(data = low_birth, color = 'blue', group = 'Low Births (<=3000)') |>
addLayersControl(
baseGroups = c('Light', 'Satellite'),
overlayGroups = c('High Births (>3000)', 'Low Births (<=3000)'),
options = layersControlOptions(collapsed = FALSE)
)addPopups 和 addLegend
addPopups() 添加持久显示(始终可见)的弹出框。addLegend() 创建与调色板关联的地图图例。两者都支持 HTML 内容,并且可以通过 CSS 类进行全面自定义。
library(leaflet)
leaflet() |>
addTiles() |>
setView(-79.0, 35.5, zoom = 7) |>
addPopups(
lng = -78.639,
lat = 35.779,
popup = '<b>Raleigh</b><br>State Capital of NC'
) |>
addLegend(
position = 'bottomleft',
colors = c('red', 'blue', 'green'),
labels = c('High', 'Medium', 'Low'),
title = 'Risk Level',
opacity = 0.8
)颜色调色板:colorNumeric 和 colorBin
colorNumeric()、colorBin()、colorQuantile() 和 colorFactor() 函数会创建调色板函数,将数据值映射为十六进制颜色。将结果传递给 fillColor,并将同一个调色板传递给 addLegend()。
library(leaflet)
library(sf)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 4326
)
# Continuous palette
pal_num <- colorNumeric('Blues', domain = nc$BIR74)
# Binned palette (5 equal bins)
pal_bin <- colorBin('RdYlGn', domain = nc$BIR74, bins = 5)
# Quantile palette (equal number of features per class)
pal_qtl <- colorQuantile('YlOrRd', domain = nc$BIR74, n = 4)
# Use binned palette
leaflet(nc) |>
addTiles() |>
addPolygons(
fillColor = ~pal_bin(BIR74),
fillOpacity = 0.7, weight = 1, color = 'white'
) |>
addLegend('bottomright', pal = pal_bin, values = ~BIR74,
title = 'Births 1974 (5 bins)')leafletProxy:在 Shiny 中更新地图
leafletProxy('mapId') 可以在 Shiny 应用中更新已有的 leaflet 地图,而无需从头重新渲染整张地图。将它与 clearMarkers()、clearShapes() 或 addMarkers() 搭配使用,可以高效地响应用户输入。
library(shiny)
library(leaflet)
# Minimal Shiny app with leafletProxy
ui <- fluidPage(
selectInput('colour', 'Marker colour:', choices = c('red', 'blue', 'green')),
leafletOutput('map')
)
server <- function(input, output, session) {
output$map <- renderLeaflet({
leaflet() |> addTiles() |>
setView(-79.0, 35.5, zoom = 7)
})
observeEvent(input$colour, {
leafletProxy('map') |>
clearMarkers() |>
addCircleMarkers(
lng = -78.639, lat = 35.779,
color = input$colour,
label = paste('Raleigh -', input$colour)
)
})
}
# shinyApp(ui, server) # uncomment to run完整的交互式分级设色地图
下面是一个达到生产质量的分级设色地图示例,结合了所有关键功能:提供商瓦片、多边形填充、悬停高亮、动态弹出框、颜色图例和图层控件——全部代码不到 25 行。
library(leaflet)
library(sf)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 4326
)
pal <- colorQuantile('YlOrRd', domain = nc$SID74, n = 5)
leaflet(nc) |>
addProviderTiles(providers$CartoDB.Positron) |>
addPolygons(
fillColor = ~pal(SID74),
fillOpacity = 0.75,
color = 'white',
weight = 0.5,
popup = ~paste0('<b>', NAME, '</b><br>SIDS 1974: ', SID74),
highlight = highlightOptions(
weight = 2, color = '#555', bringToFront = TRUE
)
) |>
addLegend(
position = 'bottomright',
pal = pal, values = ~SID74,
title = 'SIDS Deaths 1974<br>(Quintiles)'
) |>
addControl('<b>NC SIDS Data 1974</b>', position = 'topright')快速检查
在 Shiny 应用中,当用户更改下拉菜单时,您希望更新现有 leaflet 地图上的标记位置,同时不重新渲染整张地图。应该使用哪个函数?
回顾:leaflet 包
要点:
leaflet() |> addTiles()使用 OpenStreetMap 瓦片创建交互式地图addProviderTiles(providers$切换到其他瓦片提供商) - 点数据使用
addMarkers()/addCircleMarkers();同时使用popup和label - 使用
addPolygons(fillColor = ~pal(col))创建分级设色地图 colorNumeric()、colorBin()、colorQuantile()创建调色板函数addLegend()与调色板函数配合使用;addLayersControl()用于切换图层- 使用
leafletProxy()高效更新 Shiny 地图 fitBounds()自动缩放到数据范围
library(leaflet)
# Three-line interactive map
leaflet() |>
addProviderTiles(providers$CartoDB.Positron) |>
addCircleMarkers(lng = c(-74, -118, -88), lat = c(41, 34, 42),
label = c('NYC', 'LA', 'Chicago'), color = 'steelblue')常见问题解答
「使用 leaflet 创建交互式地图」课时是免费的吗?
是的 — 「使用 leaflet 创建交互式地图」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。
「使用 leaflet 创建交互式地图」这节课中我会学到什么?
使用标记、弹出窗口和图块图层渲染交互式网络地图 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 R Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「使用 leaflet 创建交互式地图」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 R Academy 课中编写并运行代码吗?
能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 使用 sf 软件包处理简单要素
- 坐标参考系与投影
- 空间连接与空间操作
- 使用 leaflet 创建交互式地图