I usually use ggplot2, but in this case I am using the regular image()
function to plot a heatmap of a large data set. I can label all the labels as red, but I want to label the y-axis with text of different colors based on a vector of color definitions that I generate:
grid = structure(c(1:12),.Dim = c(4,3))
labs = c("A","B","C")
image(1:4,1:3,grid,axes=FALSE, xlab="", ylab = "")
#This works but isn't the colors I want
axis(2,at=1:length(labs),labels=labs,las=2, adj=1,cex.axis=0.6,col.axis="red")
That generates the following image:
I would like labels A and C to be black and B to be red. This is what I tried, but it gives a "wrong length" error...
axiscolors = c("black","red","black")
axis(2,at=1:length(labs),labels=labs,las=2, adj=1, cex.axis=0.6, col.axis=axiscolors)
This is the effect I am after with some "real" data...
EDIT:
As a back-up, if this is possible in ggplot2, I might be willing to re-factor my code. There are a couple other applications I would use this for as well.
I figured out a way to plot a layer of red symbols over the top of the old labels, but would prefer a native method with the color vector, if possible...
sublabs = c("B")
axis(2,at=match(sublabs,labs),labels=sublabs,las=2, adj=1, cex.axis=0.6, col.axis="red")
Another way would be to use text()
if I could put the labels outside the plot space...
text(c(1,1,1),c(1,2,3),labs,col=c("black","red","black"))
UPDATE: See below for a solution that works with ggplot2
...
You can create custom axes using the axis( ) function. axis(side, at=, labels=, pos=, lty=, col=, las=, tck=, ...) the coordinate at which the axis line is to be drawn. If you are going to create a custom axis, you should suppress the axis automatically generated by your high level plotting function.
To set labels for X and Y axes in R plot, call plot() function and along with the data to be plot, pass required string values for the X and Y axes labels to the “xlab” and “ylab” parameters respectively. By default X-axis label is set to “x”, and Y-axis label is set to “y”.
Changing axis labels To alter the labels on the axis, add the code +labs(y= "y axis name", x = "x axis name") to your line of basic ggplot code. Note: You can also use +labs(title = "Title") which is equivalent to ggtitle .
If you ignore the vectorised possibilities like text
and mtext
, you can get there by repeatedly calling axis
. The overhead timewise will be very minimal and it will allow all the axis
calculations to occur as they normally do. E.g.:
# original code
grid = structure(c(1:12),.Dim = c(4,3))
labs = c("A","B","C")
image(1:4,1:3,grid,axes=FALSE, xlab="", ylab = "")
axiscolors = c("black","red","black")
# new code
Map(axis, side=2, at=1:3, col.axis=axiscolors, labels=labs, lwd=0, las=1)
axis(2,at=1:3,labels=FALSE)
Resulting in:
Accepting @thelatemail's answer as the most flexible, but it also turns out to be pretty simple using text()
if you add xpd = TRUE
to allow plotting outside the frame. Using mtext()
can also work, but it doesn't allow you to rotate labels.
grid = structure(c(1:20),.Dim = c(4,5))
labs = c("A","B","C","D","E")
redlabs = c("B","D")
colorlist = c("black","red")
# one of many ways to generate the color labels
axiscolor = colorlist[labs %in% redlabs +1 ]
image(1:4,1:5,grid,axes=FALSE, xlab="", ylab = "")
axis(2,at=1:length(labs),labels=FALSE)
# This would work for sideways labels
# mtext(text=labs, side=2,at=1:length(labs),col=axiscolor,adj=.5)
text(labels=labs, col=axiscolor, x=rep(.45,length(labs)), y=1:length(labs), srt = 0, pos = 2, xpd = TRUE)
UPDATE for ggplot2: You can use theme()
and element_text
to set the colors and other parameters. Something like this...
p + theme(axis.text.y = element_text(color=axiscolor))
You could specify a vector with the colors you want to apply to the labels and then use a loop to get the labels colored with axis(). In the following example, I use a different color for each level of a dot chart.
DF <- data.frame(habitat=c("Hab 1","Hab 2","Hab 3","Hab 4","Hab 5"), mean=c(0.53,0.28,0.30,0.35,0.39), color=colors()[c(24,257,26,504,652)])
> DF
habitat mean color
1 Hab 1 0.53 black
2 Hab 2 0.28 green3
3 Hab 3 0.30 blue
4 Hab 4 0.35 orangered1
5 Hab 5 0.39 yellow
par(mar=c(7, 5, 4, 3))
dotchart(DF[,2], xlim=c(0.2,0.6), col=as.character(DF$color), pch=16, lcolor="white", xlab=colnames(DF[2])) # Plot the points
for (j in 1:5){
axis(side=2, at=j, col.axis=as.character(DF$color)[j], labels=DF$habitat[j], las=1) # Add habitat as labels, each with corresponding color, on the left margin
}
I like very much thelatemail's approach, and can only add a small refinement since the fixed "at" positions (as in the example above with at = 1:3
) didn't work well for me. In my case, I needed to generate a barplot and provided my own values for space and width parameters. In the end what I used looks like (example with random data in which I wanted the bars and labels for positive (non-negative, to be more precise) data values to be green and red otherwise. For this example I also use the letters
function to provide labels and rotate the labels using las = 2
):
x <- rnorm(26)
color <- rep("green", length(x))
color[x < 0] <- "red"
par(mar=c(6,4.1,4.1,2.1))
barplot(x, las = 2, ylim = c(min(x)-0.5, max(x)+0.5), col = color, space = 0.5, width = 2)
Map(function(x,y,z)
axis(1,at=x,col.axis=y,labels=z,lwd=0,las=2),
seq(from = 2, by = 3, length.out = length(x)),
color,
letters
)
axis(1,at=seq(from = 2, by = 3, length.out = length(x)),labels=FALSE)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With