People are willing to read colors. I will show you how to repesent characters in heatmap. ComplexHeatmap can directly translate a dataframe (character matrix) into heatmap. It is good to learn basics of grid package which ComplexHeatmap and ggplot2 build on.

grid.rect is the function used to draw rectangles.

library(ComplexHeatmap)
colors<- structure(circlize::rand_color(4), names = c("a", "b", "c", "d"))
set.seed(123)
mat_letters<- matrix(sample(letters[1:4], 100, replace = TRUE), 10, 10)
## default
Heatmap(mat_letters, col = colors)

I want to have some gap between the cells:

cell_fun<-  function(j, i, x, y, width, height, fill) {
    grid.rect(x = x *0.6, y = y, width = width * 0.6, height = height, 
        gp = gpar(col = "grey", fill = fill))
}
Heatmap(mat_letters, rect_gp = gpar(type = "none"), cell_fun = cell_fun, col = colors)

It make look different in an interactive graphical device. save the figure in a pdf and you will see the effect.

## always square and have gaps between cells
cell_fun2<- function(j, i, x, y, width, height, fill) {
    s = min(unit.c(convertWidth(width, "cm"), convertHeight(height, "cm")))
    grid.rect(x = x*0.8, y = y*0.8, width = s * 0.8, height = s*0.8, 
        gp = gpar(col = "grey", fill = fill))
}
Heatmap(mat_letters, rect_gp = gpar(type = "none"), cell_fun = cell_fun2, col = colors)

cell_fun3<-  function(j, i, x, y, width, height, fill) {
    grid.rect(x = x*0.8, y = y, width = width * 0.8, height = height, 
        gp = gpar(col = "grey", fill = fill))
}
Heatmap(mat_letters, rect_gp = gpar(type = "none"), cell_fun = cell_fun3, col = colors)

make thiner

cell_fun4<- function(j, i, x, y, width, height, fill) {
        s = min(unit.c(convertWidth(width, "cm"), convertHeight(height, "cm")))
    grid.rect(x = x*0.6 , y = y, width = s* 0.6, height = height, 
        gp = gpar(col = "grey", fill = fill))
}
Heatmap(mat_letters, rect_gp = gpar(type = "none"), cell_fun = cell_fun4, col = colors, show_heatmap_legend = FALSE)

