The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
Base R plot(), hexify_heatmap() for
ggplot2, and building custom maps from scratch.
We’ll use European cities throughout:
cities <- data.frame(
name = c("Vienna", "Paris", "Madrid", "Berlin", "Rome",
"Warsaw", "Prague", "Brussels", "Amsterdam", "Lisbon"),
lon = c(16.37, 2.35, -3.70, 13.40, 12.50,
21.01, 14.42, 4.35, 4.90, -9.14),
lat = c(48.21, 48.86, 40.42, 52.52, 41.90,
52.23, 50.08, 50.85, 52.37, 38.72)
)
grid <- hex_grid(area_km2 = 10000)
result <- hexify(cities, lon = "lon", lat = "lat", grid = grid)The plot() method provides quick visualization with
sensible defaults.
plot(result,
grid_fill = "steelblue",
grid_border = "darkblue",
grid_alpha = 0.6,
basemap_fill = "ivory",
basemap_border = "gray50",
main = "Custom Styling")Points can be displayed on top of hexagon cells. By default, points are jittered within their assigned cell to avoid overplotting.
The point_size parameter accepts presets that define
what fraction of a hex cell a single point covers:
| Preset | Coverage |
|---|---|
"tiny" |
~2% of cell |
"small" |
~5% of cell |
"normal" / "auto" |
~10% of cell |
"large" |
~20% of cell |
"very large" |
~35% of cell |
oldpar <- par(mfrow = c(2, 2), cex = 1, cex.main = 1)
plot(result, show_points = TRUE, point_size = "small",
point_color = "red", main = "small (~5%)")
plot(result, show_points = TRUE, point_size = "normal",
point_color = "red", main = "normal (~10%)")
plot(result, show_points = TRUE, point_size = "large",
point_color = "red", main = "large (~20%)")
plot(result, show_points = TRUE, point_size = "very large",
point_color = "red", main = "very large (~35%)")For ggplot2 users, hexify_heatmap() returns a ggplot
object that can be further customized.
Since hexify_heatmap() returns a ggplot object, you can
add layers and modify themes:
hexify_heatmap(result, basemap = "world") +
labs(
title = "Major European Cities",
subtitle = "Assigned to ISEA hexagonal grid cells",
caption = "Data: Sample cities"
) +
theme_minimal(base_size = FIG_BASE_SIZE) +
theme(
plot.title = element_text(face = "bold", size = 14),
panel.grid = element_blank()
)# The map is in longitude/latitude, so the cities go on as plain points
hexify_heatmap(result, basemap = "world", title = "Cities with Labels",
xlim = c(-5, 25), ylim = c(45, 55)) +
geom_point(data = cities, aes(x = lon, y = lat), color = "red", size = 2) +
geom_label(data = cities, aes(x = lon, y = lat, label = name),
nudge_y = 0.8, size = 5)For choropleth-style visualizations with aggregated data, pass a
value column to hexify_heatmap().
# Simulate observation data with counts
set.seed(42)
n_obs <- 100
obs_data <- data.frame(
lon = c(rnorm(60, 10, 8), rnorm(40, 0, 10)),
lat = c(rnorm(60, 48, 5), rnorm(40, 52, 6)),
count = rpois(n_obs, lambda = 50)
)
# Hexify
grid <- hex_grid(area_km2 = 10000)
obs_hex <- hexify(obs_data, lon = "lon", lat = "lat", grid = grid)Available color palettes include any from
scale_fill_viridis_c() or
scale_fill_distiller():
Viridis options: "viridis", "magma",
"plasma", "inferno", "cividis",
"mako", "rocket",
"turbo"
ColorBrewer sequential: "YlOrRd",
"YlGnBu", "Blues", "Greens",
"Reds", "Purples", etc.
p1 <- hexify_heatmap(obs_hex, value = "count", colors = "viridis",
title = "viridis", xlim = c(-20, 35), ylim = c(35, 65))
p2 <- hexify_heatmap(obs_hex, value = "count", colors = "YlGnBu",
title = "YlGnBu", xlim = c(-20, 35), ylim = c(35, 65))
gridExtra::grid.arrange(p1, p2, ncol = 2)hexify_heatmap(
obs_hex,
value = "count",
xlim = c(-20, 35),
ylim = c(35, 65),
title = "Zoomed to Region",
legend_title = "Count"
)# With world basemap (default)
hexify_heatmap(
obs_hex,
value = "count",
basemap = "world",
xlim = c(-20, 35),
ylim = c(35, 65),
title = "With World Basemap"
)# Without basemap
hexify_heatmap(
obs_hex,
value = "count",
basemap = NULL,
xlim = c(-20, 35),
ylim = c(35, 65),
title = "No Basemap"
)plot_world() provides a quick way to draw a world
basemap:
The ISEA grid contains 12 pentagonal cells at the icosahedron vertices. Here’s how to visualize them:
# Pentagon locations (icosahedron vertices in standard ISEA orientation)
pentagon_coords <- data.frame(
type = c("Pole", "Pole", rep("Vertex", 10)),
lon = c(0, 0, seq(0, 324, by = 36)),
lat = c(90, -90, rep(c(26.57, -26.57), 5))
)
# Assign to grid and get polygons
grid <- hex_grid(area_km2 = 500000)
pentagon_cells <- lonlat_to_cell(pentagon_coords$lon, pentagon_coords$lat, grid)
pentagon_polys <- cell_to_sf(pentagon_cells, grid)
ggplot() +
geom_sf(data = hexify_world, fill = "gray95", color = "gray70", linewidth = 0.2) +
geom_sf(data = pentagon_polys, fill = alpha("purple", 0.6),
color = "purple", linewidth = 0.8) +
labs(
title = "Pentagon Cell Locations",
subtitle = "12 pentagonal cells at icosahedron vertices\n(area = 5/6 of hexagons)"
) +
theme_minimal(base_size = FIG_BASE_SIZE) +
theme(axis.text = element_blank(), axis.ticks = element_blank())cell_to_sf(), plot(),
hexify_heatmap() and st_as_sf() draw cells as
hexagons by default. With shape = "gosper", each cell edge
is replaced depth times by three shorter segments turned
the same way, which gives Gosper islands (flowsnakes); each island keeps
its cell’s area, and the islands tile the sphere. With
shape = "descendants", an aperture-7 cell is drawn as the
outline of its descendants depth resolutions down, which
nests across resolutions.
grid <- hex_grid(resolution = 2, aperture = 7)
cells <- grid_rect(c(-15, 30, 40, 65), grid)$cell_id
ortho <- "+proj=ortho +lon_0=12 +lat_0=48"
set.seed(1)
colour <- factor(sample(8, length(cells), replace = TRUE))
shapes <- do.call(rbind, lapply(c("hexagon", "gosper", "descendants"), function(s) {
polys <- cell_to_sf(cells, grid, shape = s, depth = 4)
polys$colour <- colour[match(polys$cell_id, cells)]
polys$shape <- factor(s, levels = c("hexagon", "gosper", "descendants"))
polys
}))
ggplot(sf::st_transform(shapes, ortho)) +
geom_sf(aes(fill = colour), color = "gray25", linewidth = 0.15,
show.legend = FALSE) +
facet_wrap(~shape) +
scale_fill_brewer(palette = "Set3") +
theme_void(base_size = FIG_BASE_SIZE)Visualizing uniformly sampled cells across Earth:
# Grid parameters (coarse for faster build)
grid <- hex_grid(area_km2 = 200000, aperture = 3)
max_cell <- n_cells(grid)
# Sample random cell IDs
set.seed(123)
N <- 50
random_cells <- sample(1:max_cell, N, replace = FALSE)
# Generate polygons for sampled cells
sample_polys <- cell_to_sf(random_cells, grid)
ggplot() +
geom_sf(data = hexify_world, fill = "gray95", color = "gray70", linewidth = 0.2) +
geom_sf(data = sample_polys, fill = alpha("forestgreen", 0.5),
color = "darkgreen", linewidth = 0.4) +
labs(title = sprintf("Random Sample of %d Cells", N),
subtitle = sprintf("~%.0f km2 each", summary(grid)$area_km2)) +
theme_minimal(base_size = FIG_BASE_SIZE) +
theme(axis.text = element_blank(), axis.ticks = element_blank())For full control, generate polygons directly and use ggplot2:
# Create data with a numeric variable
set.seed(456)
stations <- data.frame(
lon = runif(50, -10, 30),
lat = runif(50, 35, 60),
temperature = rnorm(50, mean = 15, sd = 5)
)
# Hexify (coarser grid for faster build)
grid <- hex_grid(area_km2 = 20000)
stations_hex <- hexify(stations, lon = "lon", lat = "lat", grid = grid)
# Aggregate temperature by cell
stations_df <- as.data.frame(stations_hex)
cell_temps <- aggregate(temperature ~ cell_id, data = stations_df, FUN = mean)
# Generate polygons and merge data
cell_polys <- cell_to_sf(cell_temps$cell_id, grid)
cell_polys <- merge(cell_polys, cell_temps, by = "cell_id")
# Custom visualization
europe <- hexify_world[hexify_world$continent == "Europe", ]
ggplot() +
geom_sf(data = europe, fill = "gray95", color = "gray60", linewidth = 0.2) +
geom_sf(data = cell_polys, aes(fill = temperature),
color = "white", linewidth = 0.2) +
scale_fill_gradient2(
low = "blue", mid = "white", high = "red",
midpoint = 15, name = "Temp (°C)"
) +
coord_sf(xlim = c(-10, 30), ylim = c(35, 60)) +
labs(
title = "Mean Temperature by Grid Cell",
subtitle = "Diverging color scale centered at 15°C"
) +
theme_minimal(base_size = FIG_BASE_SIZE) +
theme(
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_line(color = "gray90")
)| Function | Description |
|---|---|
plot() |
Base R plot method for HexData objects |
hexify_heatmap() |
ggplot2 visualization, returns modifiable ggplot object |
plot_world() |
Quick world basemap |
cell_to_sf() |
Generate sf polygons from cell IDs |
vignette("quickstart") - Getting started with
hexify
vignette("workflows") - Complete analysis
workflows
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.