2

I produced a set of 2 contour lines for 6 different individuals. The contours for each individual were originally stored in a single list which contained 6 separate SpatialLinesDataFrames (one per individual).

I used NewDf <- do.call(rbind, OriginalList) to combine these into a single SpatialLinesDataFrame so that I can plot them on a single map with geom_path. NewDf now returns this structure:

> NewDf

class       : SpatialLinesDataFrame 
features    : 12 
extent      : .....
crs         : ....
variables   : 2
names       : level,   Individual 
min values  :   0.5, 21545 
max values  :  0.95, 32156 

I can plot all contours using this:

ggplot()+
  geom_path(data = NewDf, aes(x = long, y = lat, group = group)

but I want to color each set by Individual. I find that you can access the factor Individual using NewDf@data$Individual, but I cannot figure out how to refer to this in the ggplot call (e.g. ggplot()+geom_path(data = a, aes(x = long, y = lat, group = group, col = data$Individual)) does not work)

How do you access factors stored in a SpatialLinesDataFrame for mapping aesthetics in ggplot?

1 Answer 1

1

ggplot doesn't know what do with sp-class spatial objects. It passes them into the fortify function and then works with the result. That's where the long, lat and group names come from that you used in the geom_path call.

The "fortified" spatial lines object drops all its columns, retaining only coordinates and structure of how to construct the features in its id and group columns. Here's one created from the Sl object created in the help page class?SpatialLines:

> sldf = SpatialLinesDataFrame(Sl,data=data.frame(NAME=c("First","Second")),match.ID=FALSE)

The data part of this is:

> sldf@data
    NAME
1  First
2 Second

but when fortified becomes:

> fortify(sldf)
  long  lat order piece id group
1 1.00 3.00     1     1  a   a.1
2 2.00 2.00     2     1  a   a.1
3 3.00 2.00     3     1  a   a.1
4 1.05 3.05     4     2  a   a.2
5 2.05 2.05     5     2  a   a.2
6 3.05 2.05     6     2  a   a.2
7 1.00 1.00     1     1  b   b.1
8 2.00 1.50     2     1  b   b.1
9 3.00 1.00     3     1  b   b.1

If you want to add extra columns from your spatial lines to this you need to match them up based on the id column, which is also the row.names of the spatial lines. Use the match to extract rows from the spatial lines that match the fortified data frame, pull these out and column-bind them onto the fortified data frame to get a wider fortified data frame:

> fd = fortify(sldf)
> fd = cbind(fd, data.frame(sldf[match(fd$id, row.names(sldf)),]))
> fd
    long  lat order piece id group   NAME
1   1.00 3.00     1     1  a   a.1  First
1.1 2.00 2.00     2     1  a   a.1  First
1.2 3.00 2.00     3     1  a   a.1  First
1.3 1.05 3.05     4     2  a   a.2  First
1.4 2.05 2.05     5     2  a   a.2  First
1.5 3.05 2.05     6     2  a   a.2  First
2   1.00 1.00     1     1  b   b.1 Second
2.1 2.00 1.50     2     1  b   b.1 Second
2.2 3.00 1.00     3     1  b   b.1 Second

Then you can do this:

> ggplot() + geom_path(data=fd, aes(x=long, y=lat, group=group, col=NAME))
> 

At this point (or actually for me, well before this point) you remember what a pain sp-class objects are to deal with and suggest trying to do everything with the new sf class spatial objects and the geom_sf function, which understands all the columns of sf spatial data frames. Conversion from sp to sf is simple enough.

3
  • did you save the fortify object as fd?
    – Ryan
    Apr 2 at 16:07
  • meaning is this missing: fd <- fortify(sldf)
    – Ryan
    Apr 2 at 16:07
  • Yes sorry, exactly that. Will edit.
    – Spacedman
    Apr 2 at 18:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.