0

I would like to use different colors for specific ranges of values a have in grids in a map (Southern Hemisphere), when working with this dataset. I'm not sure if have defined to blocks correctly and I don't know how to ask for different colors for each block where I have at least one occurrence.

I'm using ggplot2 in R to create a map with grids with different numbers of individuals in each. I got a nice plot, but it is showing me only few colors/shades (because I have few grids with high values). So I divided the range of the individuals sighted in each grid (n, that varies from 1-15035) in blocks (by = 100) to then ask R to use a different color/shades considering the block that each grid belongs to (e.g. use one color for the grids where I have 1-100 individuals, another color for the ones with 101-200 individuals, and so on). I know that I have many (151) blocks, but from them there's only 30 where a have at least one occurrence (there's no grid with most of the ranges). There's a mistake in my blocks (breaks in the code provided, as there's some overlap) and I don't know how to include this information when creating the plot to ask for the 30 different colors for each of the blocks where the frequency is different from zero. I tried some options using the ggplot arguments there I kept in the code provided here (the first three lines creating a object 'sc'). How should I specify my blocks (breaks) to avoid the overlap I'm getting? Is the limits argument right in the code? How to ask for different colors for the blocks where I have at least one individuals (n>0)?

Any tip will be very appreciated :)

##Setting workspace
#setwd...
rm(list=ls()) #removing previous objects

#Installing (or loading) necessary packages
packages = c('ggplot2','sp','rgdal','sf','readxl','maps','dplyr')

package.check = lapply(packages, FUN = function(x) {
if (!require(x, character.only = TRUE)) {
install.packages(x, dependencies = TRUE)
library(x, character.only = TRUE)
}
})

####     Data     ###
hump = read_excel("data_r.xlsx")
range(hump$Lat_Dec)
range(hump$Lon_Dec)

#Convert df to sf -----------------------------
hbk_sf = st_as_sf(x = hump,                         
              coords = c("Lon_Dec", "Lat_Dec"),
              crs = "+init=epsg:4326")
class(hbk_sf)

#Plot
plot(st_geometry(hbk_sf))

#Plot all variables (I don't recommend, it will take some time)
#plot(hbk_sf)

#Create grid--------------
grd = st_make_grid(hbk_sf, cellsize = 10, square = T)
grd = as_Spatial(grd)
grd = st_as_sf(grd)
grd$id = rownames(grd)
class(grd)
#plot(st_geometry(grd),add=T)

#Count individuals at grid------------------
#Spatial join: Add the grid id at hbk dataframe
hbk = st_join(hbk_sf, grd, join = st_within)

range(hbk$id,na.rm=T)
hbk_count = count(as_tibble(hbk), id) #alternativelly hbk_count = 
aggregate(hbk$Hbk, by=list(hbk$id), FUN=sum)
hbk_count


#Adding the count in grids
grd_hbk = left_join(grd,hbk_count)
plot(grd_hbk)
range(grd_hbk$n,na.rm=T)

ggplot(grd_hbk,aes(x=n))+geom_density()

#Plotting with ggplot
world = sf::st_as_sf(map('world', plot = FALSE, fill = TRUE))

mymap = ggplot(grd_hbk[!is.na(grd_hbk$n),],aes(fill=n))+
geom_sf(data=world,aes(),fill='grey',lwd=.2)+
geom_sf(alpha=.7,lwd=0)+
scale_fill_distiller(palette = "Spectral")+
coord_sf(crs = st_crs(4326),xlim = c(-165,165), ylim = c(-70,6))+
theme_bw()       # +  theme(legend.position = 'none')

mymap

mymap = mymap + ggtitle("...")+
theme(plot.title = element_text(color = "black", size = 10, hjust = 0.5))


mymap

ggsave("mymap.png", dpi=300)

#-------
#To give colours to the grids considering the range of catches in each one
#that has at least one catch (grd_hbk>0)
#Tryied to create breaks to then consider in the grd_hbk$n. I wanna R to 
#use a different colour/shade considering the range of the grd_hbk$n in 
#the grids (one colour for grids with 1-100 catches, another colour for 
#grids with 101-200 and so on)---

# Generate breaks to cut the data
breaks = seq(0, 15100, by = 100) 

# Cut the data and save the result in an object
r = cut(grd_hbk$n, breaks) #this an overlap (Levels: (0,100] (100,200] 
#(200,300]...)

# Check the number of different categories
length(levels(r))

# Name for the levels
levels(r) = as.character(1:152)

#table(levels(r))
table(r)

#create a combination of colours to use in the following plot 
#sc = scale_colour_gradientn(colors = 'red', 'blue', 'green')
#sc = scale_fill_grey(start=1, end=15035, aes(fill=y))
#sc = scale_fill_grey(start=min(levels(r)), end=max(levels(r)),     
#aes(fill=y))
sc = scale_fill_gradient(low="blue", high="red")

mymapii = ggplot(grd_hbk[!is.na(grd_hbk$n),],aes(fill=n))+
geom_sf(data=world,aes(),fill='grey',lwd=.2)+
geom_sf(alpha=.7,lwd=0)+
scale_colour_manual(limits = min(levels(r)),max(levels(r)),
                  values = sc, #colors to be used
                  breaks = breaks,
                  aes(fill=sc))+ #maybe need another specification here?
coord_sf(crs = st_crs(4326),xlim = c(-165,165), ylim = c(-70,6))+
theme_bw()

mymapii
Elisa
  • 1
  • 1
  • 1
    It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input data and desired output that can be used to test and verify possible solutions. We don't have any data to run and test your code so it's not very easy to see what it's currently doing. – MrFlick Aug 23 '19 at 15:03
  • 1
    In addition to what @MrFlick says, even *without* being able to see or run any of what you're working with, 30 colors is almost certainly too many to distinguish. – camille Aug 23 '19 at 15:10
  • If the problem is that you only have few "high" values, leading to a "compressed" palette, you could consider using a logarithmic or other transformation over the fill variable. See the `trans` argument to `scale_fill_gradient` function. Or you could set the limits so to get a "nice" palette, and use the `oob` argument to make so that out of bound points are shown with a color corresponding to the limit of the palette (`oob = scales::squish`) – lbusett Aug 24 '19 at 15:18
  • Dear, thanks for the reply. I edited the question, so you can find the data and a my complete script. – Elisa Aug 30 '19 at 14:13

0 Answers0