LS0tCnRpdGxlOiAiY2hhcmFjdGVyIG1hdHJpeCB0byBoZWF0bWFwIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpQZW9wbGUgYXJlIHdpbGxpbmcgdG8gcmVhZCBjb2xvcnMuIEkgd2lsbCBzaG93IHlvdSBob3cgdG8gcmVwZXNlbnQgY2hhcmFjdGVycyBpbiBoZWF0bWFwLgpgQ29tcGxleEhlYXRtYXBgIGNhbiBkaXJlY3RseSB0cmFuc2xhdGUgYSBkYXRhZnJhbWUgKGNoYXJhY3RlciBtYXRyaXgpIGludG8gaGVhdG1hcC4KSXQgaXMgZ29vZCB0byBsZWFybiBiYXNpY3Mgb2YgYGdyaWRgIHBhY2thZ2Ugd2hpY2ggYENvbXBsZXhIZWF0bWFwYCBhbmQgYGdncGxvdDJgIGJ1aWxkIG9uLgoKYGdyaWQucmVjdGAgaXMgdGhlIGZ1bmN0aW9uIHVzZWQgdG8gZHJhdyByZWN0YW5nbGVzLgoKYGBge3J9CmxpYnJhcnkoQ29tcGxleEhlYXRtYXApCmNvbG9yczwtIHN0cnVjdHVyZShjaXJjbGl6ZTo6cmFuZF9jb2xvcig0KSwgbmFtZXMgPSBjKCJhIiwgImIiLCAiYyIsICJkIikpCnNldC5zZWVkKDEyMykKbWF0X2xldHRlcnM8LSBtYXRyaXgoc2FtcGxlKGxldHRlcnNbMTo0XSwgMTAwLCByZXBsYWNlID0gVFJVRSksIDEwLCAxMCkKCiMjIGRlZmF1bHQKSGVhdG1hcChtYXRfbGV0dGVycywgY29sID0gY29sb3JzKQpgYGAKCkkgd2FudCB0byBoYXZlIHNvbWUgZ2FwIGJldHdlZW4gdGhlIGNlbGxzOgoKYGBge3J9CmNlbGxfZnVuPC0gIGZ1bmN0aW9uKGosIGksIHgsIHksIHdpZHRoLCBoZWlnaHQsIGZpbGwpIHsKICAgIGdyaWQucmVjdCh4ID0geCAqMC42LCB5ID0geSwgd2lkdGggPSB3aWR0aCAqIDAuNiwgaGVpZ2h0ID0gaGVpZ2h0LCAKICAgICAgICBncCA9IGdwYXIoY29sID0gImdyZXkiLCBmaWxsID0gZmlsbCkpCn0KCkhlYXRtYXAobWF0X2xldHRlcnMsIHJlY3RfZ3AgPSBncGFyKHR5cGUgPSAibm9uZSIpLCBjZWxsX2Z1biA9IGNlbGxfZnVuLCBjb2wgPSBjb2xvcnMpCmBgYAoKSXQgbWFrZSBsb29rIGRpZmZlcmVudCBpbiBhbiBpbnRlcmFjdGl2ZSBncmFwaGljYWwgZGV2aWNlLiBzYXZlIHRoZSBmaWd1cmUgaW4gYSBwZGYgYW5kIHlvdSB3aWxsIHNlZSB0aGUgZWZmZWN0LgoKYGBge3J9CiMjIGFsd2F5cyBzcXVhcmUgYW5kIGhhdmUgZ2FwcyBiZXR3ZWVuIGNlbGxzCmNlbGxfZnVuMjwtIGZ1bmN0aW9uKGosIGksIHgsIHksIHdpZHRoLCBoZWlnaHQsIGZpbGwpIHsKICAgIHMgPSBtaW4odW5pdC5jKGNvbnZlcnRXaWR0aCh3aWR0aCwgImNtIiksIGNvbnZlcnRIZWlnaHQoaGVpZ2h0LCAiY20iKSkpCiAgICBncmlkLnJlY3QoeCA9IHgqMC44LCB5ID0geSowLjgsIHdpZHRoID0gcyAqIDAuOCwgaGVpZ2h0ID0gcyowLjgsIAogICAgICAgIGdwID0gZ3Bhcihjb2wgPSAiZ3JleSIsIGZpbGwgPSBmaWxsKSkKfQpIZWF0bWFwKG1hdF9sZXR0ZXJzLCByZWN0X2dwID0gZ3Bhcih0eXBlID0gIm5vbmUiKSwgY2VsbF9mdW4gPSBjZWxsX2Z1bjIsIGNvbCA9IGNvbG9ycykKYGBgCgoKYGBge3J9CmNlbGxfZnVuMzwtICBmdW5jdGlvbihqLCBpLCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCBmaWxsKSB7CiAgICBncmlkLnJlY3QoeCA9IHgqMC44LCB5ID0geSwgd2lkdGggPSB3aWR0aCAqIDAuOCwgaGVpZ2h0ID0gaGVpZ2h0LCAKICAgICAgICBncCA9IGdwYXIoY29sID0gImdyZXkiLCBmaWxsID0gZmlsbCkpCn0KCkhlYXRtYXAobWF0X2xldHRlcnMsIHJlY3RfZ3AgPSBncGFyKHR5cGUgPSAibm9uZSIpLCBjZWxsX2Z1biA9IGNlbGxfZnVuMywgY29sID0gY29sb3JzKQpgYGAKCiMjIG1ha2UgdGhpbmVyIApgYGB7cn0KCmNlbGxfZnVuNDwtIGZ1bmN0aW9uKGosIGksIHgsIHksIHdpZHRoLCBoZWlnaHQsIGZpbGwpIHsKICAgICAgICBzID0gbWluKHVuaXQuYyhjb252ZXJ0V2lkdGgod2lkdGgsICJjbSIpLCBjb252ZXJ0SGVpZ2h0KGhlaWdodCwgImNtIikpKQogICAgZ3JpZC5yZWN0KHggPSB4KjAuNiAsIHkgPSB5LCB3aWR0aCA9IHMqIDAuNiwgaGVpZ2h0ID0gaGVpZ2h0LCAKICAgICAgICBncCA9IGdwYXIoY29sID0gImdyZXkiLCBmaWxsID0gZmlsbCkpCn0KCgpIZWF0bWFwKG1hdF9sZXR0ZXJzLCByZWN0X2dwID0gZ3Bhcih0eXBlID0gIm5vbmUiKSwgY2VsbF9mdW4gPSBjZWxsX2Z1bjQsIGNvbCA9IGNvbG9ycywgc2hvd19oZWF0bWFwX2xlZ2VuZCA9IEZBTFNFKQoKYGBg