ggplot2: Bring one line to the front, but save the colors

前端 未结 4 1010
忘了有多久
忘了有多久 2021-01-04 06:32

Consider the following code:

library(ggplot2)
foo <- data.frame(x=1:10,A=1:10,B=10:1)
ggplot(melt(foo,id.vars=\"x\"),aes(x,value,color=variable))+geom_lin         


        
相关标签:
4条回答
  • 2021-01-04 07:07

    The solution with replotting is fine unless you have reasons to avoid it. I can think of at least two: using alpha (transparency) or performance issues (you need to do it in one run, big data).

    Here's what I propose:

    require(scales)
    # give the desired order here, I just use reverse
    # separate function since we apply it over both levels & colors
    shuffle <- function(x) rev(x)
    foo <- data.frame(x=1:10, A=1:10, B=10:1, C=2.5, D=7.5)
    melt_foo <- melt(foo, id.vars="x") 
    # original plot
    ggplot(melt_foo, aes(x, value, color=variable)) + 
      geom_line(size=5)
    

    enter image description here

    orig_order <- levels(melt_foo$variable)
    new_order <- shuffle(orig_order)
    # grabbing default colours
    orig_colors <- hue_pal()(length(new_order))
    new_colors <- shuffle(orig_colors)
    melt_foo$variable <- factor(melt_foo$variable, levels=new_order)
    # levels _and_ colours reversed, legend appearance stays the same
    ggplot(melt_foo, aes(x, value, color=variable)) + 
      geom_line(size=5) + 
      scale_colour_manual(values=new_colors, labels=orig_order, breaks=orig_order) 
    

    enter image description here

    0 讨论(0)
  • 2021-01-04 07:18

    The order of your A,B inside data.frame(x=1:10,A=1:10,B=10:1) is causing this layering issue because it is drawing A (1:10) first.

    If you use data.frame(x=1:10,A=10:1,B=1:10) is will put the ascending line on top (since B is drawn last).

    0 讨论(0)
  • 2021-01-04 07:23

    Try this,

    last_plot() + aes(group=rev(variable))
    
    0 讨论(0)
  • 2021-01-04 07:33

    Replotting the red line using a subsetted dataframe does the trick.

    library(ggplot2)
    foo <- data.frame(x=1:10,A=1:10,B=10:1)
    require(reshape2)
    fooM <- melt(foo,id.vars="x")
    p<-ggplot()
    p<-p+geom_line(data=fooM[fooM$variable!="A",],aes(x,value,color=variable),size=5)
    p<-p+geom_line(data=fooM[fooM$variable=="A",],aes(x,value,color=variable),size=5)
    p
    

    EDIT: Note that ggplot applies layers sequentially on top of each other - this can be best leveraged when constructing the plot line by line.

    EDIT2: @tonytonov is right that one may want to avoid plotting identical things twice. Modified my answer to plot everything but A the first time, then only A. Result remains the same and is now also compatible with transparency or big data ;)

    0 讨论(0)
提交回复
热议问题