I have a df
with two curve definitions, each consists of two points and a curvature value. The goal is to plot two individual curves using ggplot2
geom_curve
(or an alternative).
I can generate my expected output using:
df <- data.frame(x = c(0,.2), y = c(0,.3), xend = c(1,.4), yend = c(1,.6), curvature = c(-.2,.4))
ggplot(df) + geom_curve(data = df[1, ], aes(x = x, y = y, xend = xend, yend = yend), curvature = df$curvature[1]) + geom_curve(data = df[2, ], aes(x = x, y = y, xend = xend, yend = yend), curvature = df$curvature[2])
But this is not really a solution, since in my real case I have lot more curves (and I don't know how many in advance).
How can I pass an individual curvature
argument to the geom_curve
call?
I tried:
df <- data.frame(x = c(0,0), y = c(0,0), xend = c(1,1), yend = c(1,1), curvature = c(-.2,.8))
library(ggplot2)
ggplot(df) + geom_curve(aes(x = x, y = y, xend = xend, yend = yend, curvature = curvature))
This plots both curves on top of each other and throws an additional warning:
Warning: Ignoring unknown aesthetics: curvature
So I tried:
ggplot(df) + geom_curve(aes(x = x, y = y, xend = xend, yend = yend), curvature = curvature)
This throws an error:
Error in layer(data = data, mapping = mapping, stat = stat, geom = GeomCurve, : object 'curvature' not found
So I tried to explicitly pass the curvature
colon:
ggplot(df) + geom_curve(aes(x = x, y = y, xend = xend, yend = yend), curvature = df$curvature)
This as well throws an error:
Error in seq.default(0, dir * maxtheta, dir * maxtheta/(ncp + 1)) :
'to' muss Länge 1 haben In addition: Warning messages: 1: In if (curvature == 0) { : the condition has length > 1 and only the first element will be used 2: In if (curvature > 0) hand <- "right" else hand <- "left" : the condition has length > 1 and only the first element will be used
From @markus' solution I learned, that we can pass lists
to a ggplot
object, so I tried:
ggplot(df) +
lapply(df$curvature, function(i) {
geom_curve(aes(x = x, y = y, xend = xend, yend = yend), curvature = i) }
)
But this plots each curve with both curvature
argument:
How can I pass that curvature
argument individually for each row?
You could use a for loop to build up your ggplot call as a text string and evaluate the string once the for loop finishes.
update
You might split your data first and then use
lapply
to iterate over the resulting list which we'll feed to thedata
argument ofgeom_curve()
original ansewr
curvature
is not an aesthetic, as you have noted. You can add a list toggplot()
, to get it workFrom
help("+.gg")
If you have other parameters that you want to show in your plot - each line might be coloured differently, is of different size etc. - use
Map
Modified data
Plot
Result