Creating heat maps of single Z variable with scale

In this recipe we will learn how to make a heat map showing the variation in values of one variable (z) along the X and Y axes as a grid of colors, and display a scale alongside.

Getting ready

We are only using the base graphics functions for this recipe. So, just open up the R prompt and type the following code. We will use the sales.csv example dataset for this recipe. So let's first load it:

sales<-read.csv("sales.csv")

We will use the RColorBrewer package for some good color palettes. So let's make sure it's installed and loaded:

install.packages("RColorBrewer")
library(RColorBrewer)

How to do it...

The sales dataset has monthly sales data for four cities. Let's make a heat map with the months along the X axis and the cities on the Y axis:

rownames(sales)<-sales[,1]
sales<-sales[,-1]
data_matrix<-data.matrix(sales)

pal=brewer.pal(7,"YlOrRd")

breaks<-seq(3000,12000,1500)

#Create layout with 1 row and 2 columns (for the heatmap and scale); the heatmap column is 8 times as wide as the scale column

layout(matrix(data=c(1,2), nrow=1, ncol=2), widths=c(8,1),
heights=c(1,1))

#Set margins for the heatmap
par(mar = c(5,10,4,2),oma=c(0.2,0.2,0.2,0.2),mex=0.5)


image(x=1:nrow(data_matrix),y=1:ncol(data_matrix),
z=data_matrix,axes=FALSE,xlab="Month",
ylab="",col=pal[1:(length(breaks)-1)], 
breaks=breaks,main="Sales Heat Map")

axis(1,at=1:nrow(data_matrix),labels=rownames(data_matrix),
col="white",las=1)

axis(2,at=1:ncol(data_matrix),labels=colnames(data_matrix),
col="white",las=1)

abline(h=c(1:ncol(data_matrix))+0.5, 
v=c(1:nrow(data_matrix))+0.5, col="white",lwd=2,xpd=FALSE)

breaks2<-breaks[-length(breaks)]

# Color Scale
par(mar = c(5,1,4,7))
# If you get a figure margins error while running the above code, enlarge the plot device or adjust the margins so that the graph and scale fit within the device.

image(x=1, y=0:length(breaks2),z=t(matrix(breaks2))*1.001,
col=pal[1:length(breaks)-1],axes=FALSE,breaks=breaks,
xlab="", ylab="",xaxt="n")

axis(4,at=0:(length(breaks2)-1), labels=breaks2, col="white",
las=1)

abline(h=c(1:length(breaks2)),col="white",lwd=2,xpd=F)
How to do it...

How it works...

We used a lot of steps and different function calls to create the heat map. Let's go through them one by one to understand how it all works.

Basically, we used the image() function in the base graphics library to create the heat map and its color scale. There is also a heatmap() function and a heatmap.2() function in the gplots package. However, we used image() because it is more flexible for our purpose.

First, we had to format the data in the correct format for image(), which requires that the z parameter be in the form of a matrix. The first column of the sales dataset contains the month names, which we assigned as the rownames. Then we removed the month column from the dataset and cast it as a matrix called data_matrix , containing only numerical values.

We defined breaks as a sequence of values from 3000 up to 12000 with steps of 1500. These values are used to map the sales values to the color scale, where each color denotes values within a certain range. We used the RColorBrewer palette YlOrRd which contains seven warm colors.

We created a graph layout with one row and two columns using the layout() function. The left column for the heat map is eight times as wide as the right column for the color scale and their heights are equal.

We used the image() function to create the heat map. The main argument is z which we set to data_matrix. The x and y arguments take the index of the rows and columns of the matrix respectively. We set the breaks argument to the breaks vector we created earlier and set the col argument to our palette, but with the number of colors one less than the number of breaks. This is a requirement of the image() function.

Note that we suppressed the drawing of the default axes. We used the axis() command to draw the X and Y axes with row and column names respectively as the labels. The abline() function call is used to draw the white lines separating each block of color on the heat map (a bit like gridlines). These lines make the graph look nicer and a bit easier to read.

Finally, we drew the color scale by issuing another image() function call. We first created a subset of breaks, called breaks2, without the last element of breaks. We passed a transpose of a matrix of breaks2 as the z argument to image(). Note that we also multiplied it by 1.001, to create a set of values just above each break so that they are colored appropriately. We used the same breaks and col arguments as the heat map. We added a Y axis on side 4 to mark the break values and also used abline() to draw white horizontal lines to separate the breaks.

There's more...

The preceding code may seem a bit too complicated at first, but if you go through each statement and function call carefully, you will notice that it is just a big block of code with the same building blocks that we have used in earlier recipes. The best way to really understand the recipe and to modify it for your own needs is to change, add, or remove arguments from each function call and see the resulting effects.

See also

In the next few recipes, we will continue using the image() function to make some more types of heat maps.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset