tflutre - 1 year ago 106
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")
``````

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

`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?

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
``````

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")
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download