Beyond traditional cartographic representation functions, geoviz also offers more advanced cartographic transformations.
First, let’s load packages and data.
library(geoviz)
library(sf)
world <- st_read(
system.file("gpkg/world.gpkg", package = "geoviz"),
quiet = TRUE
)
afr <- world[world$region == "Africa",]
cities <- st_read(
system.file("gpkg/cities.gpkg", package = "geoviz"),
quiet = TRUE
)Grids
With the viz_gridchoro function, it is possible to
aggregate points into regular grids. Several grid types are available
and can be selected using the grid parameter. First, there are regular
grids in the plane: "square", "diamond",
"hexbin", "triangle", and
"random". It is also possible to use regular grids on the
globe: "h3" and "square_sph".
If the var parameter is specified with an
absolute quantitative variable, the function sums the
values and assigns them to the grid cells. If var is not
specified, the function simply counts the number of points.
Then, to create the choropleth map, you can use exactly the same
parameters as in the viz_choro function.
Here is an example of a regular grid on the plane of the map.
viz_create(projection = "EqualEarth", zoomable = T) |>
viz_path(datum = world, fill = "#CCC") |>
viz_gridchoro(data = cities, var = "population", grid = "square") |>
viz_path(data = cities, fill = "black", r = 2) |>
viz_render()And here is an example of a regular grid on the globe.
viz_create(projection = "Orthographic.rotate([30,-30])",
zoomable = "versor") |>
viz_outline() |>
viz_path(datum = world, fill = "white", fillOpacity = 0.3) |>
viz_gridchoro(data = cities, var = "population", grid = "h3",
level = 1, colors = "Reds") |>
viz_path(data = cities, fill = "black", r = 2) |>
viz_render()If the data are not points but polygons, the values are distributed proportionally to the intersected area. As a result, the computation is much slower.
viz_create(projection = "Mercator", zoomable = T,
domain = afr, margin = 100) |>
viz_gridchoro(data = afr, var = "pop", step = 50,
grid = "hexbin", colors = "Oranges",
stroke = "none") |>
viz_path(datum = afr, fill = "none", stroke = "white") |>
viz_render()In the previous maps, a stock variable is represented using a color gradient. This is not a major issue since all grid cells have the same size. However, if you want to map a ratio—for example, GDP per capita—you need to specify the numerator and the denominator as follows.
viz_create(projection = "Mercator", zoomable = T,
domain = afr, margin = 100) |>
viz_gridchoro(data = afr, var = c("gdp", "pop"), step = 50,
grid = "hexbin", colors = "Blues",
stroke = "none") |>
viz_path(data = afr, fill = "none", stroke = "white") |>
viz_render()Heatmaps
Thanks to d3.contourDensity,
it is also possible to create smoothed maps in geoviz with the
viz_smooth function. d3.contourDensity() is a
function from the d3-contour module that computes density
contours (isodensity lines) from a set of points. It is the equivalent
of a 2D kernel density estimation (KDE). It returns polygons
representing areas of equal density.
By varying the bandwidth, thresholds, and
cellSize parameters, you can change the level of
generalization of the map. With the parameter colors, you
can use a palette available in dicopal.
CHN_cities <- cities[cities$iso3 == "CHN", ]
viz_create(domain = CHN_cities, margin = 50) |>
viz_tile(url = "worldimagery") |>
viz_smooth(data = CHN_cities, var = "population") |>
viz_render()Bertin dots
With the viz_gridprop function, and following exactly
the same principles as the viz_gridchoro function, it is
possible to aggregate data into regular grid cells and then represent
them using proportional symbols. This produces a cartographic
representation similar to Bertin-style dot maps.
viz_create(projection = "Mercator", zoomable = T) |>
viz_path(data = afr, fill = "#CCC", fillOpacity = 0.3) |>
viz_gridprop(data = afr, var = "pop", k = 30, step = 40,
grid = "square", fill = "#38896F", leg_values_round = 0) |>
viz_render()Dot density map
The viz_dotdensity function allows you to create dot maps in the style of Armand Joseph Frère de Montizon (1830).
The value of the point is calculated automatically and displayed at
the bottom left of the map. However, you can choose a value yourself
using the dotval parameter.
viz_create(projection = "EqualEarth", zoomable = T) |>
viz_outline() |>
viz_graticule(step = 30, stroke = "white") |>
viz_path(datum = world, fill = "white", fillOpacity = 0.3) |>
viz_dotdensity(data = world, var = "pop", fill = "#38896F") |>
viz_render()Obviously, this map is not very accurate since the points are randomly distributed within large countries. For a more accurate map, more precise data is needed.