I have a histogram in my legend that displays the distribution of my data. I would like to edit the labels of the axis to improve readability. Ideally, this would be changed to reflect the categories, so the values of 500 and 1500 can be removed.
library(tmap)
custom_colors <- c("#ffd500",'orange', "#e60000")
tm_map <- tm_shape(merged) +
tm_borders(lwd=NA) +
tm_polygons("aantal_observaties",
id = "pc4",
breaks= c(1,1001, 2001, 3000),
n=3,
palette = custom_colors,
style = "fixed",
title = "Observations",
alpha = 1,
na.color="purple",
colorNA='#ebebeb',
legend.hist=TRUE,
legend.show=FALSE) +
tm_layout(legend.outside=TRUE,legend.outside.position = "right",
frame=FALSE,
title = 'Observations',
title.size = 1)
tm_map + tm_add_legend(labels=c("1 to 1000", "1001 to 2000", "2001 to 3000", "0"),
col = c("#ffd500",'orange', "#e60000", "#ebebeb"),
border.lwd = NA,
)
Did some toying around with this and it seems like legend.hist
may not be supported in tmap
v4. Installing tmap
and loading the library gave me the message:
> library(tmap)
Breaking News: tmap 3.x is retiring. Please test v4, e.g. with
remotes::install_github('r-tmap/tmap')
Anyway, after installing that version, I was unable to get a legend.hist
. On this other SO post on customizing the histogram axes in tmap Martijn Tennekes says
Unfortunately, this is not possible (yet). tmap is currently in a big renovation (to v4): we will still have to decide how to proceed with histograms and other legend charts.
That being the case, you can get something similar using ggplot2
and patchwork
, though specifying the layout is a little clunky.
Since you didn't post data, I created some that I think is similar enough:
library(dplyr)
library(sf)
# outline
outline <- system.file("gpkg/nc.gpkg", package = "sf") |>
sf::st_read() |>
sf::st_geometry() |>
sf::st_union() |>
sf::st_as_sf()
# create polygons
polys <- outline |>
sf::st_sample(500) |>
sf::st_buffer(units::as_units(2, "mi")) |>
sf::st_as_sf()
# generate data
obs <- rnorm(10000, mean = 0, sd = 900) |>
round() |>
abs() |>
sample(size = nrow(polys))
# add observations for polys
polys <- polys |>
dplyr::mutate(obs = obs)
# add factor for category
polys <- polys |>
dplyr::mutate(group = dplyr::case_when(
dplyr::between(obs, 0, 1000) ~ "0 to 1000",
dplyr::between(obs, 1001, 2000) ~ "1001 to 2000",
obs > 2000 ~ "2001+"
)) |>
dplyr::mutate(group = as.factor(group))
And for the plot:
library(ggplot2)
library(patchwork)
map <- ggplot() +
geom_sf(data = outline) +
geom_sf(data = polys, aes(fill = group), show.legend = FALSE) +
scale_fill_manual(values = c("#ffd500", "orange", "#e60000")) +
theme_void()
hist <- ggplot(data = polys, aes(x = obs, fill = group)) +
geom_histogram(binwidth = 25) +
scale_fill_manual(
values = c("#ffd500", "orange", "#e60000")
) +
theme_minimal() +
theme(
legend.position = "bottom",
legend.title = element_blank(),
plot.title = element_text(face = "bold"),
legend.direction = "vertical",
axis.title.x = element_blank(),
axis.title.y = element_blank()
) +
ggtitle("Observations")
design <- "AAAA#\nAAAAB\nAAAA#"
wrap_plots(
map, hist,
design = design
)
Since you create the histogram separately, you have full control over it. Know this isn't ideal since it's not in tmap
but thought it might be close to what you're after.
More on using patchwork
(or gridExtra
/ cowplot
) here