Search code examples
rplotcolors

How do you use two different palettes within the same base R plot while assigning colors by group within that palette?


I'm trying to plot a simple scatterplot in base R. I am plotting x = elongation_time against y = fluorescence. I have two different groupings: one is strain, and the other is cit. I'm trying to use two different palettes for the two different strains, and have each cit have its own color within that palette.

I've approached this problem by separating the two different strains into separate dataframes (NMmedians and cit20medians) in the hopes of assigning a different palette to each of them by plotting the points sequentially:

#defining my two palettes:
darkcols <- c(cit0 = "#1548E0", cit3 = "#008F00", cit6 = "#CCAD00", cit9 = "#B85C00", citMax =  "#B80000", citMin = "#8F008F") #for normalized
cols  <-    c(cit0 = "royalblue2", cit3 = "green3", cit6 = "gold1", cit9 = "darkorange2", citMax = "red2", citMin = "magenta3") #for WT

palette = cols

pdf("20citvsNMwt.pdf", width = 2, height = 1.67, pointsize = 7, useDingbats = F, bg = "white" )
# sets margin stuff:
par( mex = 0.65 ) 
par( mar = c(7,6.5,4,3) )
par( oma = c(0,0.5,1,0) )

#first plotting one strain (works as intended)
plot( NMmedians$elongation_time, NMmedians$ratio, 
      col = as.factor(NMmedians$cit),
      pch = 20,
      #cex = 0.6,
      axes = F,
      xlim = c(150,400),
      ylim = c(0,1),
      xlab = "",
      ylab = "fluorescence"
)

#now trying to plot the other strain, the col parameter is where I've been focusing my efforts:
points(cit20medians$elongation_time, cit20medians$ratio, 
 pch = 20, 
 col = list(darkcols, as.factor(cit20medians$cit))
 )

axis( 1 )
axis( 2 )
title( xlab = "elongation time", line = 4.5 )

dev.off()

here is the graph when I just use col = as.factor(cit20medians$cit) which doesn't change the palette for the second set of points

I've been successful in getting it to use the darkcol palette for the second set of points by just doing col = darkcols, but it doesn't retain the correspondance to each 'cit': here it is with both palettes, but darkcols at random

To emphasize: pictorally, the goal here is to have each set of points rainbow going along the X axis according to which cit they belong to, and either lighter or darker along the Y axis according to which strain they belong to.


Solution

  • I think it's a matter of indexing the names of your colour vectors appropriately. Here's a simpler representative example:

    nms <- names(cols)
    NM <- data.frame(value=1:6, cit=nms)
    c20 <- data.frame(value=2:7, cit=nms)
    

    The code is then:

    plot(NM$value, col=cols[NM$cit], pch=19, cex=2, ylim=c(0,7))
    points(c20$value, col=darkcols[c20$cit], pch=19, cex=2)
    

    As an aside, you can change the cols to darkcols programmatically too:

    plot(NM$value, col=cols[NM$cit], pch=19, cex=2, ylim=c(0,7))
    darkcols <- setNames(adjustcolor(cols, red.f=0.7, green.f=0.7, blue.f=0.7), names(cols))
    points(c20$value, col=darkcols[c20$cit], pch=19, cex=2)