Vary colors of axis labels in R based on another variable

后端 未结 4 922
青春惊慌失措
青春惊慌失措 2020-12-09 11:33

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 re

相关标签:
4条回答
  • 2020-12-09 11:49

    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)
    
    0 讨论(0)
  • 2020-12-09 11:52

    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)
    

    Solution using text()

    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)) 
    
    0 讨论(0)
  • 2020-12-09 11:53

    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
    } 
    
    0 讨论(0)
  • 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:

    enter image description here

    0 讨论(0)
提交回复
热议问题