In this recipe, we will make a heat map that shows the variation in values of one variable (z
) along the x and y axes as a grid of colors and display a scale alongside.
We will only use the base graphics functions for this recipe. So, just open up the R prompt and type in 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 that it's installed and loaded:
install.packages("RColorBrewer") library(RColorBrewer)
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)
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 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 the 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.
The preceding code might 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 used in earlier recipes in the book. 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.
3.144.28.177