Adding tickmarks to colour key in R - r

Following up this question: pseudocolors in R
I've found a way to create the pseudocolour images with a colour key. However, I'm stuck with adding some text to this key (e.g., "low", "mid", "high" along with tickmarks at the ends an in the middle).
The short version of the story (as an MWE), would be:
library(RColorBrewer)
pal <- colorRampPalette(brewer.pal(9, "YlOrBr"), space = 'rgb')(256)
layout(matrix(c(1,2), nrow = 1), widths = c(4,1), heights = c(4,4))
layout.show(2)
par(mar = c(0,0,0,0))
image(t(matrix(1:30, ncol = 1, nrow = 30)),
col = pal, xaxt = "n", yaxt = "n", frame.plot = FALSE)
par(mar = c(0,0.1,0,0))
image(t(matrix(1:30, ncol = 1, nrow = 30)),
col = pal, xaxt = "n", yaxt = "n", frame.plot = FALSE)
So the aim is to end tickmarks with text on the left part of the image.
Thanks in advance for any help!

I didn't see the point of the layout but thought you could just increase your margin for the first image call and leave out the second one? You wanted "low", "mid", "high" along with tickmarks at the ends an[d] in the middle which I found confusing. Perhaps this will further the discussion:
layout(matrix(c(1,2), nrow = 1), widths = c(4,1), heights = c(4,4))
layout.show(2)
par(mar = c(0,0,0,2))
image(t(matrix(1:30, ncol = 1, nrow = 30)),
col = pal, xaxt = "n", yaxt = "n", frame.plot = FALSE)
axis(4, at=(30:1)/30, labels=1:30, cex.lab=0.6)

Related

How to customise dates (years) on the x-axis in R

I am struggling to customise the jump size on the x-axis in R.
Current code:
par(mfrow = c(2,2))
r.star.ts.sp <- ts(r.star.sp, frequency = 4, start = c(1978,1), end = c(2018, 1))
# Big drop in r* around 123th quarter equivalent to 2008:Q4 / 2009:Q1
trendgrowth.ts.sp <- ts(trendgrowth.sp, frequency = 4, start = c(1978,1), end = c(2018, 1))
plot.ts(r.star.ts.sp,
ylim = c(-3, 4), xlab = " ", ylab = " ", axes = F, col = "blue")
lines(trendgrowth.ts.sp, lty = 2, col = "red")
abline(h = 0, lty = 2)
title(main ="r* and Trend Growth", line = 0.5, font.main = 3)
box()
axis(4)
axis(1)
legend("bottomleft", legend = c("r*", "Trend Growth (g)"),
bty = "n", lty = c(1,2), col = c("blue", "red"), horiz = F, text.col = "black",
cex = 1, pt.cex = .5, inset = c(0.02, 0.02))
# -------------------------------------- #
# Plot output gap and real rate gap
# -------------------------------------- #
outputgap.ts.sp <- ts(outputgap.sp, frequency = 4, start = c(1978,1), end = c(2018, 1))
realrategap.ts.sp <- ts(realrategap.sp, frequency = 4, start = c(1978,1), end = c(2018, 1))
plot.ts(outputgap.ts.sp, ylim = c(-20, 15), xlab=" ", ylab=" ", axes = F, col="blue")
lines(realrategap.ts.sp, lty = 2, col = "red")
abline(h = 0, lty = 2)
legend("topright", legend = c("Output Gap", "Real Rate Gap"),
bty = "n", lty = c(1,2), col = c("blue", "red"), horiz = F, text.col = "black",
cex = 1, pt.cex = .5, inset = c(0.02, 0.02))
title(main = "Output Gap and Real Rate Gap", line = 0.5, font.main = 3)
box()
axis(side = 4)
axis(side = 1)
How would one specify the years on the x-axis from 1975 to 2020 with jumps of 5 years?
Furthermore, (off-topic) I need two plots next to each other, but I feel that par(mfrow = c(2,2)) is not the correct statement. However, changing it into par(mfrow = c(1,2)) creates abnormal large figures.
Thanks!
The OP has requested to specify the years on the x-axis from 1975 to 2020 with jumps of 5 years.
This can be achieved by
axis(1, at = seq(1975L, 2020L, by = 5L))
However, the result may depend on the mfrow parameter. Here is a a dummy example using par(mfrow = c(2, 2)):
Note that the x-axis of the left graph was created by axis(1) while the x-axis of the right graph was created by axis(1, at = seq(1975L, 2020L, by = 5L)). Also note the large white space below the two graphs.
With par(mfrow = c(1, 2)) the result becomes
Here, the right graph shows unlabeled ("minor") tick marks. This is explained in the mfrow section of ?par: In a layout with exactly two rows and columns the base value of "cex" is reduced by a factor of 0.83. So, font size is reduzed by 17% per cent which allows to label all tick marks without overplotting.

