2

So I think I have a pretty simple question, but I can't find the answer anywhere.

I have a lot of data containing catches of lobsters. It all pretty much looks like this.

                        Trip.ID Latitude Longitude            DateTime               ML6      TotalNephropsLandings
16409 OTB_CRU_32-69_0_0DK102831   57.931     9.277 2012-10-04 19:02:00 OTB_CRU_32-69_0_0                 0.2188619
16410 OTB_CRU_32-69_0_0DK102831   57.959     9.375 2012-10-04 21:02:00 OTB_CRU_32-69_0_0             0.2188619
16411 OTB_CRU_32-69_0_0DK102831   58.201    10.232 2012-10-04 02:00:00 OTB_CRU_32-69_0_0              0.2188619
16412 OTB_CRU_32-69_0_0DK102831   58.208    10.260 2012-10-04 03:00:00 OTB_CRU_32-69_0_0             0.2188619
16413 OTB_CRU_32-69_0_0DK102831   58.169    10.078 2012-10-03 23:00:00 OTB_CRU_32-69_0_0               0.2188619
16414 OTB_CRU_32-69_0_0DK102831   57.919     9.227 2012-10-04 18:00:00 OTB_CRU_32-69_0_0             0.2188619

What I would like to do is simply make a map with contours around areas based on the "ML6" column, which are different tools used for fishing.

I tried using geom_density2d, which looks like this: However I really don't want to show density, only where they are present. So basically one line around a group of coordinates that are from the same level in ML6. Could anyone help me with this?

It would also be nice to have the alternative to fill these in as polygons as well. But perhaps that could simple be accomplished using "fill=".

If anyone knows how to do this without R, you are also welcome to help, but then I would possibly need more in depth information.

Sorry for not producing more of my data frame...

Of course I should have produced the code I had for the plot, so here it is basically:

#Get map
 map <- get_map(location=c(left= 0, bottom=45, right=15 ,top=70), maptype = 'satellite')
ggmap(map, extent="normal") + 
  geom_density2d(data = df, aes(x=Longitude, y=Latitude, group=ML6, colour=ML6))
balconydoor
  • 55
  • 1
  • 2
  • 11
  • Would it be possible for you to provide your code? – jazzurro Nov 10 '14 at 11:09
  • @jazzurro I added the code for the plot. Was there anything else you had in mind? If you need more of my data I could provide some. I was just in a bit of a hurry writing the question... – balconydoor Nov 10 '14 at 11:45
  • I think I am finding a way out now. Hope I can post my suggestion soon. Thanks for the code. – jazzurro Nov 10 '14 at 11:47

1 Answers1

5

There are probably better way of doing this work. But, here is my approach for you. I hope this approach works with ggmap as well. Given time I have, this is my best for you. Since your sample data is way too small, I decided to use a part of my own data. What you want to do is to look into ggplot_build(objectname)$data[1]. (It seems that, when you use ggmap, data would be in ggplot_build(object name)$data[4].) For example, create an object like this.

foo <- ggmap(map, extent="normal") + 
       geom_density2d(data = df, aes(x=Longitude, y=Latitude, group=ML6, colour=ML6))

Then, type ggplot_build(foo)$data[1]. You should see a data frame which ggplot is using. There will be a column called level. Subset data with the minimum level value. I am using filter from dplyr. For example,

foo2 <- ggplot_build(foo)$data[1]
foo3 <- filter(foo2, level == 0.02)

foo3 now has data point which allows you to draw lines on your map. This data has the data points for the most outer circles of the level. You would see something like this.

#     fill level        x         y piece group PANEL
#1 #3287BD  0.02 168.3333 -45.22235     1 1-001     1
#2 #3287BD  0.02 168.3149 -45.09596     1 1-001     1
#3 #3287BD  0.02 168.3197 -44.95455     1 1-001     1

Then, you would do something like the following. In my case, I do not have googlemap. I have a map data of New Zealand. So I am drawing the country with the first geom_path. The second geom_path is the one you need. Make sure you change lon and lat to x and y like below.In this way I think you have the circles you want.

# Map data from gadm.org
NZmap  <- readOGR(dsn=".",layer="NZL_adm2")
map.df <- fortify(NZmap)

ggplot(NULL)+
geom_path(data = map.df,aes(x = long, y = lat, group=group), colour="grey50") +
geom_path(data = foo3, aes(x = x, y = y,group = group), colour="red")

enter image description here

UPDATE

Here is another approach. Here I used my answer from this post. You basically identify data points to draw a circle (polygon). I have some links in the post. Please have a look. You can learn what is happening in the loop. Sorry for being short. But, I think this approach allows you to draw all circles you want. Remind that the outcome may not be nice smooth circles like contours.

library(ggmap)
library(sp)
library(rgdal)
library(data.table)
library(plyr)
library(dplyr)

