2

I am working on stacked bar plot but i need to assign image here hand on particular stack.

enter image description here

enter image description here

How can i do this in R.

DF = data.frame(names = c("tomato", "potato", "cabbage", 
                          "sukuma-wiki", "terere"),
                freq=c(7,4,5,8,20))
barplot(as.matrix(DF[,2]), col=heat.colors(length(DF[,2])), 
        legend=DF[,1], xlim=c(0,9), width=2)

enter image description here

A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
Manish
  • 3,341
  • 15
  • 52
  • 87
  • 2
    I would approach this with ggplot2 though base is likely doable too. Here's a updates manual: [(LINK)](http://cloud.github.com/downloads/hadley/ggplot2/guide-col.pdf). See pages 22-23 – Tyler Rinker Jul 11 '12 at 05:03
  • But in this, position of image need to set manually. I need to generate 100,000 plots dynamically with different hand position in input file for each plot. How can i do it? – Manish Jul 11 '12 at 07:17

1 Answers1

1

Here is a way, how you could do it with grid.

# libraries
library(jpeg)
library(grid)

# a is your image
a <- readJPG("foo.jpg")

# ypos.img is at which height of the barchart you want to place the image
ypos.img <- 10

# Create a new polot
grid.newpage()
pushViewport(viewport(width=0.9, height=0.9))

# add image
pushViewport(viewport(yscale=c(0,sum(DF[,2])), xscale=c(0,1), x=0, y=0, width=0.4, height=1, just=c("left", "bottom")))
grid.raster(a, y=unit(ypos.img, "native"))

# add barplot
popViewport()
pushViewport(viewport(x=0.4, y=0, width=0.6, height=1, just=c("left", "bottom")))
pushViewport(dataViewport(xscale=c(0,2), yscale=c(0, sum(DF[,2]))))
cols <- heat.colors(length(DF[,2]))

for (i in 1:nrow(DF)) {
 start <- 0 
 if (i > 1) start <- sum(DF[1:(i-1), 2])
 grid.rect(x=0, y=start, width=1, height=DF[i, 2], default.units="native", just=c("left", "bottom"), gp=gpar(fill=cols[i]))
}

popViewport(2)

# Legend
pushViewport(viewport(x=0.75, y=0, width=0.25, height=1, just=c("left", "bottom")))
ypos <- 0.8
for (i in 1:nrow(DF)) {
 grid.rect(x=0.05, y=ypos, width=0.1, height=0.05, just=c("left", "bottom"), gp=gpar(fill=cols[i]))
 grid.text(DF[i,1], x=0.2, y=ypos, just=c("left", "bottom"))
 ypos <- ypos - 0.05
}

popViewport()
johannes
  • 14,043
  • 5
  • 40
  • 51
  • Thanks it works fine for me. Is there any way to represent intensity to color based on their values. I mean heat color intensity should be in according(light or dark) to numeric value. – Manish Jul 12 '12 at 03:32
  • Have a look at `?gpar`, you can then adjust the `alpha` value. If it worked for you, please also consider to mark the question as answered. – johannes Jul 12 '12 at 06:58