13

I have some data that I am using to plot a histogram. I also have two sets of thresholds that have some significance.

I am able to plot the histogram and the vlines with the appropriate styles. However, I cannot get my vlines to show up in the legend. I believe that something like this should work, however the legend items don't ever display.

df <- data.frame(val=rnorm(300, 75, 10))

cuts1 <- c(43, 70, 90)
cuts2 <- c(46, 79, 86)

ggplot(data=df, aes(x=val)) +
  geom_histogram() +
  geom_vline(xintercept=cuts1,
             linetype=1,
             color="red",
             labels="Thresholds A",
             show_guide=TRUE) +
  geom_vline(xintercept=cuts2,
             linetype=2,
             color="green",
             labels="Thresholds B",
             show_guide=TRUE)

Alternatively, if I construct a data.frame for my cuts and do an aesthetic mapping, I can get my vlines to show up in the legend. Unfortunately, the legend gives me two instances of the different line types superimposed on each other:

cuts1 <- data.frame(Thresholds="Thresholds A", vals=c(43, 70, 90))
cuts2 <- data.frame(Thresholds="Thresholds B", vals=cuts2 <- c(46, 79, 86))

ggplot(data=df, aes(x=val)) +
  geom_histogram() +
  geom_vline(data=cuts1, aes(xintercept=vals, shape=Thresholds),
             linetype=1,
             color="red",
             labels="Thresholds A",
             show_guide=TRUE) +
  geom_vline(data=cuts2, aes(xintercept=vals, shape=Thresholds),
             linetype=2,
             color="green",
             labels="Thresholds B",
             show_guide=TRUE)

enter image description here

So, in the end, what I'm looking for, is the most straightforward way to manually add two sets of lines to a plot, and then have them appear correctly in the legend.

Peter
  • 4,219
  • 4
  • 28
  • 40

1 Answers1

24

The trick is to put the threshold data all in the same data frame, and then map aesthetics, rather than set them:

cuts <- rbind(cuts1,cuts2)

ggplot(data=df, aes(x=val)) +
  geom_histogram() +
  geom_vline(data=cuts, 
             aes(xintercept=vals, 
                 linetype=Thresholds,
                 colour = Thresholds),
             show_guide = TRUE)

enter image description here

joran
  • 169,992
  • 32
  • 429
  • 468
  • Thanks for posting. I tried to use above codes but the figure didn't apprear. Only the first graph part works but no the geom_vline part. I'm wondering if there are others trick? What I did :y <- ggplot(sf,aes(date,value)) + geom_line(aes(group=variable,color=variable)) and x <- geom_vline(data=sfs,aes(xintercept=date,linetype=type),show.legend=TRUE), but when y+x I got error: Error in UseMethod("rescale") : no applicable method for 'rescale' applied to an object of class "character" In addition: Warning message: Removed 33 rows containing missing values (geom_path). Any thoughts?Thx! – ponyhd Mar 31 '20 at 23:16