Was constructing a series of plots for extracting bathymetric data and an rare output comes out when trying to generate the last b/w plot with my data. Here are my data coord (12sites_lat_long2.txt).
SITE,LAT,LONG
TAD,48.133119,-69.705842
IV,48.034772,-69.340821
LUD,49.161609,-68.173798
SAM,49.130887,-66.500031
NOR,50.163282,-66.467896
PUR,50.151276,-66.325630
NEW,48.263541,-64.735703
PAS,48.017946,-65.265587
BON,48.041124,-65.491133
COR,47.496607,-61.723938
ROO,47.806514,-61.232300
CAO,48.5058323,-64.2231551
And here my code were i downloaded the bathymetric set and ploted
library(marmap)
library(dplyr)
library(SoDA)
library(ade4)
library(adespatial)
library(ggmap)
library(ggplot2)
library(reshape2)
library(dartR)
library(BiocManager)
library(devtools)
library(plotly)
library(directlabels)
sites <- read.table("12sites_lat_long2.txt", header=TRUE,dec=".",sep=",")
#Order the site object and check the sites positions
sites <- sites %>% dplyr::arrange(SITE)
summary(sites)
#Keep only latitude and longitude info
sites_depth <- dplyr::select(sites,LONG,LAT)
#Get the bathimetric Data and build a matrix
#in this case, we get the data from NOAA using the marmap package
bathydata <- marmap::getNOAA.bathy(lon1= -70.2966,
lon2= -60.9692,
lat1= 51.2392,
lat2= 46.6170,
resolution = 1)
#Summarizing the data
summary(bathydata)
#Next, we extract the bathimetric data
#We plot map according to different levels of depth seting colors for each level
blues <- colorRampPalette(c("lightblue", "cadetblue2", "cadetblue1", "white"))
blues <- c("lightsteelblue4", "lightsteelblue3","lightsteelblue2", "lightsteelblue1")
greys <- c(grey(0.6), grey(0.93), grey(0.99))
#And Plot a map with the colors created
plot(bathydata, image = TRUE, land = TRUE, n=1,
bpal = list(c(0, max(bathydata), greys),
c(min(bathydata), 0, blues)))
#add the sampling points and text to the plot
points(sites$LON, sites$LAT, pch = 21, col = "black",
bg = "yellow", cex = 1.3)
text(sites$LON, sites$LAT,sites$SITE, pos = 2)
# plot a map without color
pdf("Marmap_saccharina.pdf")
plot(bathydata, lwd = c(0.3, 1), lty = c(1, 1),
deep = c(-4500, 0), shallow = c(-50, 0),
step = c(500, 0),
col = c("grey", "black"), drawlabels = c(FALSE, FALSE))
scaleBathy(bathydata, deg = 3, x = "bottomleft", inset = 5)
points(sites$LON, sites$LAT, pch = 21, col = "black", bg = "grey", cex = 1)
text(sites$LON, sites$LAT,sites$SITE, pos = 1,cex = 0.5)
dev.off()
The output that I get instead of the map is just
RStudioGD
2
I was expecting a map similar to this one
example
I have searched but have no clue what this output is refering to and were is the error
Related
I am creating a plot based on INLA predictions. Everything works perfectly for the modelling, but for the plot,the legend on the graph are points (like https://gis.stackexchange.com/questions/350918/how-do-i-reverse-spplot-colour-key-so-the-values-are-decreasing) rather than a scale (like here http://www.nickeubank.com/wp-content/uploads/2015/10/RGIS3_MakingMaps_part1_mappingVectorData.html):
And here is the code that I would like to change. I guess there is a problem of factor (R spplot: colorbar rather than legend for SpatialPoint data, spplot issue with legend range and colors distribution) but I cannot understand how/what to change:
m_grid <- inla(formWITHOUT, data = inla.stack.data(region.stack.predGrid, spde = inlaSetting$region.spde),
family = "gamma",
control.predictor = list(A = inla.stack.A(region.stack.predGrid), compute = TRUE, link=1),
control.compute = list(cpo = TRUE, dic = TRUE),
control.family=list(link="default"))
summary(m_grid)
index.pred <- inla.stack.index(region.stack.predGrid, "region.pred")$data
region.grid_sf$Sbiomass <- m_grid$summary.fitted.values[index.pred, "mean"]
region.grid_sf$Sbiomass_sd <- m_grid$summary.fitted.values[index.pred, "sd"]
my.palette <- brewer.pal(n = 7, name = "OrRd")
par(mar = c(0,0,0,0))
spplot(region.grid_sf, c("Sbiomass"), col.regions = my.palette, col = "transparent")
Thanks in advance for any tips !
I finally found the answer:
cuts <- c(0,5000,10000,15000,20000,25000,30000)
spplot(region.grid_sf,
c("Sbiomass"),
col.regions = my.palette,
col = "transparent",
key.space = list(x=0.1,y=0.3),
colorkey =T,
cuts = cuts,
cex = 2,
pch = 22)
I'm trying to add the legend to my classification map using the code below.
library(raster)
library(RStoolbox)
landsat5 <- stack('lt05.tif')
shp<-shapefile("to5/to.shp")
SC_rf <- superClass(landsat5, shp, responseCol = "MC_ID",
nSamples = 1000, polygonBasedCV = TRUE,
model = "rf", tuneLength = 5, kfold = 5,
mode = "classification", predType = "raw", overwrite = TRUE)
## Plots
colors <- c("yellow", "green", "deeppink", "orange", "red")
plot(SC_rf$map, col = colors, legend = TRUE, axes = FALSE, box = FALSE)
legend(1, 1, legend = levels(shp$MC_info), fill = colors , title = "Classes")
The map is created but a legend error occurs:
'legend(1, 1, legend = levels(shp$MC_info), fill = colors, title = "Classes")':
'legend' is of length 0
Here is my shp object:
MC_info seems to be a vector, not a factor, so you don't need to use levels(). To access data in shapefile object, try to convert it by as.data.frame() function from raster package:
legend(1, 1, legend = raster::as.data.frame(shp)$MC_info, fill = colors , title = "Classes")
Or you can define a variable for that:
shp_df <- raster::as.data.frame(shp)
legend(1, 1, legend = shp_df$MC_info, fill = colors , title = "Classes")
This works for me as it converts the data data frame from the shp object and the MC_Info column is easily accessible. But I don!t have your data to check the legend working properly as you need...
I have a fairly simple and probably common task, plotting a raster dataset with countour lines and adding country borders together in one plot, however I did not find a solution anywhere. There are a a few hints available (such as this one), but no raster dataset is used there and I can't get it to work.
The dataset I am using is actually in netcdf format and available here (15mb in size) and contains about 40 years of gridded precipitation data.
Here is my line of code:
setwd("...netcdf Data/GPCP")
library("raster")
library("maps")
nc_brick79_17 <- brick("precip.mon.mean.nc") # load in the ncdf data as a
raster brick
newextent <- c(85, 125, -20, 20) # specify region of interest
SEA_brick <- crop(nc_brick79_17, newextent) # crop the region
day1 <- SEA_brick[[1]] # select very first day as example
colfunc<-colorRampPalette(c("white","lightblue","yellow","red","purple")) # colorscale for plotting
So it works of course when I just plot the raster data together with a map overlaid:
plot(day1, col=(colfunc(100)), interpolate=F, main="day1",legend.args=list(text='mm/hr', side=4,font=1, line=2.5, cex=1.1))
map("world", add=TRUE, lwd=0.5, interior = FALSE, col = "black")
We get this plot (Raster Plot with country borders added)
Now the code I use to generate the contour plot is the following:
filledContour(day1,zlim=c(0,20),color=colorRampPalette(c("white","lightblue","yellow","red","purple")),
xlab = "Longitude (°)", ylab = "Latitude (°)")
map("world", add=TRUE, lwd=0.5, interior = FALSE, col = "black") # add map overlay
I end up with a plot where obviously the country borders do not align and are even covering the colorbar.
Contour plot with map overlay shifted
In this last part I am trying to add the country boundaries to the contour plot, but it does not work, even though it should I assume. The map is simply not there, no error though:
filledContour(day1, zlim=c(0,20),
color.palette = colorRampPalette(c("white","lightblue","yellow","red","purple")),
xlab = "Longitude (°)", ylab = "Latitude (°)",
xlim = c(90, 120), ylim = c(-20, 20), nlevels = 25,
plot.axes = {axis(1); axis(2);
map('world', xlim = c(90, 120), ylim = c(-20, 20), add = TRUE, lwd=0.5, col = "black")})
From that line of code I get this plot.
Contour plot but no country borders added
What could I improve or is there any mistake somewhere? Thank you!
I chose to use ggplot here. I leave two maps for you. The first one is the one you created. This is a replication with ggplot. The second one is the one you could not produce. There are many things to explain. But I am afraid I do not have enough time to write all. But I left some comments in my code below. Please check this question to learn more about the second graphic. Finally, I'd like to give credit to hrbrmstr who wrote a great answer in the linked question.
library(maptools)
library(akima)
library(raster)
library(ggplot2)
# This is a data set from the maptools package
data(wrld_simpl)
# Create a data.frame object for ggplot. ggplot requires a data frame.
mymap <- fortify(wrld_simpl)
# This part is your code.
nc_brick79_17 <- brick("precip.mon.mean.nc")
newextent <- c(85, 125, -20, 20)
SEA_brick <- crop(nc_brick79_17, newextent)
day1 <- SEA_brick[[1]]
# Create a data frame with a raster object. This is a spatial class
# data frame, not a regular data frame. Then, convert it to a data frame.
spdf <- as(day1, "SpatialPixelsDataFrame")
mydf <- as.data.frame(spdf)
colnames(mydf) <- c("value", "x", "y")
# This part creates the first graphic that you drew. You draw a map.
# Then, you add tiles on it. Then, you add colors as you wish.
# Since we have a world map data set, we trim it at the end.
ggplot() +
geom_map(data = mymap, map = mymap, aes(x = long, y = lat, map_id = id), fill = "white", color = "black") +
geom_tile(data = mydf, aes(x = x, y = y, fill = value), alpha = 0.4) +
scale_fill_gradientn(colors = c("white", "lightblue", "yellow", "red", "purple")) +
scale_x_continuous(limits = c(85, 125), expand = c(0, 0)) +
scale_y_continuous(limits = c( -20, 20), expand = c(0, 0)) +
coord_equal()
ggplot version of filled.contour()
# As I mentioned above, you want to study the linked question for this part.
mydf2 <- with(mydf, interp(x = x,
y = y,
z = value,
xo = seq(min(x), max(x), length = 400),
duplicate = "mean"))
gdat <- interp2xyz(mydf2, data.frame = TRUE)
# You need to draw countries as lines here. You gotta do that after you draw
# the contours. Otherwise, you will not see the map.
ggplot(data = gdat, aes(x = x, y = y, z = z)) +
geom_tile(aes(fill = z)) +
stat_contour(aes(fill = ..level..), geom = "polygon", binwidth = 0.007) +
geom_contour(color = "white") +
geom_path(data = mymap, aes(x = long, y = lat, group = group), inherit.aes = FALSE) +
scale_x_continuous(limits = c(85, 125), expand = c(0, 0)) +
scale_y_continuous(limits = c(-20, 20), expand = c(0, 0)) +
scale_fill_gradientn(colors = c("white", "lightblue", "yellow", "red", "purple")) +
coord_equal() +
theme_bw()
Using the sample data below, how can I generate rasters and spatial points plot with the same colorkey as in the "manually" joined plot shown below?
library(rasterVis)
library(raster)
library(colorRamps)
col=colorRampPalette(matlab.like2(255))
s <- stack(replicate(2, raster(matrix(runif(100), 10))))
xy <- data.frame(coordinates(sampleRandom(s, 10, sp=TRUE)),
z1=runif(10), z2=runif(10))
levelplot(s, margin=FALSE, at=seq(0, 1, 0.05),col.regions=col)
x=xy$x;y=xy$y;z=xy$z1
levelplot(z ~ x + y,contour=F, panel = panel.levelplot.points,
margin=FALSE,col.regions=col,
par.settings=list(axis.line=list(lwd=3), strip.border=list(lwd=3)),
cex=1.4, scales=list(x=list(cex=1.7),y=list(cex=1.7)),xlab=list(label="Longitude",cex=2),
ylab=list(label="Latitude",cex=2))
Thanks to #fdestch I was able to generate the following plot using:
latticeCombineGrid(mget(rep("pp", 24)), layout = c(3, 8))
following my comments on printing multiple plots with the same colorkey.
An issue that remains to be clarified:
1) How can one decide on the order of panels? That is, which row & column to place a particular plot just as in levelplot using index.cond.
First of all, you should probably make sure that the breaks in the points plot are identical with those defined in the first levelplot.
## raster plot with colorkey disabled
pr <- levelplot(s, margin = FALSE, at = seq(0, 1, 0.05), col.regions = col,
colorkey = FALSE, xlab = list("Longitude", col = "transparent"))
## points plot
pp <- levelplot(z ~ x + y, panel = panel.levelplot.points, cex = 1.4,
contour = FALSE, margin = FALSE, col.regions = col,
colorkey = list(at = seq(0, 1, .05), width = .6, height = .6),
xlab = "Longitude", ylab = "Latitude")
Please note the definition of a transparent xlab when creating the raster plot. This little workaround comes in quite handy when using downViewport later on to ensure that the actual plot boundaries of pr and pp overlap (feel free to run grid.rect() right after print(pr, newpage = FALSE) to see what I mean).
The actual plot arrangement can then easily be achieved by using viewports from the grid package.
library(grid)
library(lattice)
## initialize new grid device
grid.newpage()
## add raster plot
vp1 <- viewport(x = 0, y = 0, width = .5, height = 1,
just = c("left", "bottom"))
pushViewport(vp1)
print(pr, newpage = FALSE)
## add points plot
downViewport(trellis.vpname("page"))
vp2 <- viewport(x = 1, y = 0, width = .75, height = 1,
just = c("left", "bottom"))
pushViewport(vp2)
print(pp, newpage = FALSE)
Here is my solution using latticeExtra::c.trellis:
library(raster)
library(rasterVis)
s <- stack(replicate(2, raster(matrix(runif(100), 10))))
xy <- data.frame(coordinates(sampleRandom(s, 10, sp=TRUE)),
z1=runif(10), z2=runif(10))
## Define theme and breaks
myTheme <- BTCTheme()
my.at <- seq(0, 1, 0.05)
Plot the Raster* object, using rasterVis::levelplot:
p1 <- levelplot(s, margin=FALSE,
at = my.at,
par.settings = myTheme)
Plot the points, using lattice::levelplot:
p2 <- levelplot(z1 ~ x + y, data = xy,
at = my.at,
panel = panel.levelplot.points,
par.settings = myTheme)
Join them with latticeExtra::c.trellis:
p3 <- c(p1, p2, layout = c(3, 1))
Unfortunately, c.trellis does not assign the strip labels correctly, so you have to define them directly:
update(p3,
strip = strip.custom(factor.levels = c(names(s), "Points")))
I am trying to plot rose diagrams/ circular histograms on specific coordinates on a map analogous to drawing pie charts on a map as in the package mapplots.
Below is an example generated with mapplots (see below for code), I'd like to replace the pie charts with rose diagrams
The package circular lets me plot the rose diagrams, but I am unable to integrate it with the mapplots package. Any suggestions for alternative packages or code to achieve this?
In response to the question for the code to make the map. It's all based on the mapplots package. I downloaded a shapefile for the map (I think from http://www.freegisdata.org/)
library(mapplots)
library(shapefiles)
xlim = c(-180, 180)
ylim = c(-90, 90)
#load shapefile
wmap = read.shapefile ("xxx")
# define x,y,z for pies
x <- c(-100, 100)
y <- c(50, -50)
z1 <- c(0.25, 0.25, 0.5)
z2 <- c(0.5, 0.2, 0.3)
z <- rbind(z1,z2)
# define radii of the pies
r <- c(5, 10)
# it's easier to have all data in a single df
plot(NA, xlim = xlim, ylim = ylim, cex = 0.75, xlab = NA, ylab = NA)
draw.shape(wmap, col = "grey", border = "NA")
draw.pie(x,y,z,radius = r, col=c("blue", "yellow", "red"))
legend.pie (x = -160, y = -70, labels = c("0", "1", "2"), radius = 5,
bty = "n", cex = 0.5, label.dist=1.5, col = c("blue", "yellow", "red"))
the legend for the pie size can then be added using legend.bubble
Have a look at this example, you can use the map as background an plot your rose diagrams withPlotrix or ggplot2. In either case you would want to overlay multiple of these diagrams on top of your map which is easy to do in ggplot, just have a look at the example.
I discovered subplot() in the package Hmisc, which seems to do exactly what I wanted. Below is my solution (without the map in the background, which can be plotted using mapplots). I am open to suggestions on how to improve this though...
library(Hmisc)
library (circular)
dat <- data.frame(replicate(2,sample(0:360,10,rep=TRUE)))
lat <- c(50, -40)
lon <- c(-100, 20)
# convert to class circular
cir.dat <- as.circular (dat, type ='angles', units = 'degrees', template = 'geographic', modulo = 'asis', zero = 'pi/2', rotation = 'clock')
# function for subplot, plots relative frequencies, see rose.diag for how to adjust the plot
sub.rose <- function(x){
nu <- sum(!is.na(x))
de <- max(hist(x, breaks = (seq(0, 360, 30)), plot = FALSE)$counts)
prop <- nu/de
rose.diag(x, bins = 12, ticks = FALSE, axes = FALSE,
radii.scale = 'linear',
border = NA,
prop = prop,
col = 'black'
)
}
plot(NA, xlim = xlim, ylim = ylim)
for(i in 1:length(lat)){
subplot(sub.rose(cir.dat[,i]), x = lon[i], y = lat[i], size = c(1, 1))
}