Wolfram Fischer - Z/I/M
2003-Jan-21 16:10 UTC
[Rd] [R] proposal: lattice/levelplot: panel.catlevelplot
I suggest to add a panel function to levelplot (or perhaps to an other 3d lattice function) which is able to translate the z values into the size of the rectangles. It could be used to display categorical data. I append the proposed code and two examples: - panel.catlevelplot() - example1.catlevelplot.esoph() - example2.catlevelplot.esoph() Wolfram Fischer #------ CODE -------------------------------------------------------------- panel.catlevelplot <- function (x, y, z, wx, wy, zcol, col.regions, subscripts , ... , z.factor.min = 0.02 # factor for z range expansion # -> little cells become visible , col.x = NULL # colors for categories in x direction , col.y = NULL # colors for categories in y direction , prop.width= TRUE # calculate width of cells proportionally to z position , prop.height= TRUE # calculate height of cells proportionally to z position , col.border.cells = NULL # color of borders of levelplot cells , lwd.border.cells = NULL # linewidth of borders of levelplot cells ){ axis.line <- trellis.par.get('axis.line') if( is.null( col.border.cells ) ) col.border.cells = axis.line$col if( is.null( lwd.border.cells ) ) lwd.border.cells = axis.line$lwd x <- as.numeric( x ) y <- as.numeric( y ) z <- as.numeric( z ) # <--- It would be better to do the following calculations # of z.x.factor and z.y.factor in the main function (levelplot). z.min <- min( z, na.rm=TRUE ) z.range <- max( z, na.rm=TRUE ) - z.min z.factor <- ( z - z.min + z.range * z.factor.min ) / ( z.range * ( 1 + z.factor.min ) ) z.x.factor <- if( prop.width ) z.factor else rep( 1, length(z) ) z.y.factor <- if( prop.height ) z.factor else rep( 1, length(z) ) # ---> fe.grid.rect <- function( sel, fill ){ grid.rect( x = x[subscripts][sel] , y = y[subscripts][sel] , width = wx[subscripts][sel] * z.x.factor[subscripts][sel] , height = wy[subscripts][sel] * z.y.factor[subscripts][sel] , default.units = "native" , gp = gpar( fill = fill , col = col.border.cells , lwd = lwd.border.cells ) ) } if( any(subscripts) ){ if( ! is.null( col.x ) ){ x.levels <- unique( x ) col.x <- rep( col.x, length = length(x.levels) ) for( i.col in seq( along = x.levels ) ){ fe.grid.rect( sel = ( x[subscripts] == viq.x.levels[i.col] ) , fill = col.x[i.col] ) } }else if( ! is.null( col.y ) ){ y.levels <- unique( y ) col.y <- rep( col.y, length = length(y.levels) ) for( i.col in seq( along = y.levels ) ){ fe.grid.rect( sel = ( y[subscripts] == y.levels[i.col] ) , fill = col.y[i.col] ) } }else{ for( i.col in seq( along = col.regions ) ){ fe.grid.rect( sel = ( zcol[subscripts] == i.col ) , fill = col.regions[i.col] ) } } } } #------ EXAMPLE ----------------------------------------------------------- data(esoph) library(lattice) example1.catlevelplot.esoph <- function( ... ){ ncolors <- nlevels( esoph$alcgp ) print( levelplot( ncases ~ agegp * alcgp | tobgp, data=esoph , main = 'esoph data set' , sub = 'tobgp' , cuts = ncolors , layout = c( 4, 4 ) , scales=list( x = list( labels = levels( esoph$agegp ), rot=90, alternating=F ) , y = list( labels = levels( esoph$alcgp ) ) ) , panel = panel.catlevelplot , colorkey = NULL , col.y = rainbow(ncolors) # , prop.height = F , ... )) } example2.catlevelplot.esoph <- function( ... ){ cuts <- 15 print( levelplot( ncases ~ agegp * alcgp | tobgp, data=esoph , main = 'esoph data set' , sub = 'tobgp' , cuts = cuts , layout = c( 4, 4 ) , scales=list( x = list( labels = levels( esoph$agegp ), rot=90, alternating=F ) , y = list( labels = levels( esoph$alcgp ) ) ) , panel = panel.catlevelplot , col.regions = rev( heat.colors(cuts+1) ) , col.border.cells = trellis.par.get('background')$col , lwd.border.cells = 3 , prop.height = F , prop.width = F , ... )) } #------ -------------------------------------------------------------------
Deepayan Sarkar
2003-Jan-22 04:29 UTC
[Rd] [R] proposal: lattice/levelplot: panel.catlevelplot
On Tuesday 21 January 2003 08:49 am, Wolfram Fischer - Z/I/M wrote:> I suggest to add a panel function to levelplot (or perhaps > to an other 3d lattice function) which is able to translate > the z values into the size of the rectangles.Cool.> It could be used to display categorical data. > > I append the proposed code and two examples: > - panel.catlevelplot() > - example1.catlevelplot.esoph() > - example2.catlevelplot.esoph()The second example gives an error for me. Do you have the latest grid installed ? I think changing fe.grid.rect below would solve it.> Wolfram Fischer > > #------ CODE -------------------------------------------------------------- > panel.catlevelplot <- function (x, y, z, wx, wy, zcol, col.regions, > subscripts , ... > , z.factor.min = 0.02 # factor for z range expansion > # -> little cells become visible > , col.x = NULL # colors for categories in x direction > , col.y = NULL # colors for categories in y direction > , prop.width= TRUE # calculate width of cells proportionally to z > position , prop.height= TRUE # calculate height of cells proportionally to > z position , col.border.cells = NULL # color of borders of levelplot > cells , lwd.border.cells = NULL # linewidth of borders of levelplot cells > ){ > axis.line <- trellis.par.get('axis.line') > if( is.null( col.border.cells ) ) col.border.cells = axis.line$col > if( is.null( lwd.border.cells ) ) lwd.border.cells = axis.line$lwd > > x <- as.numeric( x ) > y <- as.numeric( y ) > z <- as.numeric( z ) > > # <--- It would be better to do the following calculations > # of z.x.factor and z.y.factor in the main function (levelplot). > > z.min <- min( z, na.rm=TRUE ) > z.range <- max( z, na.rm=TRUE ) - z.min > z.factor <- ( z - z.min + z.range * z.factor.min ) / > ( z.range * ( 1 + z.factor.min ) ) > z.x.factor <- if( prop.width ) z.factor else rep( 1, length(z) ) > z.y.factor <- if( prop.height ) z.factor else rep( 1, length(z) ) > # ---> > > fe.grid.rect <- function( sel, fill ){if (any(sel)) ## ADDED> grid.rect( > x = x[subscripts][sel] > , y = y[subscripts][sel] > , width = wx[subscripts][sel] * > z.x.factor[subscripts][sel] > , height = wy[subscripts][sel] * > z.y.factor[subscripts][sel] > , default.units = "native" > , gp = gpar( > fill = fill > , col = col.border.cells > , lwd = lwd.border.cells > ) > ) > } > > if( any(subscripts) ){ > if( ! is.null( col.x ) ){ > x.levels <- unique( x ) > col.x <- rep( col.x, length = length(x.levels) ) > for( i.col in seq( along = x.levels ) ){ > fe.grid.rect( > sel = ( x[subscripts] == viq.x.levels[i.col] ) > , fill = col.x[i.col] > ) > } > }else if( ! is.null( col.y ) ){ > y.levels <- unique( y ) > col.y <- rep( col.y, length = length(y.levels) ) > for( i.col in seq( along = y.levels ) ){ > fe.grid.rect( > sel = ( y[subscripts] == y.levels[i.col] ) > , fill = col.y[i.col] > ) > } > }else{ > for( i.col in seq( along = col.regions ) ){ > fe.grid.rect( > sel = ( zcol[subscripts] == i.col ) > , fill = col.regions[i.col] > ) > } > } > } > } > > #------ EXAMPLE ----------------------------------------------------------- > data(esoph) > library(lattice) > > example1.catlevelplot.esoph <- function( ... ){ > ncolors <- nlevels( esoph$alcgp ) > print( levelplot( ncases ~ agegp * alcgp | tobgp, data=esoph > , main = 'esoph data set' > , sub = 'tobgp' > , cuts = ncolors > , layout = c( 4, 4 ) > , scales=list( > x = list( labels = levels( esoph$agegp ), rot=90, > alternating=F ) , y = list( labels = levels( esoph$alcgp ) ) > ) > , panel = panel.catlevelplot > , colorkey = NULL > , col.y = rainbow(ncolors) > # , prop.height = F > , ... > )) > } > > example2.catlevelplot.esoph <- function( ... ){ > cuts <- 15 > print( levelplot( ncases ~ agegp * alcgp | tobgp, data=esoph > , main = 'esoph data set' > , sub = 'tobgp' > , cuts = cuts > , layout = c( 4, 4 ) > , scales=list( > x = list( labels = levels( esoph$agegp ), rot=90, > alternating=F ) , y = list( labels = levels( esoph$alcgp ) ) > ) > , panel = panel.catlevelplot > , col.regions = rev( heat.colors(cuts+1) ) > , col.border.cells = trellis.par.get('background')$col > , lwd.border.cells = 3 > , prop.height = F > , prop.width = F > , ... > )) > } > > #------ ------------------------------------------------------------------- > > ______________________________________________ > R-devel@stat.math.ethz.ch mailing list > http://www.stat.math.ethz.ch/mailman/listinfo/r-devel