Hi all (really probably just Deepayan): In the plot below I want to add text on either side of each violin plot that indicates the number of observations that are either positive or negative. I'm trying to do this with ltext() and I've also monkeyed about with panel.text(). The code below is generally what I want but my calls to ltext() are wrong and I'm not sure how to fix them. Right now they replicate the first column of the matrices obs.pos and obs.neg for each panel. How do I tell ltext to advance to the next column when the next panel is plotted? I don't see how subscripts can do it, but I bet it's something along that line... Thanks, Andy rm(list = ls()) set.seed(354) # make a bimodal dataset with three groups and three treatments foo <- c(rnorm(150,-1,0.5), rnorm(150,1,0.25)) treatment <- factor(rep(seq(1,3),100), labels = c("Treatment 1", "Treatment 2", "Treatment 3")) group <- factor(rep(seq(1,3),100), labels = c("Group A", "Group B", "Group C")) group <- sample(group) # corrupt Group A, Treatment 2 for fun. foo[group=="Group A" & treatment=="Treatment 2"][1:8] <- rnorm(8,1,1) dat <- data.frame(foo,treatment,group) # set the limits for the plot, which also tells where to put the text my.xlim <- c(-6, 6) # make a matrix that counts the number of obs greater or less than zero obs.pos <- tapply(dat[dat[,1] > 0,1], dat[dat[,1] > 0,-1], length) obs.neg <- tapply(dat[dat[,1] <= 0,1], dat[dat[,1] <= 0,-1], length) #write some coordinate data x.obs.pos <- rep(my.xlim[2],dim(obs.pos)[2]) y.obs.pos <- 1:dim(obs.pos)[2] x.obs.neg <- rep(my.xlim[1],dim(obs.neg)[2]) y.obs.neg <- 1:dim(obs.neg)[2] bwplot(treatment~foo|group, data = dat, panel=function(...) { panel.violin(..., col = "transparent", varwidth = F) panel.abline(v=0, lty = "dotted") ltext(x.obs.pos, y.obs.pos, obs.pos, pos = 2) ltext(x.obs.neg, y.obs.neg, obs.neg, pos = 4) }, par.strip.text = list(cex = 0.8), xlim = my.xlim) obs.pos obs.neg # note that the numbers in the plot only match the matrices for Group A, # which is the first panel. Alas.
Haven't checked it too carefully, but how about: bwplot(treatment~foo|group, data = dat, panel=function(x,y,...) { panel.violin(x,y, ..., col = "transparent", varwidth = F) gt0 <- table( x > 0, y) panel.abline(v=0, lty = "dotted") grid.text(as.character(gt0[1,]), unit(1, 'lines'), unit(1:3, 'native'), just='left') grid.text(as.character(gt0[2,]), unit(1, 'npc') - unit(1, 'lines'), unit(1:3, 'native'), just='left') }, par.strip.text = list(cex = 0.8), xlim = my.xlim) --Matt> -----Original Message----- > From: r-help-bounces at stat.math.ethz.ch > [mailto:r-help-bounces at stat.math.ethz.ch]On Behalf Of Andy Bunn > Sent: Thursday, November 10, 2005 8:19 AM > To: R-Help > Subject: [R] ltext - adding text to each panel from a matrix > > > Hi all (really probably just Deepayan): > > In the plot below I want to add text on either side of each > violin plot that > indicates the number of observations that are either positive > or negative. > I'm trying to do this with ltext() and I've also monkeyed about with > panel.text(). The code below is generally what I want but my calls to > ltext() are wrong and I'm not sure how to fix them. Right now > they replicate > the first column of the matrices obs.pos and obs.neg for each > panel. How do > I tell ltext to advance to the next column when the next > panel is plotted? I > don't see how subscripts can do it, but I bet it's something > along that > line... > > Thanks, Andy > > rm(list = ls()) > set.seed(354) > # make a bimodal dataset with three groups and three treatments > foo <- c(rnorm(150,-1,0.5), rnorm(150,1,0.25)) > treatment <- factor(rep(seq(1,3),100), labels = c("Treatment > 1", "Treatment > 2", "Treatment 3")) > group <- factor(rep(seq(1,3),100), labels = c("Group A", > "Group B", "Group > C")) > group <- sample(group) > # corrupt Group A, Treatment 2 for fun. > foo[group=="Group A" & treatment=="Treatment 2"][1:8] <- rnorm(8,1,1) > dat <- data.frame(foo,treatment,group) > > # set the limits for the plot, which also tells where to put the text > my.xlim <- c(-6, 6) > > # make a matrix that counts the number of obs greater or less > than zero > obs.pos <- tapply(dat[dat[,1] > 0,1], dat[dat[,1] > 0,-1], length) > obs.neg <- tapply(dat[dat[,1] <= 0,1], dat[dat[,1] <= 0,-1], length) > #write some coordinate data > x.obs.pos <- rep(my.xlim[2],dim(obs.pos)[2]) > y.obs.pos <- 1:dim(obs.pos)[2] > x.obs.neg <- rep(my.xlim[1],dim(obs.neg)[2]) > y.obs.neg <- 1:dim(obs.neg)[2] > > bwplot(treatment~foo|group, data = dat, > panel=function(...) { > panel.violin(..., col = "transparent", varwidth = F) > panel.abline(v=0, lty = "dotted") > ltext(x.obs.pos, y.obs.pos, obs.pos, pos = 2) > ltext(x.obs.neg, y.obs.neg, obs.neg, pos = 4) > }, > par.strip.text = list(cex = 0.8), xlim = my.xlim) > obs.pos > obs.neg > > # note that the numbers in the plot only match the matrices > for Group A, > # which is the first panel. Alas. > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! > http://www.R-project.org/posting-guide.html >
On 11/10/05, Andy Bunn <abunn at whrc.org> wrote:> Hi all (really probably just Deepayan): > > In the plot below I want to add text on either side of each violin plot > that > indicates the number of observations that are either positive or negative. > I'm trying to do this with ltext() and I've also monkeyed about with > panel.text().They are the same (at least for now).> The code below is generally what I want but my calls to > ltext() are wrong and I'm not sure how to fix them. Right now they > replicate > the first column of the matrices obs.pos and obs.neg for each panel. How do > I tell ltext to advance to the next column when the next panel is plotted? > I > don't see how subscripts can do it, but I bet it's something along that > line...Maybe, but there's a more direct solution (somewhat artificial perhaps): bwplot(treatment~foo|group, data = dat, panel=function(..., packet.number) { panel.violin(..., col = "transparent", varwidth = F) panel.abline(v=0, lty = "dotted") ltext(x.obs.pos, y.obs.pos, obs.pos[, packet.number], pos = 2) ltext(x.obs.neg, y.obs.neg, obs.neg[, packet.number], pos = 4) }, par.strip.text = list(cex = 0.8), xlim = my.xlim) This is documented under 'panel' in ?xyplot. Deepayan