Reputation: 85
I created six heatmaps with R base graphics using the image()
function. They show depth on the y-axis and time along the x-axis. The z values are temperatures. Additionally you can see some contour lines with labels indicating temperature in °C.
As each plot comes from a different data frame with a slightly different temperature range, I had to ensure the same colours are used to display temperature in a consistent way. Therefore I customised a colour scale
cols
showing low temperatures towards the blue end and high temperatures at the red end. For each of the six data frames, I aligned their min and max temperatures at predefined max and min values of cols
. See below the code exemplary for the upperleft data frame RW1-iBA.
# Customise colour scale
RColorBrewer::display.brewer.all()
cols = rev(colorRampPalette(RColorBrewer::brewer.pal(11,"RdYlBu"))(2000))
# Define temperature range for cols
min.cols.temp <- -23
max.cols.temp <- 23
# Define min and max temperatures for RW1-iBA
max_temp <- max(RW1_iBA$temp)
min_temp <- min(RW1_iBA$temp)
# Align RW1-iBA along cols
lowerend.RW1_iBA <- round(min_temp/min.cols.temp*1000)
upperend.RW1_iBA <- round(max_temp/max.cols.temp*1000)
trunc.low.RW1_iBA <- 1000-lowerend.RW1_iBA
trunc.upp.RW1_iBA <- 1001+upperend.RW1_iBA
col.RW1_iBA <- cols[-c(1:trunc.low.RW1_iBA, trunc.upp.RW1_iBA:2000)]
What I did here is basically setting upper and lower ends of cols
to 23 and -23, respectively, making sure these values represent the full range of temperatures for all data frames. Then, I aligned temperature values for each data frame individually along the colour scale by cutting out parts of cols
that exceed the data frame's max and fall short of its min temperature value, respectively. This gives me six different colour scales (above: col.RW1_iBA
) that I used for plotting each data frame individually.
What I am missing now is cols
added to the plot as a legend. The scale itself looks like this:
plot(rep(1, 2000), col = cols, pch = 16)
I set up the six plots above with a layout matrix as follows:
layoutMatrix
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 7
[3,] 3 6 7
Spots 1 to 6 are occupied by the six plots you can see above. The margin for column 3 (containing "plot" 7) is already set smaller and I would like to add cols
as a legend vertically in it. At best it has tick marks and lables for temperature values 20, 10, 0, -10, -20 and a heading like Temperatures (°C). Any idea how I can do this?
Upvotes: 0
Views: 530
Reputation: 1255
Here is a piece of code that may help:
mat = cbind(1:3, 4:6, 7)
layout(mat, width = c(1,1,.25))
pal = colorRampPalette(c("white", "black"))(100)
# empty plots
for (i in 1:6) image(matrix(runif(100), 10), col = pal)
# color scale
par(las=1, mar = c(4, 1, 4, 5))
image(t(1:100), col = pal, axes = F, ann = F)
axis(4)
par(las=0)
mtext(4, text = "new_ylab", line = 3)
You may have to tweak the margins!
Upvotes: 1
Reputation: 85
Okay, figured it out with the help of this post that uses a customised function to plot scales. I just had to remove the dev.new()
call to avoid plotting the colour scale in a new device. The function is flexible but you still need to play around with the par(mar = c())
parameter to adjust width and height of the vertical bar.
Upvotes: 0