简体   繁体   中英

ggplot2- geom_linerange with stat_smooth

Oh wise ones: I've got a question about the use of geom_linerange(), attached is what I hope is a workable example to illustrate my problem.

b=c(100,110,90,100,120,130,170,150,150,120,140,150,120,90,90,100,40,50,40,40,20,60,30)
test<-data.frame(a=c(2,2,2,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,10,10,10,10),
                 b=b,c=c(b-15))

testMelt <- melt(
  test, 
  id       = c("a"), 
  measured = c("b", "c")
  )


p <- ggplot(
  aes(
    x    = factor(a), 
    y    = value,
    fill= variable
    ),      
   data  = testMelt) + 
    geom_boxplot() + 
          stat_smooth(aes(group=variable,x=factor(a),y=value,fill=factor(variable)),data=testMelt)

My actual dataset is much larger, and the boxplots are a bit overwhelming. I think what I want is to use geom_linerange() somehow to show the range of the data, at "b" and "c", at each value of "a".

The best I've come up with is:

p<- p+ geom_linerange(aes(as.factor(a),ymin=min(value),ymax=value,color=variable))

I can assume the "c" values are always equal to or less than "b", but if the range is smaller, this "covers it up". Can I jitter the lines somehow? Is there a better solution?

In your geom_linerange call, add an additional argument position=position_dodge(width=0.3) . You can adjust the absolute width to change the separation between the vertical lines.

在此处输入图片说明

My understanding of the question is that you want the line range to reflect the range for the combination a:b:c .

geom_linerange(aes(as.factor(a),ymin=min(value),ymax=value,color=variable)) will set the minimum value to the whole-dataset minimum (hence all the lines appear with the same minimum value.

A couple of solutions.

Calculate the minima and maxima yourself

test_range <- ddply(testMelt, .(a,variable), summarize, 
                    val_min = min(value), val_max = max(value))

then run

 ggplot(data  = testMelt) + 
    geom_boxplot(aes(x = factor(a), y = value, fill = variable)) + 
    stat_smooth(aes(group = variable, x = factor(a), y = value, 
                    fill = factor(variable))) +
     geom_linerange(data = test_range, aes(x = as.factor(a), ymin = val_min,
                    ymax = val_max, color = variable), 
                    position = position_dodge(width = 0.3))

Or, for an alternative to boxplots / line range use a violin plot.

ggplot(data  = testMelt) + 
    geom_violin(aes(x = factor(a), y = value, fill = variable)) + 
    stat_smooth(aes(group = variable, x = factor(a), y = value, 
                    fill = factor(variable)))

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