tmap icon indicating copy to clipboard operation
tmap copied to clipboard

Support for Hatched/Patterned Polygons

Open Bevann opened this issue 6 months ago • 10 comments

It would be highly valuable for the tmap package to support hatched (patterned) fills for polygon layers, similar to classic GIS hatching and the functionality available in packages like ggpattern for ggplot2. This feature should also include consistent legend rendering for patterns.

  • Other R mapping packages (notably ggpattern for ggplot2) and GIS software (QGIS, ArcGIS) offer pattern fills, but tmap currently does not.
  • Many users rely on tmap for publication-quality static maps and would benefit from this functionality.
  • Add arguments to tm_polygons() (or similar) to specify fill pattern type (stripe, crosshatch, dot, etc.), angle, spacing/size, foreground and background color.
  • Allow patterns to be mapped to variables, similar to how color or linetype can be mapped.
  • Ensure patterns render correctly in both R graphics devices and exported files (png, pdf, svg).
  • Legend support: The map legend should show pattern swatches, with clear, scalable representation.

Bevann avatar Jun 06 '25 18:06 Bevann

This topic is already open: https://github.com/r-tmap/tmap/issues/49

Rapsodia86 avatar Jun 06 '25 18:06 Rapsodia86

Thx @Bevann yes indeed a feature with high importance but so (far always) low priority. I'll close the outdated #49

In order to make it mode-independent, I think the easiest way is the generate sf pattern sheets, from which we can intersect the polygons.

So:

  1. Find the bounding box of the map
  2. Generate a couple of pattern sheets (e.g.

Image

(One for each category)

  1. Intersect each sheet with the polygons of the corresponding category.

@edzer Do you know what the easiest way is to create those 'pattern sheets' using sf? Do you know of any package (that uses sf ) that does this directly?

mtennekes avatar Jun 11 '25 07:06 mtennekes

@mtennekes have you seen https://coolbutuseless.github.io/2021/07/01/r-v4.1.0-grid-graphics-new-feature-patterns/? Would it not be more straightforward to use the grid package tools to create patterns?

Nowosad avatar Jun 11 '25 09:06 Nowosad

Also, possibly some inspiration could be taken from https://github.com/trevorld/ggpattern

Nowosad avatar Jun 11 '25 09:06 Nowosad

Good suggestions. Pros and cons. If we use grid, then we still need to have some pattern sheets. Big downside is that it won't be available in other modes.

These patterns are not only useful for (ancient) journals that only publish in black and white. It also helps if fill color is not sufficient (e.g. for colour-blind people).

mtennekes avatar Jun 11 '25 09:06 mtennekes

These patterns are not only useful for (ancient) journals that only publish in black and white. It also helps if fill color is not sufficient (e.g. for colour-blind people).

Also, for overlays, such as modelling results with e.g. significance levels...

tim-salabim avatar Jun 11 '25 09:06 tim-salabim

This could also be interesting: https://rpubs.com/dieghernan/559092

jguelat avatar Jun 11 '25 13:06 jguelat

In the past I have done a workaround with hatchedLayer from the cartography package, but there does not seem to be an equivalent in it's predecessor sfmaps. I couldn't find the script but was also abel to hack a legend in by using the base r symbol that closest matched the hatching pattern. That never aligend quite right and took some messing with sizes etc..., it woudl be really snazzy if tmap was able to make a nice looking legend as well.

library(cartography)
library(sf)
library(tmap)



nc <- st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)

nc_sub <- nc[1:3,]

nc_sub_border <- nc_sub %>%
 st_cast("MULTILINESTRING")

nc_hatch <- hatchedLayer(nc_sub,mode="sfc", pattern = "left2right" , density =0.75) %>%
 st_as_sf() %>%
 st_intersection(nc_sub) %>%
   bind_rows(nc_sub_border)




tm_shape(nc)+
 tm_polygons(fill = "NAME")+
 tm_shape(nc_hatch)+
 tm_lines(col = "NAME" , lwd=2)

Bevann avatar Jun 11 '25 18:06 Bevann

Probably the easiest way to get started is a new package (tmap.hatch?) Where tm_polygons is extended with the additional hatch/pattern (?) map variable.

We can use cartography for the time being, but ultimately have our own pattern/haching methods (or use an existing dedicated package for that).

About interactive modes: A downside of using sf pattern lines is that when zooming, the pattern itself will also be zoomed in and out, which may not be desirable (?).

mtennekes avatar Jun 12 '25 08:06 mtennekes

I think a new package could work instead. Having it in interactive mode will be a lot to resolve in addition to boundaries as you zoom in.

aonojeghuo avatar Jul 25 '25 19:07 aonojeghuo