Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wanted: repeated-pictogram visualization of population split

I am looking for a way to do a (actually quite common) visualization, whereby the split of a population of, say, N units into several categories is shown via a set of N pictograms - I'd prefer filled squares; in a newspaper, etc., one might see little humanoid shapes - with each pictogram colored according to the category of n'th unit. N fixed to 1 or 100, and the chart displaying fractions or percentages rather than counts, would be OK. The colored "stripes" would have to wrap to multiple lines. Is anyone aware of this chart available in an R package?

To take a specific example,

x = sample(c("A","B"),100,replace = T)

I would like to see a 10x10 (or 5x20, or whatever) grid of colored squares, some - corresponding to "A" - colored green, others red. The green (and likewise red) squares could be "bunched", or left in the original order.

Thank you.

like image 571
Dimitri Shvorob Avatar asked Dec 10 '14 13:12

Dimitri Shvorob


1 Answers

Below we show 3 versions. The first uses squares, the next uses circles, the next uses an icon of a man and finally we use smiley faces.

Squares

# input data
set.seed(123)
x <- sample(c("A","B"),100,replace = T)

# input parameters - nr * nc should equal length(x)
cols <- c("green", "red")
nr <- 10
nc <- 10

# create data.frame of positions and colors
m <- matrix(cols[factor(x)], nr, nc)
DF <- data.frame(row = c(row(m)), col = c(col(m)[, nc:1]), value = c(m), 
      stringsAsFactors = FALSE)

# plot squares - modify cex to get different sized squares
plot(col ~ row, DF, col = DF$value, pch = 15, cex = 4, asp = 1,
     xlim = c(0, nr), ylim = c(0, nc),
     axes = FALSE, xlab = "", ylab = "")

enter image description here

Circles

# plot circles
plot(col ~ row, DF, col = DF$value, pch = 20, cex = 6, asp = 1,
     xlim = c(0, nr), ylim = c(0, nc),
     axes = FALSE, xlab = "", ylab = "")

enter image description here

png Icons This solution uses a black/white icon of a man which we have assumed has been saved in the current directory as man.png. We color it red and green and use those two versions in place of the squares or circles:

# blank graph to insert man icons into
plot(col ~ row, DF, col = DF$value, asp = 1,
     xlim = c(0, nr), ylim = c(0, nc),
     axes = FALSE, xlab = "", ylab = "", type = "n")

library(png)
man <- readPNG("man.png")

red.man <- man
red.man[,,1] <- man[,,4] # fill in red dimension
R <- subset(DF, value == "red")
with(R, rasterImage(red.man, 
     row-.5, col-.5, row+.5, col+.5, 
     xlim = c(0, nr), ylim = c(0, nc),
     xlab = "", ylab = ""))

green.man <- man
green.man[,,2] <- man[,,4] # fill in green dimension
G <- subset(DF, value == "green")
with(G, rasterImage(green.man, 
     row-.5, col-.5, row+.5, col+.5, 
     xlim = c(0, nr), ylim = c(0, nc),
     xlab = "", ylab = ""))

enter image description here

Smiley Face Icons This solution uses a green smiley face icon and a red frowning face icon which we have assumed have been saved in the current directory as smiley_green.jpg and smiley_red.jpg.

# blank graph to insert man icons into
xp <- 1.25
plot(col ~ row, DF, col = DF$value, asp = 1,
     xlim = c(0, xp * nr), ylim = c(0, xp * nc),
     axes = FALSE, xlab = "", ylab = "", type = "n")

library(jpeg)
smiley_green <- readJPEG("smiley_green.jpg")
smiley_red <- readJPEG("smiley_red.jpg")    

R <- subset(transform(DF, row = xp * row, col = xp * col), value == "red")
with(R, rasterImage(smiley_red,
     row - .5, col - .5, row + .5, col + .5, 
     xlim = c(0, xp * nr), ylim = c(0, xp * nc),
     xlab = "", ylab = ""))

G <- subset(transform(DF, row = xp * row, col = xp * col), value == "green")
with(G, rasterImage(smiley_green,
     row - .5, col - .5, row + .5, col + .5, 
     xlim = c(0, xp * nr), ylim = c(0, xp * nc),
     xlab = "", ylab = ""))

enter image description here

Revised To 10x10 green/red and added version using man icon.

like image 168
G. Grothendieck Avatar answered Nov 27 '22 00:11

G. Grothendieck