Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I highlight variance over a ggplot?

I can't find out how should I put up this ques so I used this method.

I have a latitude-longitude dataset. The image posted below is what I want to produce.. This is my dataset:

Latitude    Longitude
21.06941667 71.07952778
21.06941667 71.07952778
21.06666667 71.08158333
21.07186111 71.08688889
21.08625    71.07083333
21.08719444 71.07286111
21.08580556 71.07686111
21.07894444 71.08225
....

enter image description here

I have used geom_path() to find the path. Now, As shown in fig. I have highlighted the variance with white color around the path which I want to do. This is how I calculated variance:

var.latitude <- var(Data$Latitude)
var.longitude <- var(Data$Longitude)

I have marked the variance over the points using geom_errorbar():

geom_errorbar(aes(x=Latitude,y=Longitude, ymin=Longitude-var.longitude, ymax=Longitude+var.longitude),width=0.001)+
geom_errorbarh(aes(xmin=Latitude-var.latitude,xmax=Latitude+var.latitude),height=0.001)

Can anyone tell me how should I highlight the white area?

like image 243
ayush Avatar asked Jul 05 '15 08:07

ayush


1 Answers

I'm approaching this with the polygon feature of ggplot, see the documentation

library(ggplot2)    
data = rbind.data.frame(c(21.06941667, 71.07952778),
                        c(21.06666667, 71.08158333 ),
                        c(21.07186111, 71.08688889 ),
                        c(21.08625   , 71.07083333 ),
                        c(21.08719444, 71.07286111 ),
                        c(21.08580556, 71.07686111 ),
                        c(21.07894444, 71.08225 ))
names(data) = c("Latitude",     "Longitude")

Your variance is quite small, I multiplied by 10 for it to be visible in the graph. Note that in the graph in your question you draw the area from the fins of the errorbars, which is almost certainly not what you want.

var.latitude <- var(data$Latitude)*10
var.longitude <- var(data$Longitude)*10

Calculating this area as one is a menial task as also noted in the comments above. I found the easiest way to do this is overlapping two polygons for each path plus a polygon for each point. There sure may be more elegant ways, but hey, it works.

pos.poly = data.frame(id = paste0("c", as.character(1)), 
                      x = c(data$Latitude[1]-var.latitude, data$Latitude[1], data$Latitude[1]+var.latitude, data$Latitude[1]), 
                      y = c(data$Longitude[1], data$Longitude[1]+var.longitude, data$Longitude[1], data$Longitude[1]-var.longitude))
for(i in 2:dim(data)[1]){
  loc.pos1 = data.frame(id = paste0("a", as.character(i)), 
                       x = c(data$Latitude[i-1]-var.latitude, data$Latitude[i]-var.latitude, 
                             data$Latitude[i]+var.latitude, data$Latitude[i-1]+var.latitude), 
                       y = c(data$Longitude[i-1], data$Longitude[i], data$Longitude[i], data$Longitude[i-1]))
  pos.poly = rbind(pos.poly, loc.pos1)
  loc.pos2 = data.frame(id = paste0("b", as.character(i)), 
                        x = c(data$Latitude[i-1], data$Latitude[i], data$Latitude[i], data$Latitude[i-1]), 
                        y = c(data$Longitude[i-1]+var.longitude, data$Longitude[i]+var.longitude, 
                              data$Longitude[i]-var.longitude, data$Longitude[i-1]-var.longitude))
  pos.poly = rbind(pos.poly, loc.pos2)
  loc.pos3 = data.frame(id = paste0("c", as.character(i)), 
                        x = c(data$Latitude[i]-var.latitude, data$Latitude[i], data$Latitude[i]+var.latitude, data$Latitude[i]), 
                        y = c(data$Longitude[i], data$Longitude[i]+var.longitude, data$Longitude[i], data$Longitude[i]-var.longitude))
  pos.poly = rbind(pos.poly, loc.pos3)
}

This is plotted from two datasets so we need to specify data and the aes a couple more times.

plot1 = ggplot(pos.poly, aes(x=x, y=y)) + geom_polygon(aes(group=id), fill="white") + geom_path(data = data, aes(x=Latitude, y=Longitude))
plot1 = plot1 + xlab("Latitude") + ylab("Longitude") +  
  geom_errorbar(data = data, aes(x=Latitude,y=Longitude, ymin=Longitude-var.longitude, ymax=Longitude+var.longitude)) +
  geom_errorbarh(data = data, aes(xmin=Latitude-var.latitude,xmax=Latitude+var.latitude, x=Latitude, y=Longitude))
print(plot1)

enter image description here

like image 145
mts Avatar answered Oct 05 '22 05:10

mts