Dear all,
I'm trying to use the lattice barchart function to obtain a bar plot of a
variable for different values of two factors. The thing I'm trying to do is
something like this:
barchart(MyVar ~ season | place, data=mydataset)
My problem is that the column MyVar has some negative values and I would like
them to be represented as bars stacking down from zero instead of what the
function does that is finding the minimum value and then stacking all bars
from this minimum value up. I've looked into the the help pages and I saw no
way to go around this behaviour. Is there an easy way to get these "negative"
bars?
Thanks,
Luis
Luis Torgo
FEP/LIACC, University of Porto Phone : (+351) 22 607 88 30
Machine Learning Group Fax : (+351) 22 600 36 54
R. Campo Alegre, 823 email : ltorgo at liacc.up.pt
4150 PORTO - PORTUGAL WWW : http://www.liacc.up.pt/~ltorgo
On Tuesday 10 December 2002 06:11 am, Luis Torgo wrote:
Dear all,
I'm trying to use the lattice barchart function to obtain a bar plot of a
variable for different values of two factors. The thing I'm trying to do is
something like this:
barchart(MyVar ~ season | place, data=mydataset)
My problem is that the column MyVar has some negative values and I would
like them to be represented as bars stacking down from zero instead of what
the function does that is finding the minimum value and then stacking all
bars from this minimum value up. I've looked into the the help pages and I
saw no way to go around this behaviour. Is there an easy way to get these
"negative" bars?
No, I don't think so (short of using a modified panel.barchart, which should
be relatively easy -- panel.barchart essentially has just 3 lines of code).
But this seems very reasonable thing to want, so I'll add an option for this.
You could also use xyplot with type = "h", but that will give you lines
instead of bars.
Deepayan
On Tuesday 10 December 2002 14:30, Deepayan Sarkar wrote:
No, I don't think so (short of using a modified panel.barchart, which
should be relatively easy -- panel.barchart essentially has just 3 lines of
code). But this seems very reasonable thing to want, so I'll add an option
for this.
You could also use xyplot with type = "h", but that will give you lines
instead of bars.
Thank you for your help. You are right it is easy to adapt panel.barchart to
perform what I wanted. As such, while you do not add an option for that, I've
took the liberty to create my version of panel.barchart to solve the problem
temporarily. I herein include it together with a simple example use, in case
somebody has the same problem as me.
The function works almost fine. The only problem I was not able to get around
is the zero value reference line I want to draw in the case of horizontal
bars. I've used the grid.lines function. It works fine for vertical bars, but
it doesn't work for horizontal bars...
Luis Torgo
# Adapted from the code of panel.barchart by Deepayan Sarkar
my.panel.barchart <- function (x, y, box.ratio = 1, horizontal = TRUE, col =
bar.fill$col,
...)
{
x <- as.numeric(x)
y <- as.numeric(y)
bar.fill <- trellis.par.get("bar.fill")
if (horizontal) {
height <- box.ratio/(1 + box.ratio)
grid.lines(x=0,y=unit(c(0,1),"npc"),default.units="native")
for (i in seq(along = x))
if (x[i] >= 0)
grid.rect(gp = gpar(fill = col), y = y[i], x = 0,
height = height, width = y[i] - 0,
just = c("left", "centre"), default.units = "native")
else
grid.rect(gp = gpar(fill = col), y = y[i], x = x[i],
height = height, width = 0 - x[i],
just = c("left", "centre"), default.units = "native")
}
else {
width <- box.ratio/(1 + box.ratio)
grid.lines(x=unit(c(0,1),"npc"),y=0,default.units="native")
for (i in seq(along = y))
if (y[i] >= 0)
grid.rect(gp = gpar(fill = col), x = x[i], y = 0,
height = y[i] - 0, width = width,
just = c("centre", "bottom"), default.units = "native")
else
grid.rect(gp = gpar(fill = col), x = x[i], y = y[i],
height = 0 - y[i], width = width,
just = c("centre", "bottom"), default.units = "native")
}
}
# Example using the function
my.data <-
data.frame(var=c(34,-10,25,-40),season=c('s','w','s','w'),site=c('A','A','B','B'))
barchart(var ~ season | site, data=my.data, panel="my.panel.barchart")
Luis Torgo
FEP/LIACC, University of Porto Phone : (+351) 22 607 88 30
Machine Learning Group Fax : (+351) 22 600 36 54
R. Campo Alegre, 823 email : ltorgo at liacc.up.pt
4150 PORTO - PORTUGAL WWW : http://www.liacc.up.pt/~ltorgo
On Tuesday 10 December 2002 12:15 pm, Luis Torgo wrote:
On Tuesday 10 December 2002 14:30, Deepayan Sarkar wrote:
No, I don't think so (short of using a modified panel.barchart, which
should be relatively easy -- panel.barchart essentially has just 3 lines
of code). But this seems very reasonable thing to want, so I'll add an
option for this.
You could also use xyplot with type = "h", but that will give you lines
instead of bars.
Thank you for your help. You are right it is easy to adapt panel.barchart
to perform what I wanted. As such, while you do not add an option for that,
I've took the liberty to create my version of panel.barchart to solve the
problem temporarily. I herein include it together with a simple example
use, in case somebody has the same problem as me.
The function works almost fine. The only problem I was not able to get
around is the zero value reference line I want to draw in the case of
horizontal bars. I've used the grid.lines function. It works fine for
vertical bars, but it doesn't work for horizontal bars...
Luis Torgo
# Adapted from the code of panel.barchart by Deepayan Sarkar
my.panel.barchart <- function (x, y, box.ratio = 1, horizontal = TRUE, col
= bar.fill$col,
...)
{
x <- as.numeric(x)
y <- as.numeric(y)
bar.fill <- trellis.par.get("bar.fill")
if (horizontal) {
height <- box.ratio/(1 + box.ratio)
grid.lines(x=0,y=unit(c(0,1),"npc"),default.units="native")
This seems to need x = c(0,0). It's slightly odd that this works in the other
case. In any case,
panel.abline(v = 0) ## correspondingly, h = 0 below
might be a more elegant solution.
for (i in seq(along = x))
if (x[i] >= 0)
grid.rect(gp = gpar(fill = col), y = y[i], x = 0,
height = height, width = y[i] - 0,
^^^^^^^^^^^^^^^^
Typo here, should be width = x[i] - 0,
just = c("left", "centre"), default.units = "native")
else
grid.rect(gp = gpar(fill = col), y = y[i], x = x[i],
height = height, width = 0 - x[i],
just = c("left", "centre"), default.units = "native")
}
else {
width <- box.ratio/(1 + box.ratio)
grid.lines(x=unit(c(0,1),"npc"),y=0,default.units="native")
for (i in seq(along = y))
if (y[i] >= 0)
grid.rect(gp = gpar(fill = col), x = x[i], y = 0,
height = y[i] - 0, width = width,
just = c("centre", "bottom"), default.units =
"native") else
grid.rect(gp = gpar(fill = col), x = x[i], y = y[i],
height = 0 - y[i], width = width,
just = c("centre", "bottom"), default.units =
"native") }
}
# Example using the function
my.data <-
data.frame(var=c(34,-10,25,-40),season=c('s','w','s','w'),site=c('A','A','B
','B'))
barchart(var ~ season | site, data=my.data, panel="my.panel.barchart")