-3

I have a ggplot and I have geom_text to paste column values on the plot. I actually pasted multiple columns on my plot. Is it possible to differentiate the columns based on colour?

df <- data.frame(YearMonth = c(200606,200606,200608,200701,200703,200605),
             person1 = c('Alice','Bob','Alice','Alice','Bob','Alice'),
             person2 = c('Bob','Alice','Bob','Bob','Alice','Bob'),
             Event = c('event1','event2','event3','event3','event2','event4')
             )

df$YM <- as.Date(paste0("01",df$YearMonth), format="%d%Y%m")
rangeYM <- range(df$YM)
ypts <- rep_len(c(-1,1), length.out=nrow(df))

Below is the code I have used for plotting.

ggplot()+geom_blank(aes(x= rangeYM, y = c(-1,1))) + labs(x = "", y = "") +
theme(axis.ticks = element_blank()) +
geom_hline(yintercept = 0, col = 'maroon') +
geom_segment(aes(x = df$YM, y = 0, xend = df$YM, yend = ypts), arrow = arrow(length = unit(0.2,"cm"))) +
scale_x_date(date_labels = '%b-%y', date_breaks = "month", minor_breaks = NULL) +
scale_y_continuous(minor_breaks = NULL) +
geom_text(aes(x = df$YM, y = 0, label = paste(format(df$YM, "%b-%y")), vjust = 1.5), colour = "#5B7FA3", size = 3, fontface = "bold") +
geom_text(aes(x = df$YM, y = ypts, label = paste(df$person1,df$person2,df$Event,sep="\n")))

As it can be seen from the dataframe person1, person2,Event are columns and are represented in same colour. I tried to assign different colour by including colour in aes of geom_text as below.

geom_text(aes(x = df$YM, y = c(-1,1), label = paste(df$person1,df$person2,df$Event,sep="\n"), colour = factor(df$person1,df$person2,df$Event)))

But this gives me an error. If I include one column in factor i.e colour = factor(df$Person1) then it assigns different colours to values of Person1 column. But I want the colour to be differentiated based on columns as I am pasting multiple columns in the plot.

Please help if there is an option to do so.

mockash
  • 1,204
  • 5
  • 14
  • 26
  • 2
    I'm not sure what data frame from "there" you are talking about. I certainly dont see an easy way to create one via simple cut and paste, and I'm not pasting in a text table and then figuring out the correct read.csv syntax. Please include your data as the output from `dput` or give code that creates it. – Spacedman Dec 29 '16 at 08:12
  • 1
    I tried to reproduce your plot but I do get an error message saying _Error: Aesthetics must be either length 1 or the same as the data (6): x, y_ from `ggplot2` version 2.2.0 – Uwe Dec 29 '16 at 09:11
  • 1
    Does your first plotting code above actually work? Because I get "Error: Aesthetics must be either length 1 or the same as the data (6): x, y" because of the `c(-1,1)`. Are you trying to draw Person1 at YM,1 and Person2 and YM,-1? – Spacedman Dec 29 '16 at 09:13
  • Actually now I see the problem. Where on the `y` axis do you want the text to appear? – Spacedman Dec 29 '16 at 09:16
  • 1
    In your Q, you are using different ways of writing variable names, e.g. `person1` and `Person1`. – Uwe Dec 29 '16 at 09:23
  • 2
    As a courtesy to those who are willing to spent time in answering your questions you should have tested your "working" example before posting. – Uwe Dec 29 '16 at 09:36
  • @UweBlock Agree my mistake I was actually trying out different ways to figure out and may be pasted the wrong line. – mockash Dec 29 '16 at 09:41

1 Answers1

2

I guess in this case it's easiest to just use seperate geoms.

Also, I strongly recommend that you pass data.frames to the data argument, instead of using objects in the global environment or $ notation within the aes. In my experience, this tends to bite you in the behind at some point or another and is bad practice.

ggplot()+geom_blank(aes(x= rangeYM, y = c(-1,1))) + labs(x = "", y = "") +
  theme(axis.ticks = element_blank()) +
  geom_hline(yintercept = 0, col = 'maroon') +
  geom_segment(aes(x = df$YM, y = 0, xend = df$YM, yend = ypts), arrow = arrow(length = unit(0.2,"cm"))) +
  scale_x_date(date_labels = '%b-%y', date_breaks = "month", minor_breaks = NULL) +
  scale_y_continuous(minor_breaks = NULL) +
  geom_text(aes(x = df$YM, y = 0, label = paste(format(df$YM, "%b-%y")), vjust = 1.5), colour = "#5B7FA3", size = 3, fontface = "bold") +
  geom_text(aes(x = YM, y = ypts, label = person1), df, col = 'red', nudge_y = .1) +
  geom_text(aes(x = YM, y = ypts, label = person2), df, col = 'darkgreen') +
  geom_text(aes(x = YM, y = ypts, label = Event), df, col = 'blue', nudge_y = -.1)

enter image description here

Axeman
  • 32,068
  • 8
  • 81
  • 94
  • This is exactly what I was looking at. But is there any way to get it in single geom? because I actually wanted to plot lot of columns in my original dataframe. and thanks for your advise. – mockash Dec 29 '16 at 09:35
  • No. By design, `ggplot2` maps _single_ variables to aesthetics. You could reshape your data, but you'll have to recalculate the y-values. – Axeman Dec 29 '16 at 09:37
  • @Axeman: Don't you want to polish up the code to demonstrate best practice? – Uwe Dec 29 '16 at 09:39