How can I align a photo with a plot in R?

I want to plot in R several panels with data measured along a sediment core (see image below). Next to the plots, I want to add a photo of that sediment core, aligned to the exact y coordinates as the plots (to be able to identify if a certain layer in the photo corresponds to a peak in some element in the plot).
The piece of code below produces de multipanel plot plus the photo (see below as well). As you can see using the tape measure in the photo, the y coordinates of the plots do not match the coordinates of the photo.
op <- par(mfrow = c(1,4), oma = c(5,4,2,0) + 0.1, mar = c(0,0,4,1) + 0.1, pch = 20)
plot(y = -curian3_scores$Sample, x = curian3_scores$RC1, xaxt = "n", type = "o", pch =16, ylab = "", xlab = "", lwd = 1.5, col = "blue", ylim = c(-1197.744, -40), cex.axis = 1.2)
axis(3, cex.axis = 1.2)
mtext(side = 3, text = var.PC1, line = 2.2, cex = 0.9)
mtext(side = 2, text = "Depth (mm)", line = 3, cex = 0.9)
plot(y = -curian3_scores$Sample, x = curian3_scores$RC2, xaxt = "n", yaxt = "n", type = "o", ylab = "", xlab = "", lwd = 1.5, col = "red", ylim = c(-1197.744, -40), cex.axis = 1.2)
axis(3, cex.axis = 1.2)
mtext(side = 3, text = var.PC2, line = 2.2, cex = 0.9)
plot(y = -curian3_scores$Sample, x = curian3_scores$RC3, xaxt = "n", yaxt = "n", type = "o", ylab = "", xlab = "", lwd = 1.5, col = "darkgreen", ylim = c(-1197.744, -40), cex.axis = 1.2)
axis(3, cex.axis = 1.2)
mtext(side = 3, text = var.PC3, line = 2.2, cex = 0.9)
# Charge the image as an R object with the "JPEG" package
library(jpeg)
my_image=readJPEG("~/Documents/FEINA/POSTDOCTORAT/RESILCOAST/ARTICLES/Carbon_persistence/Data_mining/CoreScanner/Core_Images_for_R/CURIAN3a_8.jpg")
# Set up a plot area with no plot
plot(y = -curian3_scores$Sample, x = curian3_scores$RC3, type = "n", axes = F, ylab = "", xlab = "")
# Get the plot information so the image will fill the plot box, and draw it
lim <- par()
rasterImage(my_image, xleft = lim$usr[1], ybottom = lim$usr[3], xright = lim$usr[2], ytop = lim$usr[4])
par(op)
Any ideas to make the photo's and plots' coordinates to match? If the ylim in each plot worked, I think this would be it... however, I think they're overruled for some reason...

Automatically find out proper value of 'pos' for plotting axis labels

In the last line of the example below, I had to manually try a couple of different values for pos before I found the 'correct' value that was just outside of the labels that had already been plotted in the previous line. Is there a way to find out that proper value of pos automatically?
dev.off()
windows(width = 8, height = 6)
par(mai = c(0.3, 2.5, 0.3, 0.3)) #bottom, left, top and right
set.seed(42)
plot(rnorm(15,10,1),rnorm(15,10,1), type = "p",
ylim = c(5,15), xlim = c(5,15), xlab = "", ylab = "",
xaxt = "n", yaxt = "n", yaxs="i", xaxs="i")
axis(2, at = c(5,10,15), labels = c("This one", "Particularly long one", "two"), las = 2)
axis(2, at = 10, pos = 2, labels = "Y Axis Label", font = 2, tick = FALSE, cex.axis = 1.5)
You can grab par(usr)[1] and subtract the strwidth of your long label to get the position:
dev.off()
windows(width = 8, height = 6)
par(mai = c(0.3, 2.5, 0.3, 0.3)) #bottom, left, top and right
set.seed(42)
plot(rnorm(15, 10, 1),rnorm(15, 10, 1), type = "p",
ylim = c(5, 15), xlim = c(5, 15), xlab = "", ylab = "",
xaxt = "n", yaxt = "n", yaxs= "i", xaxs= "i")
axis(2, at = c(5, 10, 15),
labels = c("This one", "Particularly long one", "two"), las = 2)
# get the position based on the long string width and par('usr')[1]
pos <- par('usr')[1] - strwidth("Particularly long one")
axis(2, at = 10, pos = pos,
labels = "Y Axis Label", font = 2, tick = FALSE, cex.axis = 1.5)
Of course, if you resize the image interactively after this, all bets are off.

