简体   繁体   中英

How to conditionally adjusting colour for multiple geom_segment ggplot?

I'm trying to set the colours conditionally in a geom_segment plot within ggplot. I can get a gradient to the colours but not set each segment to a colour of my choosing based on the type of comment in another cell.

Data:

START<-as.POSIXct(c("2017-07-13 01:40:00 MDT", "2017-07-21 06:00:00 MDT", "2017-07-21 14:00:00 MDT", "2017-07-24 11:00:00 MDT",
                  "2017-07-24 12:00:00 MDT", "2017-07-25 05:00:00 MDT", "2017-07-25 17:00:00 MDT", "2017-07-26 12:00:00 MDT",
                  "2017-07-30 12:00:00 MDT", "2017-07-31 04:00:00 MDT", "2017-07-31 15:00:00 MDT", "2017-08-03 18:30:00 MDT",
                  "2017-08-03 23:30:00 MDT", "2017-08-09 05:00:00 MDT", "2017-08-09 20:00:00 MDT", "2017-08-14 09:00:00 MDT",
                  "2017-08-16 05:00:00 MDT", "2017-08-16 07:00:00 MDT", "2017-08-16 19:00:00 MDT", "2017-08-17 18:00:00 MDT",
                  "2017-08-20 05:00:00 MDT", "2017-08-23 06:00:00 MDT", "2017-08-23 14:00:00 MDT", "2017-08-24 17:00:00 MDT",
                  "2017-08-28 00:00:00 MDT"))

 END<-as.POSIXct(c("2017-07-21 06:00:00 MDT", "2017-07-21 14:00:00 MDT", "2017-07-24 11:00:00 MDT", "2017-07-24 12:00:00 MDT",
                "2017-07-25 05:00:00 MDT", "2017-07-25 17:00:00 MDT", "2017-07-26 12:00:00 MDT", "2017-07-30 12:00:00 MDT",
                "2017-07-31 04:00:00 MDT", "2017-07-31 15:00:00 MDT", "2017-08-03 18:30:00 MDT", "2017-08-03 23:30:00 MDT",
                "2017-08-09 05:00:00 MDT", "2017-08-09 20:00:00 MDT", "2017-08-14 09:00:00 MDT", "2017-08-16 05:00:00 MDT",
                "2017-08-16 07:00:00 MDT", "2017-08-16 19:00:00 MDT", "2017-08-17 18:00:00 MDT", "2017-08-20 05:00:00 MDT",
                "2017-08-23 06:00:00 MDT", "2017-08-23 14:00:00 MDT", "2017-08-24 17:00:00 MDT", "2017-08-28 00:00:00 MDT",
                "2017-09-28 13:00:00 MDT"))

 RATE<-c(1485, 0, 1485,  880, 1485, 0, 1485, 1100, 1485, 0, 1485, 1483, 1485, 0, 1485, 1419, 880, 0, 1419, 1485, 1419, 0, 1100, 419, 1100)

 Comms<-c("", "Issue-asdfa", "asfdaf",  "Issue-asdfa", "asfdaf","", "Issue-asdfa", "asfdaf",  "Issue-asdfa", "asfdaf", "", "Issue-asdfa", "asfdaf",  "Issue-asdfa", "asfdaf","", "Issue-asdfa", "asfdaf",  "Issue-asdfa", "asfdaf", "asfdaf","", "Issue-asdfa", "asfdaf",  "Issue-asdfa")

DF<-data.frame(START, END, RATE, Comms)

Functions to tell what type of comment and the colour to set that segment too are:

WhatisCommentType <- function(SchComment) {
CommentType = 0
if (grepl("Issue", SchComment)) {
  CommentType = 2
} ## 2 is when there is maintenance 

if (grepl("Issue", SchComment) == FALSE & (SchComment!="")) {
  CommentType = 1
} ## 1 is when there is a comment and it's not a Issue

if (SchComment=="") {
  CommentType = 0
} ## 0 is when there is no comment

return(CommentType)

}#end WhatisCommentType funciton 


WhatisCommentTypecolour <- function(SchComment) {
CommentTypecolour = "dodgerblue4" #"#045a8d" #
if (grepl("Issue", SchComment)) {
  CommentTypecolour = "firebrick1" #f03b20" #firebrick1"
} ## 2 is when there is maintenance 

if (grepl("Issue", SchComment) == FALSE & (SchComment!="")) {
  CommentTypecolour = "darkorange3" # "#d95f0e" #
} ## 1 is when there is a comment and it's not a Issue

if (SchComment=="") {
  CommentTypecolour = "dodgerblue4" #"#045a8d" #"dodgerblue4"
} ## 0 is when there is no comment

return(CommentTypecolour)

}#end WhatisCommentType funciton 

Setup the data to be plotted:

#Comment colouring type
DF$CommentType<-unlist(lapply(DF$Comms, WhatisCommentType))
DF$CommentTypecolour<-unlist(lapply(DF$Comms, WhatisCommentTypecolour))


ym1 <- as.yearmon(min(DF$START)) # convert to yearmon
ym2 <- as.yearmon(max(DF$END)) # ditto
ListStartOfMonthDates <- seq(ym1, ym2, 1/12)
ListStartOfMonthDates <- as.Date(paste('01',  ListStartOfMonthDates), format='%d %b %Y') 
lower <-  as.POSIXct(strptime(paste(ListStartOfMonthDates[1], "01:00"), "%Y-%m-%d %H:%M"))
upper <- max(DF$END)
limits = c(lower,upper)
ListStartOfMonthDates <- as.POSIXct(strptime(paste(ListStartOfMonthDates, "07:00"), "%Y-%m-%d %H:%M"))

  ggplot(DF)+
    geom_segment(aes(x=as.POSIXct(as.character(START)),
                 xend=as.POSIXct(as.character(END)),
                 y=RATE,
                 yend=RATE,
                 colour=CommentType), size=2)+
    scale_colour_manual(name="",
                      # labels map onto colors and pretty labels
                      values=c("0"="dodgerblue4",
                               "1"="firebrick1",
                               "2"="firebrick1"),
                      labels=c("0"="No Comment",
                               "1"="copas",
                               "2"="Non-copas Commet")) 

Getting the following error.

Error: Continuous value supplied to discrete scale

I was playing around with these other posts to see if I could get it working.

matching legend items and colours in ggplot2 where some geom_segment are not included in legend

Colours in ggplot (geom_segment)

Any ideas how I could get this plot to generate correctly?

scale_colour_manual creates a scale with discrete values, ex. A, B and C. You're getting this error because the variable “CommentType” is actually being considered a continuous variable.

I think the reason for this is that you assign numeric value to it:

(SchComment=="") {
  CommentType = 0
} ## 0 is when there is no comment

If you instead assign a string or factor value to it, then ggplot2 should recognize that it is a discrete value and work correctly.

(SchComment=="") {
  CommentType = "0"
} ## 0 is when there is no comment

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM