I am mapping using the "oce" package in R and want to add color to the ocean. I can manipulate the land color but not the ocean, and the mapping function omits "bg" to add background color. Here is my current code and parameters:
library(oce)
library(ocedata)
data("coastlineWorldFine")
par(mar=c(2, 2, 1, 1))
lonlim <- c(-79, -76)
latlim <- c(33, 35)
mapPlot(coastlineWorldFine,
projection="+proj=moll",
col = "lightgray",
longitudelim=lonlim,
latitudelim=latlim,
grid = FALSE,
bg = "lightblue")
Any suggestions on how to change the color of the ocean from white to a light blue?
Thanks!
Bit of a hack, but you can plot a rectangle the same size as the plotting area, then use par(new = TRUE) to plot mapPlot on top:
par(mar=c(2, 2, 1, 1))
plot(0, 0, type="n", ann=FALSE, axes=FALSE)
user <- par("usr")
rect(user[1], user[3], user[2], user[4],
col="lightblue", border=NA)
par(new = TRUE)
lonlim <- c(-79, -76)
latlim <- c(33, 35)
mapPlot(coastlineWorldFine,
projection="+proj=moll",
col = "lightgray",
longitudelim=lonlim,
latitudelim=latlim,
grid = FALSE)
Related
I would like to use the function abline to plot several lines which should be made transparent but I am stuck.
Currently I have this code:
plot(x=NA, type="n", ylim=c(1, 9), xlim=c(1, 4), xlab="x-value",
ylab="y-value", cex.axis = 1, cex.lab = 1)
for (i in 1:nrow(one_hundred_regressions)) {abline(coef=one_hundred_regressions[i,],
col = "red")}
Use adjustcolor changing the alpha value to whatever degree of transparency you want:
plot(1:10)
abline(v = 1:10, col = adjustcolor("red", alpha = 0.3))
You may use RGB colors "#RRGGBBaa", where aa is the alpha value for transparency. Example:
plot(1:10, type="n")
Map(function(x, y, z) abline(coef=c(x, y), col=z, lwd=2), 2:4, 2/(2:4)^2,
c("#AA000066", "#00AA0066", "#0000AA66"))
I am doing an arrange of four maps for a report. My desire plots' design is this:
To do this, I use layout() and plot following guidelines here.
I share below the code I am using to get what I mentioned. Note: code for plots 1 and 2 is simplified in order to focus on my question.
First, I design my arrange of plots:
## Layout design ####
layout(mat = matrix(c(1, 1, 1, 2, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4),
ncol = 8, byrow=TRUE),
widths = c(1, 1, 1),
heights = c(1))
par(mar = c(0.5, 0.5, 0.5, 0.5),oma = c(1.5, 1.5, 1.5, 1.5))
layout.show(4) # With this command we see the current plots' design, which gives the same plot I shared previously.
Then, I start to plot:
## Set colours for maps ####
col.t <- "#D2B48C" # Coastal line colour
col.amp <- c("darkolivegreen2", "olivedrab") # Marine protected area colour
col.mar <- "lightskyblue" # Sea colour
## First plot ####
plot(1, xlim = xlim.1, ylim = ylim.1, axes = FALSE, ann = FALSE)
rect(xleft = par("usr")[1], xright = par("usr")[2], ybottom = par("usr")[3], ytop = par("usr")[4], col = col.mar, border = "transparent")
plot(coastal_line, add = TRUE, col = col.t) #shape file
## Second plot ####
plot(1, xlim = xlim.2, ylim = ylim.2, axes = FALSE, ann = FALSE)
rect(xleft = par("usr")[1], xright = par("usr")[2], ybottom = par("usr")[3], ytop = par("usr")[4], col = col.mar, border = "transparent")
plot(coastal_line, add = TRUE, col = col.t) #shape file
## Third plot ####
plot(1, xlim = xlim.3, ylim = ylim.3, axes = FALSE, ann = FALSE)
rect(xleft = par("usr")[1], xright = par("usr")[2], ybottom = par("usr")[3], ytop = par("usr")[4], col = col.mar, border = "transparent")
plot(bathymetry,
col = fields::tim.colors(50),
xlim = c(par("usr")[1], par("usr")[2]),
ylim = c(par("usr")[3], par("usr")[4]),
add=TRUE,
legend=FALSE) #raster file
So far, everything is ok and my arrange of plots look like this:
However, when I add the isobaths I get problems:
contour(bathymetry,
add = TRUE,
levels = seq(0, -80, -8))
As you can see, the isobaths are plotted in a small region of my arrange of plots (in the left below corner). If I use layout.show(n), I see the current arrange of plots design.
layout.show(16) # Here I use 16 because I checked that I had 16 plots in my layout
So, I don't know why, but after plotting the raster layer, my layout configuration (4 plots in a 2x2 matrix) has changed to a 2x8 matrix (=16 plots).
Does anyone know why is this happening?
Thanks in advance
Earlier I asked about creating a gradient of n values in base graphics (LINK). Now I'd like to create a gradient legend that goes with it. My ideal would be something like ggplot2's gradient legends:
Here's some code similar to what I'm working with:
colfunc <- colorRampPalette(c("red", "blue"))
plot(1:20, 1:20, pch = 19, cex=2, col = colfunc(20))
Here is an example of how to build a legend from first principles using rasterImage from grDevices and layout to split the screen
layout(matrix(1:2,ncol=2), width = c(2,1),height = c(1,1))
plot(1:20, 1:20, pch = 19, cex=2, col = colfunc(20))
legend_image <- as.raster(matrix(colfunc(20), ncol=1))
plot(c(0,2),c(0,1),type = 'n', axes = F,xlab = '', ylab = '', main = 'legend title')
text(x=1.5, y = seq(0,1,l=5), labels = seq(0,1,l=5))
rasterImage(legend_image, 0, 0, 1,1)
Late to the party, but here is a base version presenting a legend using discrete cutoffs. Thought it might be useful for future searchers.
layout(matrix(1:2,nrow=1),widths=c(0.8,0.2))
colfunc <- colorRampPalette(c("white","black"))
par(mar=c(5.1,4.1,4.1,2.1))
plot(1:10,ann=FALSE,type="n")
grid()
points(1:10,col=colfunc(10),pch=19,cex=1.5)
xl <- 1
yb <- 1
xr <- 1.5
yt <- 2
par(mar=c(5.1,0.5,4.1,0.5))
plot(NA,type="n",ann=FALSE,xlim=c(1,2),ylim=c(1,2),xaxt="n",yaxt="n",bty="n")
rect(
xl,
head(seq(yb,yt,(yt-yb)/10),-1),
xr,
tail(seq(yb,yt,(yt-yb)/10),-1),
col=colfunc(10)
)
mtext(1:10,side=2,at=tail(seq(yb,yt,(yt-yb)/10),-1)-0.05,las=2,cex=0.7)
And an example image:
The following creates a gradient color bar with three pinpoints without any plot beforehand and no alien package is needed. Hope it is useful:
plot.new()
lgd_ = rep(NA, 11)
lgd_[c(1,6,11)] = c(1,6,11)
legend(x = 0.5, y = 0.5,
legend = lgd_,
fill = colorRampPalette(colors = c('black','red3','grey96'))(11),
border = NA,
y.intersp = 0.5,
cex = 2, text.font = 2)
As a refinement of #mnel's great answer, inspired from another great answer of #Josh O'Brien, here comes a way to display the gradient legend inside the plot.
colfunc <- colorRampPalette(c("red", "blue"))
legend_image <- as.raster(matrix(colfunc(20), ncol=1))
## layer 1, base plot
plot(1:20, 1:20, pch=19, cex=2, col=colfunc(20), main='
Awesome gradient legend inside')
## layer 2, legend inside
op <- par( ## set and store par
fig=c(grconvertX(c(0, 10), from="user", to="ndc"), ## set figure region
grconvertY(c(4, 20.5), from="user", to="ndc")),
mar=c(1, 1, 1, 9.5), ## set margins
new=TRUE) ## set new for overplot w/ next plot
plot(c(0, 2), c(0, 1), type='n', axes=F, xlab='', ylab='') ## ini plot2
rasterImage(legend_image, 0, 0, 1, 1) ## the gradient
lbsq <- seq.int(0, 1, l=5) ## seq. for labels
axis(4, at=lbsq, pos=1, labels=F, col=0, col.ticks=1, tck=-.1) ## axis ticks
mtext(sq, 4, -.5, at=lbsq, las=2, cex=.6) ## tick labels
mtext('diff', 3, -.125, cex=.6, adj=.1, font=2) ## title
par(op) ## reset par
I might be missing something simple here... I can't find anyway to remove the lines that cross the legend differentiating different colours; following on the from the volcano topography example in ?filled.contour, I've got this:
x <- 10*1:nrow(volcano)
y <- 10*1:ncol(volcano)
filled.contour(x, y, volcano, color = terrain.colors,
plot.title = title(main = "The Topography of Maunga Whau",
xlab = "Meters North", ylab = "Meters West"),
plot.axes = { axis(1, seq(100, 800, by = 100))
axis(2, seq(100, 600, by = 100)) },
key.title = title(main="Height\n(meters)"),
key.axes = axis(2,
labels=FALSE,
at=FALSE,
lty=NULL,
tick=FALSE,
col="white",
col.ticks=NULL)
)
mtext(paste("filled.contour(.) from", R.version.string),side = 1, line = 4, adj = 1, cex = .66)
I've managed to remove all the labels and tick-marks from the axis, but the lines still exist (incidentally, the effect I'm trying to achieve is (I believe) the default in Matlab!)
If you examine the code for filled.contour you'll see this line:
rect(0, levels[-length(levels)], 1, levels[-1L], col = col)
that draws the color key rectangle. It's vectorized, so it's drawing each of the individual color boxes. The function rect accepts an argument border, which if you set to NA will omit the internal borders of the rectangles. So create your own version of the function and change this line to :
rect(0, levels[-length(levels)], 1, levels[-1L], col = col, border = NA)
or make it an argument, rather than hard coding. When I do this, I get the following graph:
You don't even need to change the filled.contour hardcode. Apparently the argument border in the function rect relies on par("fg"). Just set par(fg = NA) to remove those black lines.
I am trying to remove all margins and the "figure region" of a plot in R, so that the plot region comprises the entire graphic device. I thought the code below would do it, but there is still a border around my plot (wider on left/bottom, thinner on top/right). Thanks
par(oma=c(0, 0, 0, 0))
par(mar=c(0, 0, 0, 0))
par(plt=c(0, 1, 0, 1))
Thought I would add a picture to show my progress. The xaxs and yaxs removed nearly all border from the top and right- there is still a border on the left and bottom.
The relevant portion of my script is below.
png("Test.png",
width = 256, height = 256,
units = "px", pointsize = 6.4,
bg = "black", res = NA)
par(mar=c(0, 0, 0, 0), xaxs='i', yaxs='i')
smoothScatter(lhb$px, lhb$pz, nrpoints=0, xlim=c(-3,3), ylim=c(0,5),
main="", xlab="", ylab="", axes=FALSE,
colramp=colorRampPalette(c("black", "#202020", "#736AFF", "cyan", "yellow", "#F87431", "#FF7F00", "red", "#7E2217"))
)
segments(.83, 1.597, .83, 3.436, col = par("fg"), lty = par("lty"), lwd = par("lwd"))
segments(-.83, 1.597, -.83, 3.436, col = par("fg"), lty = par("lty"), lwd = par("lwd"))
segments(-.83, 3.436, .83, 3.436, col = par("fg"), lty = par("lty"), lwd = par("lwd"))
segments(-.83, 1.597, .83, 1.597, col = par("fg"), lty = par("lty"), lwd = par("lwd"))
dev.off()
One issue is fundamentally not getting what plt does. From ?par we have:
‘plt’ A vector of the form ‘c(x1, x2, y1, y2)’ giving the
coordinates of the plot region as fractions of the current
figure region.
So your plot region is of zero size if you do par(plt=c(1, 1, 1, 1)), so that doesn't seem to be the way to go. This is because the figure region contains the plot region.
This plot seems to cover the entire region, without any margins:
op <- par(mar = rep(0, 4))
plot(1:10)
par(op)
it covers it so well you can't see the axes or the box:
This assumes the default for 0 outer margin (oma). Is this what you were looking for?
We can see that just adjusting the plot margins, as above, we also change the plt parameter as a side effect:
> par("plt")
[1] 0.1173174 0.9399106 0.1457273 0.8828467
> op <- par(mar = rep(0, 4))
> par("plt")
[1] 0 1 0 1
> par(op)
> par("plt")
[1] 0.1173174 0.9399106 0.1457273 0.8828467
indicating that simply setting the plot margins is sufficient to get a plot/figure region encompassing the entire device.
Of course, there is still a bit of internal padding that insures the ranges of the axes are slightly large than the range of the data in both the x and y coordinates. But you can control this with xaxs and yaxs --- see ?par
Update: As the OP has shown the sort of figure they are trying to produce without margins, I can provide a reproducible example:
set.seed(1)
dat <- matrix(rnorm(100*100), ncol = 100, nrow = 100)
layout(matrix(1:2, ncol = 2))
image(dat)
op <- par(mar = rep(0, 4))
image(dat)
par(op)
layout(1)
which gives for comparison:
and showing just the full plotting region:
Try setting the clip region parameter 'xpd' to NA ( clipped to device).
par(xpd = NA)