data = (
lng = [-122.4, -122.45, -122.35, -122.42, -122.38, -122.41, -122.43, -122.39],
lat = [37.8, 37.75, 37.85, 37.78, 37.82, 37.79, 37.81, 37.77],
size = [100, 150, 80, 120, 90, 110, 95, 130]
)
layer = ScatterplotLayer(
data = data,
get_position = [:lng, :lat],
get_radius = :size,
get_fill_color = [255, 140, 0, 200],
radius_min_pixels = 5,
radius_max_pixels = 50
)
Deck(layer, initial_view_state = ViewState(longitude=-122.4, latitude=37.8, zoom=12))Examples
Interactive examples demonstrating each DeckGL.jl layer type. Each visualization is generated by DeckGL.jl and rendered using deck.gl.
ScatterplotLayer
Renders circles at geographic coordinates. Size and color can be data-driven.
ArcLayer
Renders arcs between source and target coordinates. Great for showing connections or flows.
trips = (
src_lng = [-122.4, -122.4, -122.4, -73.9, -87.6],
src_lat = [37.8, 37.8, 37.8, 40.7, 41.9],
dst_lng = [-73.9, -87.6, -118.2, -87.6, -118.2],
dst_lat = [40.7, 41.9, 34.0, 41.9, 34.0]
)
layer = ArcLayer(
data = trips,
get_source_position = [:src_lng, :src_lat],
get_target_position = [:dst_lng, :dst_lat],
get_source_color = [0, 128, 255],
get_target_color = [255, 0, 128],
get_width = 3
)
Deck(layer, initial_view_state = ViewState(longitude=-98, latitude=39, zoom=3, pitch=30))LineLayer
Renders straight lines between points. Simpler than arcs, useful for direct connections.
connections = (
from_lng = [-122.4, -122.45, -122.35, -122.42, -122.38],
from_lat = [37.8, 37.75, 37.85, 37.78, 37.82],
to_lng = [-122.45, -122.35, -122.4, -122.38, -122.43],
to_lat = [37.75, 37.85, 37.8, 37.82, 37.77]
)
layer = LineLayer(
data = connections,
get_source_position = [:from_lng, :from_lat],
get_target_position = [:to_lng, :to_lat],
get_color = [64, 192, 128, 200],
get_width = 3
)
Deck(layer, initial_view_state = ViewState(longitude=-122.4, latitude=37.8, zoom=12))PathLayer
Renders polylines/paths from sequences of coordinates. Ideal for routes, tracks, or boundaries.
routes = (
path = [
[[-122.4, 37.8], [-122.42, 37.78], [-122.44, 37.76], [-122.45, 37.75]],
[[-122.35, 37.85], [-122.37, 37.83], [-122.39, 37.81], [-122.4, 37.8]],
[[-122.43, 37.82], [-122.41, 37.79], [-122.38, 37.77], [-122.36, 37.76]]
],
color = [[0, 128, 255], [255, 128, 0], [128, 0, 255]]
)
layer = PathLayer(
data = routes,
get_path = :path,
get_color = :color,
get_width = 5,
cap_rounded = true,
joint_rounded = true
)
Deck(layer, initial_view_state = ViewState(longitude=-122.4, latitude=37.8, zoom=12))PolygonLayer
Renders filled polygons. Supports 3D extrusion for building-like visualizations.
regions = (
polygon = [
[[-122.42, 37.78], [-122.44, 37.76], [-122.42, 37.74], [-122.40, 37.76]],
[[-122.38, 37.82], [-122.40, 37.80], [-122.37, 37.79], [-122.35, 37.81]],
[[-122.45, 37.80], [-122.47, 37.78], [-122.45, 37.76], [-122.43, 37.78]]
],
height = [200, 300, 150],
color = [[255, 140, 0, 180], [0, 140, 255, 180], [140, 255, 0, 180]]
)
layer = PolygonLayer(
data = regions,
get_polygon = :polygon,
get_fill_color = :color,
get_line_color = [80, 80, 80],
extruded = true,
get_elevation = :height,
elevation_scale = 10
)
Deck(layer, initial_view_state = ViewState(longitude=-122.4, latitude=37.78, zoom=12, pitch=45, bearing=15))TextLayer
Renders text labels at geographic coordinates.
cities = (
lng = [-122.4, -122.45, -122.35, -122.42, -122.38],
lat = [37.8, 37.75, 37.85, 37.77, 37.82],
name = ["Downtown SF", "Daly City", "Berkeley", "Mission", "Marina"],
size = [20, 16, 16, 14, 14]
)
points_layer = ScatterplotLayer(
data = cities,
get_position = [:lng, :lat],
get_radius = 100,
get_fill_color = [255, 0, 0, 200],
radius_min_pixels = 5
)
text_layer = TextLayer(
data = cities,
get_position = [:lng, :lat],
get_text = :name,
get_size = :size,
get_color = [0, 0, 0, 255],
get_pixel_offset = [0, -20]
)
Deck([points_layer, text_layer], initial_view_state = ViewState(longitude=-122.4, latitude=37.8, zoom=11))HexagonLayer
Aggregates points into hexagonal bins. Height represents density or aggregated values.
using Random
Random.seed!(42)
# Generate clustered point data
points_data = let
lngs = Float64[]
lats = Float64[]
clusters = [(-122.4, 37.8, 500), (-122.45, 37.75, 300), (-122.35, 37.82, 400)]
for (cx, cy, n) in clusters
append!(lngs, cx .+ 0.025 .* randn(n))
append!(lats, cy .+ 0.025 .* randn(n))
end
(lng = lngs, lat = lats)
end
layer = HexagonLayer(
data = points_data,
get_position = [:lng, :lat],
radius = 200,
elevation_scale = 50,
elevation_range = [0, 500],
extruded = true,
coverage = 0.9
)
Deck(layer, initial_view_state = ViewState(longitude=-122.4, latitude=37.8, zoom=11, pitch=45, bearing=15))GridLayer
Similar to HexagonLayer but uses rectangular grid cells.
Random.seed!(123)
grid_data = let
lngs = Float64[]
lats = Float64[]
centers = [(-122.4, 37.8), (-122.45, 37.76), (-122.35, 37.83)]
for _ in 1:1000
cx, cy = centers[rand(1:3)]
push!(lngs, cx + (rand() - 0.5) * 0.04)
push!(lats, cy + (rand() - 0.5) * 0.04)
end
(lng = lngs, lat = lats)
end
layer = GridLayer(
data = grid_data,
get_position = [:lng, :lat],
cell_size = 200,
elevation_scale = 50,
elevation_range = [0, 300],
extruded = true,
coverage = 0.9
)
Deck(layer, initial_view_state = ViewState(longitude=-122.4, latitude=37.8, zoom=11, pitch=45, bearing=-15))HeatmapLayer
Renders a smooth density heatmap. Great for visualizing point density.
Random.seed!(456)
heatmap_data = let
lngs = Float64[]
lats = Float64[]
weights = Float64[]
clusters = [(-122.41, 37.79, 2000), (-122.43, 37.77, 1500), (-122.38, 37.81, 1200), (-122.45, 37.75, 800)]
for (cx, cy, n) in clusters
for _ in 1:n
push!(lngs, cx + (rand() - 0.5) * 0.03)
push!(lats, cy + (rand() - 0.5) * 0.03)
push!(weights, rand())
end
end
(lng = lngs, lat = lats, weight = weights)
end
layer = HeatmapLayer(
data = heatmap_data,
get_position = [:lng, :lat],
get_weight = :weight,
radius_pixels = 40,
intensity = 1,
threshold = 0.03
)
Deck(layer, initial_view_state = ViewState(longitude=-122.41, latitude=37.78, zoom=12))GeoJsonLayer
Renders GeoJSON data including points, lines, and polygons.
geojson_data = Dict(
"type" => "FeatureCollection",
"features" => [
Dict(
"type" => "Feature",
"geometry" => Dict(
"type" => "Polygon",
"coordinates" => [[[-122.45, 37.78], [-122.43, 37.75], [-122.40, 37.76], [-122.41, 37.79], [-122.45, 37.78]]]
),
"properties" => Dict("name" => "Region A")
),
Dict(
"type" => "Feature",
"geometry" => Dict(
"type" => "Polygon",
"coordinates" => [[[-122.40, 37.82], [-122.38, 37.80], [-122.35, 37.81], [-122.36, 37.84], [-122.40, 37.82]]]
),
"properties" => Dict("name" => "Region B")
),
Dict(
"type" => "Feature",
"geometry" => Dict(
"type" => "LineString",
"coordinates" => [[-122.45, 37.78], [-122.42, 37.80], [-122.40, 37.82]]
),
"properties" => Dict("name" => "Route 1")
),
Dict(
"type" => "Feature",
"geometry" => Dict("type" => "Point", "coordinates" => [-122.42, 37.78]),
"properties" => Dict("name" => "Point A")
),
Dict(
"type" => "Feature",
"geometry" => Dict("type" => "Point", "coordinates" => [-122.37, 37.82]),
"properties" => Dict("name" => "Point B")
)
]
)
layer = GeoJsonLayer(
data = geojson_data,
filled = true,
stroked = true,
get_fill_color = [255, 140, 0, 150],
get_line_color = [0, 0, 0, 200],
get_line_width = 2,
get_point_radius = 200,
line_width_min_pixels = 2,
point_radius_min_pixels = 5
)
Deck(layer, initial_view_state = ViewState(longitude=-122.4, latitude=37.79, zoom=12))Multiple Layers
Combine multiple layer types in a single visualization.
cities_multi = (
lng = [-122.4, -122.27, -122.22],
lat = [37.8, 37.87, 37.77],
name = ["San Francisco", "Berkeley", "Oakland"],
size = [300, 200, 250]
)
routes_multi = (
path = [
[[-122.4, 37.8], [-122.35, 37.82], [-122.27, 37.87]],
[[-122.4, 37.8], [-122.32, 37.78], [-122.22, 37.77]],
[[-122.27, 37.87], [-122.25, 37.82], [-122.22, 37.77]]
],
)
path_layer = PathLayer(
data = routes_multi,
get_path = :path,
get_color = [100, 100, 100, 150],
get_width = 3,
cap_rounded = true
)
scatter_layer = ScatterplotLayer(
data = cities_multi,
get_position = [:lng, :lat],
get_radius = :size,
get_fill_color = [0, 128, 255, 200],
radius_min_pixels = 10
)
label_layer = TextLayer(
data = cities_multi,
get_position = [:lng, :lat],
get_text = :name,
get_size = 16,
get_color = [0, 0, 0],
get_pixel_offset = [0, -30]
)
Deck([path_layer, scatter_layer, label_layer], initial_view_state = ViewState(longitude=-122.32, latitude=37.82, zoom=11))Base Maps
Add a base map using the map_style parameter. DeckGL.jl supports any MapLibre-compatible tile source. Here are some free options:
- OpenStreetMap:
https://basemaps.cartocdn.com/gl/positron-gl-style/style.json - CartoDB Dark:
https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json - CartoDB Voyager:
https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json
airports = (
lng = [-122.38, -73.78, -87.90, -118.41, -84.43],
lat = [37.62, 40.64, 41.98, 33.94, 33.64],
name = ["SFO", "JFK", "ORD", "LAX", "ATL"],
passengers = [50, 60, 80, 85, 110] # millions
)
layer = ScatterplotLayer(
data = airports,
get_position = [:lng, :lat],
get_radius = :passengers,
get_fill_color = [255, 0, 80, 180],
radius_scale = 5000,
radius_min_pixels = 5,
pickable = true
)
Deck(
layer,
initial_view_state = ViewState(longitude=-98, latitude=38, zoom=3.5, pitch=0),
map_style = "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"
)Dark Theme Base Map
The dark matter style works well for visualizations with bright colors.
earthquakes = (
lng = [-122.0, -121.5, -117.5, -116.0, -118.2, -119.5, -122.5, -120.0],
lat = [37.0, 36.5, 34.0, 33.5, 34.2, 35.0, 38.0, 35.5],
magnitude = [3.2, 4.1, 5.5, 3.8, 4.5, 3.0, 4.8, 3.5]
)
layer = ScatterplotLayer(
data = earthquakes,
get_position = [:lng, :lat],
get_radius = :magnitude,
get_fill_color = [255, 200, 0, 200],
radius_scale = 20000,
radius_min_pixels = 3,
pickable = true
)
Deck(
layer,
initial_view_state = ViewState(longitude=-119, latitude=36, zoom=5.5),
map_style = "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json"
)