Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot legend order mismatch

Tags:

r

legend

ggplot2

I'm a newbie to R/ggplot, and I have surveyed StackOverflow for similar problems, to no avail. It is probably a trivial problem for the ggplot experts in the house, if so, I look forward to a quick answer!

So here goes: I am trying to plot 4 curves from variables stored in a dataframe, playng with both color and linetype. Unfortunately the legend labels are mismatched to the curves, which defeats the whole purpose of a legend.

Here is the figure: 4 curves with mismatched labels

And here is the code that generated it:

# declare variables
alpha = 0.5
m = 500
x = seq(m)
fdr_thresh = x/m*alpha
lvl_thresh = rep(alpha,m)
pvals = sin(2*pi*x/20)
pvalsA = exp(-x/100)*cos(2*pi*x/20)

# plot
df <- data.frame(pvals=pvals, pvalsA = pvalsA, FDR = fdr_thresh, level = lvl_thresh, x=x)
p4 <- ggplot(data = df) + geom_line(aes(x=x, y=pvals,color="Pure Sinusoid",linetype="Pure Sinusoid"))
p4 <- p4 + geom_line(aes(x=x, y=pvalsA,color="Damped Sinusoid",linetype="Damped Sinusoid"))
p4 <- p4 + geom_line(aes(x=x, y=FDR,color = 'FDR', linetype='FDR')) 
p4 <- p4 + geom_line(aes(x=x, y=level,color='alpha',linetype='alpha'))  
p4 = p4+ scale_linetype_manual(name = "Significance", values=c("Pure Sinusoid"= 1,"Damped Sinusoid" = 1,"FDR" = 2,"alpha" = 3),labels=c("Pure Sinusoid", "Damped Sinusoid", "Sloping line",bquote(alpha == .(alpha))))
p4 = p4 + scale_color_manual(name = "Significance",values=c("Pure Sinusoid"= "Chocolate1","Damped Sinusoid" = 'Chartreuse4',"FDR" = "black","alpha" = "black") , labels=c("Pure Sinusoid", "Damped Sinusoid", "Sloping line",bquote(alpha == .(alpha))))
p4 <- p4 +  theme(legend.position = c(0.7, 0.8),legend.title=element_blank(),legend.key = element_rect(fill = "transparent",colour = "transparent"),legend.background = element_rect(fill=alpha('white', 0.8)))
show(p4)

I would be most grateful for a tip on how to do this better. The same plot in Matlab or Python would be correct and have taken 15 minutes, so I must have made a wrong decision somewhere. (and no, choosing R was not that decision: this is part of my effort to learn it)

like image 870
El Niño Avatar asked Jul 27 '26 14:07

El Niño


1 Answers

The "right way" to do this is to melt your data set into one long data frame and then let ggplot take care of plotting the multiple lines for you, rather than issuing separate geom_line() calls ...

# plot
df <- data.frame(pvals, pvalsA, FDR = fdr_thresh, level = lvl_thresh, x)

mm <- reshape2::melt(df,id.var="x")
my.labs <- c("Pure Sinusoid","Damped Sinusoid","Sloping line",
           bquote(alpha==.(alpha)))
p4 <- ggplot(data = mm, aes(x,value,colour=variable,linetype=variable)) +
    geom_line()
p4 <- p4 + scale_linetype_manual(name="Significance",values=c(1,1,2,3),
          labels=my.labs)
p4 <- p4 + scale_color_manual(name = "Significance",
                  values=c("Chocolate1",'Chartreuse4',"black","black"),
                  labels=my.labs)
p4 <- p4 +  theme(legend.position = c(0.7, 0.8),
                  legend.title=element_blank(),
                  legend.key = element_rect(fill = "transparent",
                                            colour = "transparent"),
          legend.background = element_rect(fill=alpha('white', 0.8)))
show(p4)

enter image description here

(I already had theme_bw() set in the R session I was working in, which is why the gray background/grid lines are missing ...)

like image 189
Ben Bolker Avatar answered Jul 30 '26 07:07

Ben Bolker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!