@mtennekes do you plan to implement possibility to create bivariate maps (e.g. http://axismaps.github.io/thematic-cartography/articles/bivariate_choropleth.html)? Or maybe could be done already?
Coincidentally @eugenividal and I discussed this last week. It can be done and I think the example below with 2 or 3 layers could be useful in some cases, it's just the legend that's tricky to create it seems:
``` r
library(tmap)
data("World")
names(World)
m1 = tm_shape(World) + tm_fill("pop_est", alpha = 0.3, "Purples")
m2 = tm_shape(World) + tm_fill("HPI", alpha = 0.3, palette = "Blues")
m3 = tm_shape(World) + tm_fill("life_exp", alpha = 0.3, palette = "Oranges")
m1 + m2 + m3
```

Wow, be careful there! The order of semi-transparent layers will influence the outcome colors. See for instance m2 + m1 + m3.
It would definitely be nice to support bivariate maps. Any ideas how to implement them?
Indeed - just a starter for 10. The legend in that pals package vignette looks awesome, thanks for sharing.
more on how to create https://cran.r-project.org/web/packages/pals/vignettes/pals_examples.html at the very bottom
For context / interest - this is I think a 'trivariate' colourscheme generator: https://github.com/jschoeley/tricolore
@mtennekes this could be useful - https://github.com/Robinlovelace/geocompr/issues/376
Another (working, but not perfectly integrated with tmap) solution to create bivariate maps can be seen below.
It was inspired by the work of @sdesabbata (see https://github.com/sdesabbata/BivariateTMap).
@mtennekes can we think of integrating it into tmap somehow?
library(tmap)
library(sf)
library(stars)
library(spData)
library(classInt)
library(lattice)
library(grid)
library(pals)
legend_creator = function(col.regions, xlab, ylab, nbins){
bilegend = levelplot(matrix(1:(nbins * nbins), nrow = nbins),
axes = FALSE, col.regions = col.regions,
xlab = xlab, ylab = ylab,
cuts = 8, colorkey = FALSE, scales = list(draw = 0))
bilegend
}
add_new_var = function(x, var1, var2, nbins, style = "quantile"){
class1 = suppressWarnings(findCols(classIntervals(c(x[[var1]]),
n = nbins,
style = style)))
class2 = suppressWarnings(findCols(classIntervals(c(x[[var2]]),
n = nbins,
style = style)))
x$new_class = class1 + nbins * (class2 - 1)
return(x)
}
# vector example ----------------------------------------------------------
africa = subset(world, continent == "Africa")
africa = add_new_var(africa,
var1 = "lifeExp",
var2 = "gdpPercap",
nbins = 3)
bilegend = legend_creator(stevens.pinkblue(n = 9),
xlab = "lifeExp",
ylab = "gdpPercap",
nbins = 3)
bimap = tm_shape(africa) +
tm_polygons("new_class", style = "cat", palette = stevens.pinkblue(n = 9)) +
tm_layout(legend.show = FALSE)
grid.newpage()
print(bimap)
vp = viewport(x = 0.25, y = 0.25, width = 0.25, height = 0.25)
pushViewport(vp)
print(bilegend, newpage = FALSE)

# raster example ----------------------------------------------------------
data("land")
land = add_new_var(land,
var1 = "trees",
var2 = "elevation",
nbins = 3,
style = "equal")
bilegend = legend_creator(stevens.pinkblue(n = 9),
xlab = "trees",
ylab = "elevation",
nbins = 3)
bimap = tm_shape(land) +
tm_raster("new_class", style = "cat", palette = stevens.pinkblue(n = 9)) +
tm_layout(legend.show = FALSE)
grid.newpage()
print(bimap)
vp = viewport(x = 0.15, y = 0.45, width = 0.25, height = 0.25)
pushViewport(vp)
print(bilegend, newpage = FALSE)

Created on 2020-08-07 by the reprex package (v0.3.0)
Hi all, just thought would flag this convo , it's not tmap but same principle should apply...
Thanks for you inputs, @Nowosad and @aspina7.
Although the implementation is not hard, there are a few difficult obstacles that need to be taken:
User input How does a user specify a bivariate aesthetic? This is not straightforward; tm_polygons(c("varA", "varB")) interferes with drawing two small multiples, one for varA and one for varB. Since we use standard evaluation, we could introduce a new operator, e.g. tm_polygons("varA _x_ varB"). Any ideas?
Color palettes I'm not sure which bivariate color palettes to use. My initial approach would probably be to use the HCL color space. However, it would also be good to have a palette with yellow as neutral mid-color, since it is better distinguishable from gray that is often used for missing values. Update: I just discovered your package colorblindcheck and vignette about bivatiate palettes (https://nowosad.github.io/colorblindcheck/articles/articles/check_bivariate_pals.html) Awesome work @Nowosad! Also didn't know that there are already a lot of bivariate palettes in pals. Which ones would you prefer in tmap?
Legend This is not a question of how to implement it, but this would take time. On the other hand, there is no distinction between portrait and landscape for this legend type.
is_bivariate, FALSE by default). When this argument is FALSE then tm_polygons(c("varA", "varB")) creates two small multiples, and when this argument is TRUE then we have one bivariate map. "fisher", "quantile", "equal", etc.). It includes "fixed" style as well.is_bivariate is TRUE, then only a subset of color palettes (see below) is possible.it is possible to save it via tmap_save()
it is possible to save it via tmap_save()
Not yet.
Most helpful comment
Another (working, but not perfectly integrated with tmap) solution to create bivariate maps can be seen below.
It was inspired by the work of @sdesabbata (see https://github.com/sdesabbata/BivariateTMap).
@mtennekes can we think of integrating it into tmap somehow?
Created on 2020-08-07 by the reprex package (v0.3.0)