Misalignment when using "adj" in title() for an R plot

I want to have my titles be above my points in a pdf plot. It seems R thinks my title is wider than my plot area even though I have my right and left plot margins set to zero.
x <- seq(from = 0.1, to = 0.9, by = 0.1)
xtitle <- c("0.1","0.2","0.3","0.4","0.5","0.6","0.7","0.8","0.9")
pdf("testpdfopts.pdf", width = 16)
par(mar = c(0, 0, 1, 0)) # only need margin at top for title
plot(
x,
rep(0.9,length(x)),
xlim = c(0, 1),
ylim = c(0, 1),
cex = 1,
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = ""
)
for (i in 1:length(x)) {
title(xtitle[i],adj=x[i],cex.main=1)
}
dev.off()
Thanks in advance for any assistance
I am sort of confused with what you are trying to do. Maybe I should put my comment into complete code:
x <- seq(from = 0.1, to = 0.9, by = 0.1)
plot(
x,
rep(0.9,length(x)),
xlim = c(0, 1),
ylim = c(0, 1),
cex = 1,
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = ""
)
axis(3, at = 1:9/10)
Is this equivalent to what you aim to achieve?
You can get character labels too:
x <- seq(from = 0.1, to = 0.9, by = 0.1)
plot(
x,
rep(0.9,length(x)),
xlim = c(0, 1),
ylim = c(0, 1),
cex = 1,
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = ""
)
axis(3, at = 1:9/10, labels = letters[1:9])

Plot axis not meeting at origin

Consider the following vector:
q1 <- c(1000000.0, 908364.8, 876009.1, 847892.8, 824808.3, 805416.2, 785266.2, 770997.1, 753908.6, 744599.9, 706777.6, 674659.9, 634654.4, 601440.4, 568259.7, 535361.3, 493679.9, 465526.5, 429766.6, 395244.7, 361483.2, 332136.6, 308574.5, 285500.6, 262166.2 ,237989.0 , 210766.1, 188578.1, 166762.3 , 140399.8 ,114865.5)
Here is the plot:
dev.new(width=10, height=5)
par(xaxs='i',yaxs='i')
plot(q1, type = "l", lty = 1, lwd = 2, col = "green", xaxt = 'n', xlim = c(0,30), bty = "l")
x.ticks = seq(from = 0, to = 30, by = 5)
axis(1, at = x.ticks+1, labels=paste("Year", x.ticks, sep=" "))
For some reason, my x-axis and y-axis are not meeting at (0,0)! I tried fixing this by using par(xaxs='i',yaxs='i'), but it doesn't do the trick in this case?
Any ideas? Thanks!
If you do not specify ylim, R will fit the plot area to the data, not extend the plot to the origin. This will fix it:
plot(q1, type = "l", lty = 1, lwd = 2, col = "green", xaxt = 'n',
xlim = c(0,30), ylim = c(0, max(q1, na.rm = TRUE)), bty = "l")
I wrote the ylim to look for the maximum in q1. You can change it to a fixed value.
Here is the full code I ran to make it work:
q1 <- c(1000000.0, 908364.8, 876009.1, 847892.8, 824808.3, 805416.2,
785266.2, 770997.1, 753908.6, 744599.9, 706777.6, 674659.9,
634654.4, 601440.4, 568259.7, 535361.3, 493679.9, 465526.5,
429766.6, 395244.7, 361483.2, 332136.6, 308574.5, 285500.6,
262166.2 ,237989.0 , 210766.1, 188578.1, 166762.3 , 140399.8 ,114865.5)
dev.new(width=10, height=5)
par(xaxs='i',yaxs='i')
plot(q1, type = "l", lty = 1, lwd = 2, col = "green",
xaxt = 'n', xlim = c(1,30), ylim = c(0, max(q1)), bty = "l")
x.ticks = seq(from = 0, to = 30, by = 5)
axis(1, at = x.ticks + 1, labels=paste("Year", x.ticks, sep=" "))

Resources