### This is also from my old answer.
### Set a range
lat <- c(44.49,44.5)                
lon <- c(11.33,11.36)   

### Get a map
map <- get_map(location = c(lon = mean(lon), lat = mean(lat)), zoom = 14,
   maptype = "satellite", source = "google")

### Create pseudo data.
foo <- data.frame(x = runif(50, 11.345, 11.357),
                  y= runif(50, 44.4924, 44.4978),
                  group = "one",
                  stringsAsFactors = FALSE)

foo2 <- data.frame(x = runif(50, 11.331, 11.338),
                   y= runif(50, 44.4924, 44.4978),
                   group = "two",
                   stringsAsFactors = FALSE)

new <- rbind(foo,foo2)

### Loop through and create data points to draw a polygon for each group.
cats <- list()

for(i in unique(new$group)){

foo <- new %>%
       filter(group == i) %>%
       select(x, y)

ch <- chull(foo)
coords <- foo[c(ch, ch[1]), ]

sp_poly <- SpatialPolygons(list(Polygons(list(Polygon(coords)), ID=1)))

bob <- fortify(sp_poly)

bob$area <- i

cats[[i]] <- bob
}

cathy <- as.data.frame(rbindlist(cats))

ggmap(map) +
geom_path(data = cathy, aes(x = long, y = lat, group = area), colour="red") +
scale_x_continuous(limits = c(11.33, 11.36), expand = c(0, 0)) +
scale_y_continuous(limits = c(44.49, 44.5), expand = c(0, 0))

enter image description here

Community
  • 1
  • 1
jazzurro
  • 23,179
  • 35
  • 66
  • 76
  • Because `geom_density2d` is a wrapper for `kde2d` (and subsequently `countour`) you can pass an argument for the `levels=c(...)`, so I would suspect your map could be created directly using `stat_density2d(levels = 0.02)`. Another option here would be to calculate the [convex hulls](http://stats.stackexchange.com/a/22855/1036) around the regions of the catches as well, although the contours may be nicer to look at. – Andy W Nov 10 '14 at 12:59
  • @AndyW Thanks for your comment. I thought about using `hull` as well. I will test out `stat_density2d(levels = 0.02)` tomorrow. This is something I did not have in my mind. Thank you for sharing your idea. – jazzurro Nov 10 '14 at 15:31
  • @jazzurro Thanks for your answer and sorry for not replying immediately. I seem to have a problem though, because when accessing the data I only get the columns; `x`, `y`, `PANEL` and `group`. Any idea why? This seems like a nice way to go about what I want to achieve, but I'm not really sure that all of the locations are included. Since when normally using `stat_density2d()` locations are not included if they occur too few times in the data relatively to those that occur a lot. Meaning, I guess, that their occurrence density is not high enough. – balconydoor Nov 11 '14 at 09:40
  • @balconydoor Thanks for your message. I see. I need to test what comes out with `ggmap`. However, given your images has contours, I am sure you have data somewhere. If not `ggplot_build(foo)$data[[1]]`, then see what `ggplot_build(foo)$data[[2]]` has. I am not knowledgeable in this `ggplot_build` business, but there should be polygon info somewhere.As for your 2nd part, you are right. I guess even your map does not have all data points. I have tight schedule this week, but I will try to give it a shot. Please be patient a bit. – jazzurro Nov 11 '14 at 10:25
  • @balconydoor I think using `hull` is probably the way to go. Let me create and play with a sample data. Meanwhile my answer in [this post](http://stackoverflow.com/questions/25847188/geographical-heat-map-of-a-custom-property-in-r-with-ggmap) may be something good to read. It may give you some ideas. – jazzurro Nov 11 '14 at 10:55
  • @balconydoor Just done it! I am afraid I do not have enough time to explain everything. However, you can find more info from links in the link I gave you above. I learned from these links. I really hope this approach works for you. Cheers. – jazzurro Nov 11 '14 at 11:49
  • 1
    @balconydoor One more thing. Try `ggplot_build(object name)$data[4]` with my first approach. You probably see `level`. Untested, but data there seems to be the one. – jazzurro Nov 11 '14 at 12:03
  • @Thanks your additional information. Your first apporach worked when using `ggplot_build(object name)$data[4]`. Now I just need to find a way to smoothly bring back the original level names, since they were transformed into number codes. Your second alternative also worked, though it became a bit messy. I will also take a look at hull, and experiment with your code a bit. Thank you for your time! – balconydoor Nov 12 '14 at 11:13
  • @balconydoor Good to hear that. I think the first approach will give you better circles. Hope you get the ideal graphic soon. – jazzurro Nov 12 '14 at 11:50
  • @balconydoor One more thing. The `hull` thing is the 2nd approach. `chull` is the function for it. :) – jazzurro Nov 12 '14 at 12:04
  • @jazzurro Yeah, I realised that after a few more moments of thinking. :) thanks – balconydoor Nov 12 '14 at 12:23