Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
604 views
in Technique[技术] by (71.8m points)

r - ggplot2: adding lines in a loop and retaining colour mappings

When running the following two pieces of code, I unexpectedly get different results. I need to add lines in a loop as in EX2, but all lines end up having the same colour. Why is this?

EX1

economics2 <- economics
economics2$unemploy <- economics$unemploy + 1000
economics3 <- economics
economics3$unemploy <- economics$unemploy + 2000
economics4 <- economics
economics4$unemploy <- economics$unemploy + 3000
b <- ggplot() +
 geom_line(aes(x = date, y = unemploy, colour = as.character(1)), data=economics2) +
 geom_line(aes(x = date, y = unemploy, colour = as.character(2)), data=economics3) +
 geom_line(aes(x = date, y = unemploy, colour = as.character(3)), data=economics4)
print(b)

EX1

EX2

#economics2, economics3, economics4 are reused from EX1.
b <- ggplot()
econ <- list(economics2, economics3, economics4)
for(i in 1:3){
  b <- b + geom_line(aes(x = date, y = unemploy, colour = as.character(i)), data=econ[[i]])
}
print(b)

EX2

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is not a good way to use ggplot. Try this way:

econ <- list(e1=economics2, e2=economics3, e3=economics4)
df   <- cbind(cat=rep(names(econ),sapply(econ,nrow)),do.call(rbind,econ))
ggplot(df, aes(date,unemploy, color=cat)) + geom_line()

This puts your three versions of economics into a single data.frame, in long format (all the data in 1 column, with a second column, cat in this example, identifying the source). Once you've done that, ggplot takes care of everything else. No loops.

The specific reason your loop failed, as pointed out in the comment, is that using aes(...) stores the expression in the ggplot object, and that expression is evaluated when you call print(...). At that point i is 3.

Note that this does not apply to the data=... argument, so you could have done something like this:

b=ggplot()
for(i in 1:3){
  b <- b + geom_line(aes(x=date,y=unemploy,colour=cat), 
                     data=cbind(cat=as.character(i),econ[[i]]))
}
print(b)

But, this is still the wrong way to use ggplot.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...