tflutre tflutre - 1 month ago 17
R Question

distinguish spatial points by two attributes (via color and symbol) with spplot

Let's say we are interested in comparing 9 different cultivars of a plant species, by planting 2 cuttings of each of them in a field. I want to plot the whole layout, with one point per cutting, as if we were seeing the field from above. With the

sp
and
lattice
R packages, I know how to use colors to distinguish cuttings according to one factor attribute, but I can't succeed in also using symbols for another factor attribute.

More details are needed to understand the reproducible example below. I further assume that the cuttings were planted on a regular grid with 6 rows and 3 columns (18 locations in total). The field is divided into 2 blocks of 9 locations each, so that each cultivar is present only once in each block. So I want to use color to distinguish the blocks (say, block A in blue and block B in red). Moreover, the cultivars belong to two different categories. I hence also want to use symbols to distinguish categories (say, circles and triangles).

(x <- data.frame(cultivar=rep(paste0("cv", 1:9), 2),
row=rep(11:16, each=3),
column=rep(5:7, 6),
block=rep(c("A","B"), each=9),
category=rep(c(5,5,rep(1,7)), 2)))


Such a data.frame can be converted into a spatial object:

library(sp)
x.sp <- SpatialPointsDataFrame(coords=x[,c("column","row")],
data=x[,c("block","category")])
summary(x.sp)


Here is how I manage to distinguish blocks per color:

spplot(obj=x.sp, zcol=c("block"),
col.regions=c("blue","red"), key.space="right",
scales=list(draw=TRUE), aspect="fill",
xlab=colnames(coordinates(x.sp))[1],
ylab=colnames(coordinates(x.sp))[2],
main="Layout on the field")


spplot

When I specify
zcol=c("block","category")
, the error says:
all factors should have identical levels
.

I read about the
sp.layout
option of
spplot
, and the
par.settings
option of
xyplot
(called by
spplot
), but don't quite understand how they work. Any idea?

Or do you know of another (easy) way to do such a plot with other packages?

Answer

I shows two approaches, using update and making additional factor.

The foarmer: First, you make a base object having a "block" (color) information (it is almost the same as what you showed above). Second, you can add "category" (pch) information and legend using update().

The latter: It is based on the idea that make and use combination factor having all factorial information.

  ## "category" isn't numeric but factor. It would be better to change class.
x$category <- as.factor(x$category)
x.sp <- SpatialPointsDataFrame(coords=x[,c("column","row")], data=x[,c("block","category")])

  ## make a base graph ("block")
p <- spplot(obj = x.sp, zcol = c("block"),
            col.regions = c("blue","red"), key.space = "none", # <- modify not to make legend
            scales = list(draw=TRUE), aspect = "fill",
            xlab = colnames(coordinates(x.sp))[1],
            ylab = colnames(coordinates(x.sp))[2],
            main = "Layout on the field")

  ## add "category" information and legend
p <- update(p, pch = c(16, 17)[x.sp$category],
            key = list(right = list(fun = draw.key), 
                       points = list(col = c("red", "blue", 1, 1), pch = c(15, 15, 1, 2)), 
                       text = list(c(levels(x.sp$block), levels(x.sp$category))),
                       space = 'right', columns = 1)) 
p

enter image description here

The latter approach (using combination of factor)

x.sp2 <- SpatialPointsDataFrame(coords=x[,c("column","row")], 
                                data=cbind(x[,c("block","category")], comb = paste0(x$block, x$category)))

spplot(x.sp2, "comb", col.regions = rep(c("red", "blue"), each = 2), pch = rep(c(16, 17), 2), 
       scales=list(draw=TRUE), aspect="fill", key.space = "right",
       xlab=colnames(coordinates(x.sp))[1],
       ylab=colnames(coordinates(x.sp))[2],
       main="Layout on the field")