Search code examples
rplotggplot2pointssegments

R: Unite multiple segments() and points() in base R plot


I am plotting several graphs defined by ID into different files in the following way.

xy <- data.frame(NAME=c("NAME1","NAME1","NAME1","NAME2","NAME2","NAME2","NAME3","NAME3"),ID=c(87,87,87,199,199,199,233,233), X_START_YEAR=c(1950,1988,1994,1899,1909,1924,1945,1948),Y_START_VALUE=c(75,25,-90,-8,-55,-10,-9,12),X_END_YEAR=c(1985,1994,1999,1904,1924,1987,1946,1949), Y_END_VALUE=c(20,50,-15,-70,-80,-100,24,59))

  NAME  ID X_START_YEAR Y_START_VALUE X_END_YEAR Y_END_VALUE
1 NAME1  87         1950            75       1985          20
2 NAME1  87         1988            25       1994          50
3 NAME1  87         1994           -90       1999         -15
4 NAME2 199         1899            -8       1904         -70
5 NAME2 199         1909           -55       1924         -80
6 NAME2 199         1924           -10       1987        -100
7 NAME3 233         1945            -9       1946          24
8 NAME3 233         1948            12       1949          59

# Split glacier names by ID
ind <- split(x = xy,f = xy[,'ID'])

# Plot
for (i in ind){
  xx = unlist(i[,grep('X_',colnames(i))])
  yy = unlist(i[,grep('Y_',colnames(i))])    
  filename <- paste0(i[1, 'ID'], '.png') 
  png(filename, width=1679, height=1165, res=150)
  if(any(xx < 1946)) {my_x_lim <- c(min(xx), 2014)} else {my_x_lim <- c(1946, 2014)} 
  par(mar=c(6,8,6,5))
  plot(xx, yy)
  i <- i[,-1]
  segments(i[,2],i[,3],i[,4],i[,5],lwd=2)
  points(xx, yy, pch=21,cex=1, bg='white') 
  dev.off()
} 

My question: What I am looking for is a base R solution to include the whole data of xy into one plot (instead of several plots like the code above does) and have multiple lines and points (groups defined by ID) in a legend. I figured out a quite straightforward way to do this with ggplot but I am interested how to do that in base R. Any ideas?

Here is the ggplot code that might give you an idea of what I am attempting to do:

library(ggplot2)
p = ggplot(xy)
p = p + geom_segment(aes(x = X_START_YEAR, xend = X_END_YEAR, y = Y_START_VALUE, yend = Y_END_VALUE,linetype=NAME))
print(p)

Solution

  • noms<-levels(xy$NAME)
    nblev<-nlevels(xy$NAME)
    linetype<-(1:9)[1:nblev]
    
    par(mar=c(5,4,4,10),xpd=TRUE)
    plot(c(xy[,3],xy[,5]),c(xy[,4],xy[,6]),type="p",pch=21,xlab="YEAR",ylab="VALUE",las=1)
    segments(xy[,3],xy[,4],xy[,5],xy[,6],lty=linetype[as.numeric(xy$NAME)])
    coord<-par("usr")
    legend(coord[2]+10,sum(coord[3:4])/2,lty=linetype,legend=noms,bty="n")