r-tmap / tmap

R package for thematic maps
https://r-tmap.github.io/tmap
GNU General Public License v3.0
868 stars 121 forks source link

Different colours in the legend and raster in RGB and CMYK #899

Open andliszmmu opened 4 months ago

andliszmmu commented 4 months ago

I am working on an Atlas with a number of raster maps. I want complete correspondence between the colours in the legend and on the map, naturally. I need CMYK pdf for print. When I produce a pdf, colours in the legend and the map are very different. The problem is absent if I save the map in RGB. Shorten code: model.pal <- c("#4DAF4A","#BCE395","#FFFF33","#FD9243","#DF171C") ... model <- raster(paste0("./tif/",species.name,".tif")) ... tm <- ... tm_shape(model)+ tm_raster(style='fixed', breaks = c(0.445,0.521,0.635,0.729,0.85,1.2), palette=model.pal, alpha = 1, n=5, stretch.palette = FALSE, title = species.name, legend.show = TRUE, legend.reverse = TRUE, legend.z=0)+ ... tmapsave(tm, filename = (paste0(dsn,file.name,'', file.suff,'.pdf')), device = pdf(), colormodel="cmyk", width = 205, height = 260, units='mm')

I guess that it is not a problem of pdf device, since both legend and the map come there from tmap.

marine-ecologist commented 4 months ago

Can confirm with reproducible example below (colormodel="cmyk" results in legend values being darker than the raster), but... is this not because the RGB hues are beyond the CMYK range?

pal8 <- c("#33A02C", "#B2DF8A", "#FDBF6F", "#1F78B4", "#999999", "#E31A1C", "#E6E6E6", "#A6CEE3")
example_map <- tm_shape(land, ylim = c(-88,88)) +
  tm_raster("cover_cls", 
            values = pal8, 
            col.legend = tm_legend("Global Land Cover")) +
  tm_layout(legend.only=TRUE)

tmap_save(example_map, filename = "example_map_cmyk.pdf", device = pdf(), colormodel="cmyk", width = 205, height = 260, units='mm')

tmap_save(example_map, filename = "example_map_rgb.pdf", device = pdf(), colormodel="rgb", width = 205, height = 260, units='mm')

Screenshot 2024-07-11 at 12 45 41 PM

andliszmmu commented 4 months ago

Thank you, marine-ecologist!

but... is this not because the RGB hues are beyond the CMYK range?

Generally, no. RGB and CMYK looks absolutely different because one is adopted for eye/display and the second for print. However the range of colours are the same. Nevertheless, I checked coincidence of the legend and map in wide spectrum of colours, as well as in different functions. The problem with tm_raster repeats with any colours, including "red", "green" etc. Besides the problem appears with tm_raster() only. For example, tm_fill() works properly.

mtennekes commented 3 months ago

Also confirm. This answer may be useful here: https://stackoverflow.com/a/68920794

The strange thing is that the raster image is not affected. Perhaps this cannot be easily converted to CMYK so it remains in RGB (?). Polygons, lines, dots, etc also get other colors:

pal8 <- c("#33A02C", "#B2DF8A", "#FDBF6F", "#1F78B4", "#999999", "#E31A1C", "#E6E6E6", "#A6CEE3")
example_map <- tm_shape(land, ylim = c(-88,88)) +
    tm_raster("cover_cls", 
              col.scale = tm_scale_categorical(values = pal8), 
              col.legend = tm_legend("Global Land Cover"))

tmap_save(example_map, filename = "example_map_cmyk.pdf", colormodel="cmyk", width = 205, height = 260, units='mm')

tmap_save(example_map, filename = "example_map_rgb.pdf", colormodel="rgb", width = 205, height = 260, units='mm')

example_map2 <- tm_shape(World) +
    tm_polygons("HPI",
                fill.scale = tm_scale_intervals(n = 8, values = pal8))

tmap_save(example_map2, filename = "example_map2_cmyk.pdf", colormodel="cmyk", width = 205, height = 260, units='mm')

tmap_save(example_map2, filename = "example_map2_rgb.pdf", colormodel="rgb", width = 205, height = 260, units='mm')

@marine-ecologist note the difference with our code: tm_scale is needed to pass on col8. The second difference is that device = pdf() is not needed. Somehow, with device = pdf(), the device is not closed correctly (maybe a bug in tmap_save) or at least something to be improved....