Enriching a ggplot2 plot with multiple geom_segment in a loop?
Solution 1
It has to do with the lazy evaluation of the aes()
values. You are binding to the variable i
but not actually doing anything with it in the loop. The mappings aren't resolved till you actually print(p)
. Essentially this means they are all being bound to i
and after the loop exits, i
will have the value it had during the final loop.
So the problem really is you shounld't be using aes()
here as you don't really want active binding. Just set the x
and xend
values outside the aes()
. (And since the y
's are constant they should be outside the aes()
as well).
values <- c(1, 5)
for (i in values) {
p <- p + geom_segment(x=i, y=103, xend=i, yend=107)
}
Solution 2
An alternative approach would be to avoid using a loop at all. You can pack your segment data up in a separate data.frame from your main data and use aes() to plot everything at once like so:
segment_data = data.frame(
x = c(1, 5),
xend = c(1, 5),
y = c(103, 103),
yend = c(107, 107)
)
p = ggplot(df, ...) +
geom_segment(data = segment_data, aes(x = x, y = y, xend = xend, yend = yend))
SkyWalker
How would you be rated on a technical skill that you haven't used yet e.g. tableau? Check out my Stack Overflow skill recommender system: https://github.com/bravegag/HarvardX-Skillability
Updated on June 23, 2022Comments
-
SkyWalker almost 2 years
I successfully create a plot using the following:
# suppose I have a p <- ggplot(data=df, ...) then the following works # I get those two segments plotted correctly p <- p + geom_segment(aes(x=1,y=103,xend=1,yend=107)) p <- p + geom_segment(aes(x=5,y=103,xend=5,yend=107))
However if I do:
values <- c(1, 5) for (i in values) { p <- p + geom_segment(aes(x=i,y=103,xend=i,yend=107)) }
It doesn't work, only the last segment is created. Can anyone advice what's wrong here?
-
MrFlick almost 10 yearsWhat i posted will fix it. Don't use
aes()
in thegeom_segment()
in the loop. -
csgillespie almost 10 yearsThat's what I thought. Do you know why adding a
print
statement or usingforce
in the for loop doesn't fix the problem? -
MrFlick almost 10 years@csgillespie Because in this case you're still binding to the variable
i
, not the value. You can't forceaes
to resolve the name till it actually draws the plot.force
is sometimes useful in situations like this, but with the non-standard evaluation ofaes
it won't help in this case. -
aaiezza almost 7 yearsThis does seem better. I can't even get the other answer to work!
-
Taylor White over 5 years@SkyWalker can you make this the answer?