1
votes

Having to plot altimeter profiles computed from .gpx tracks of hiking/biking routes, I've normal XY graphs, where X is the progressive distance covered, and Y is the altitude:
I know also the surface of each segment of a track (asphalt, ground, cobblestone, ...) , so my data.table TRACKS is in the form:

PROGDIST  ALTITUDE  SURFACE
      50       110  asphalt
     100       123  asphalt
     150       146  asphalt
     200       124  asphalt
     250       141  asphalt
     300       141  asphalt
     350       148  ground
     400       118  ground
     450       120  ground
      …         …        …

I'd like to enrich the graph with this information, obtaining something like this:

I tried to use geom=c("area", "line") with qplot, and geom="ribbon" from ggplot2, but my actual knowledge of these packages is not enough, so any help will be welcome!

2

2 Answers

1
votes

You can easily do this with the fill option in ggplot. But you first have to change your data to make the change points unique:

# original data
df <- read.table(text = 'PROGDIST  ALTITUDE  SURFACE
      50       110  asphalt
     100       123  asphalt
     150       146  asphalt
     200       124  asphalt
     250       141  asphalt
     300       141  asphalt
     350       148  ground
     400       118  ground
     450       120  ground', header=TRUE)
# find points where SURFACE changes
df.change <- df[diff(as.numeric(df$SURFACE)) > 0, ] 
df.change$SURFACE <- df[c(0, diff(as.numeric(df$SURFACE))) > 0, "SURFACE"] 
# add points with new surface to plot
df.new <- rbind(df, df.change)
df.new <- df.new[order(df.new$PROGDIST), ]
# plot
ggplot(df.new, aes(PROGDIST, ALTITUDE)) + 
  geom_line() + 
  geom_ribbon(aes(ymin=0, ymax=ALTITUDE, fill=SURFACE)) +
  theme_bw()
1
votes

Using your data this is one way you can do it:

df <- read.table(header=T,text="
PROGDIST  ALTITUDE  SURFACE
50       110  asphalt
100       123  asphalt
150       146  asphalt
200       124  asphalt
250       141  asphalt
300       141  asphalt
350       148  asphalt #you need to add this line in your data so that the colouring goes up to 350 and not stop at 300. #remove this comment to run read.table()
350       148  ground
400       118  ground
450       120  ground")

ggplot(aes(x=PROGDIST,y=ALTITUDE) , data=df ) + geom_line() +
  geom_ribbon(data=subset(df, SURFACE=='asphalt') , aes(ymax=ALTITUDE) ,ymin=0, fill='red', colour=NA, alpha=0.5) +
  geom_ribbon(data=subset(df, SURFACE=='ground') , aes(ymax=ALTITUDE) ,ymin=0, fill='blue', colour=NA, alpha=0.5) 

enter image description here

However, note in your data that you need to add an extra line to achieve this graph, otherwise you will have a gap in the plot. Check the comment above.

Hope it helps.