2

Is it possible to used ggplot to color points based on predefinded standard color codes contained in the data frame?

Below is some sample data and code to help articulate my question.

tick  <- c("GE","APPL","GM","BTU","WMT","JPM","LUV")
price <- c(22,900,20,22,80,31,35)
volume<- c(300,500,100,107,400,300,325)
df1 <- data.frame(ticker=tick, price=price, volume=volume)

#  Here is a sample chart without colors:
p <- ggplot(df1, aes(volume, price))+ 
  geom_point();
p

#  I could use astetics and color_brewer to color points by ticker.
#  But since I want to have my colors uniform across multiple plots 
#  outside of this script, I have specified the colors to always 
#  be used for certian tickers   

## color speciciations
## http://wiki.stdout.org/rcookbook/Graphs/Colors%20(ggplot2)/#rcolorbrewer-palette-chart 

tick<-c("GE","APPL","GM","BTU","WMT")
ccodes<-c("#3399FF", "#FF000", "#CC00FF", "#993300", "#66CC00")
cnames<-c("blue", "red", "purple", "brown", "green")
df2=data.frame(ticker=tick, color.codes=ccodes, color.names=cnames)

## merge color specifcations into data
df3 <-merge(df1,df2, by=("ticker"), all.x=TRUE, all.y=TRUE)

# since I wont be able to specify colors for all the data will be 
# be plotting I need to speficy a default color, in this case black.
# this is where I start to run into trouble.  For some reason the 
# following line dosent work as i would have intended as it dosent
# correctly bring back the defined colors.
df3$color.code.new <- ifelse(is.na(df3$color.codes), "#000000", df3$color.codes) 

# Once that is corrected, I would like to use the new color codes
# in df3 as the colors of the points.
p <- ggplot(df3, aes(volume, price))+ 
  geom_point(); 
p

Any guidance would be greatly appreciated.

#####################################################################
#####  Edit below  - to test
#####################################################################
ccodes<-c("#990000", "#990000", "#990000", "#990000", "#990000")
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
MikeTP
  • 7,716
  • 16
  • 44
  • 57

1 Answers1

5

The line you claimed didn't work:

df3$color.code.new <- ifelse(is.na(df3$color.codes), "#000000", df3$color.codes)

works for me, although I think you missed a digit in one of your hex colors. Once you have that straightened out, you just want to use scale_colour_manual with something like this:

tick  <- c("GE","APPL","GM","BTU","WMT","JPM","LUV")
price <- c(22,900,20,22,80,31,35)
volume<- c(300,500,100,107,400,300,325)
df1 <- data.frame(ticker=tick, price=price, volume=volume)

tick<-c("GE","APPL","GM","BTU","WMT")
ccodes<-c("#3399FF", "#FF0000", "#CC00FF", "#993300", "#66CC00")
cnames<-c("blue", "red", "purple", "brown", "green")
df2=data.frame(ticker=tick, color.codes=ccodes, color.names=cnames)

## merge color specifcations into data
df3 <-merge(df1,df2, by=("ticker"), all.x=TRUE, all.y=TRUE)
df3$color.code.new <- ifelse(is.na(df3$color.codes), "#000000", df3$color.codes) 

p <- ggplot(df3, aes(volume, price,colour = ticker))+ 
         geom_point() 
p + scale_colour_manual(breaks = df3$ticker,values = df3$color.code.new)

enter image description here

joran
  • 169,992
  • 32
  • 429
  • 468
  • thank you. For some reason when i run the line to establish defaults, I get: "5" "3" "1" "4" "#000000" "#000000" "2" which is fine for the defaults, but not the predefined colors. – MikeTP Mar 22 '12 at 17:47
  • 1
    @MikeTP Ah, probably because it's a factor. (I typically set `options(stringsAsFactors = FALSE)`). Try `as.character(df3$color.codes)` instead. – joran Mar 22 '12 at 17:50
  • Thanks...still not working as expected as it seems to return default colors instead of defined. I went back and changed all the color codes to something simple (see edit above) to make sure I didnt have any errors In my hex. – MikeTP Mar 22 '12 at 18:05
  • ps the "as.character(df3$color.codes)" suggestion did fix that error – MikeTP Mar 22 '12 at 18:08
  • @MikeTP Not sure what the problem could be w/out more info. I edited my answer to include the complete code I ran and the output, which seems to work correctly for me. – joran Mar 22 '12 at 21:55