Reputation: 3545
I have a set of data points that I would like to plot the "integral" for.
For example:
x = seq(from=0, to=9, by=0.05)
y = sin(x)
How do I plot the integral from 0
to x
over the interval, say, 0
to 10
? Where integral is the area bounded by the curve and y=0
.
This of course should look very much like a plot of 1 - cos(x)
, but let's assume we don't know what y = f(x)
actually is.
The only thing I know how to do that seems to make sense is:
spl = smooth.spline(x, y)
However I don't know what to do next.
EDIT: this is not a duplicate of shading under a curve, for one thing areas below y=0 need to be subtracted, for another it's not about displaying shaded regions, but about constructing a function that is the integral...
Upvotes: 0
Views: 548
Reputation: 3545
@Maciej Pitucha's answer is good too, but I eventually muddled my way through what I was originally trying to do with smooth.spline()
, and it seems to work better for my actual data.
test.x = seq(from=0, to=9, by=0.05)
test.y = sin(x)
spl = smooth.spline(y=test.y, x=test.x)
f = function(x) {predict(spl, x)$y}
f.int = function(x) {integrate(f, lower=0, upper=x)$value}
f.int.vec = Vectorize(f.int, vectorize.args='x')
plot(test.x, test.y, type="l", ylim = c(-1,2))
lines(test.x, 1-cos(test.x), col="red")
lines(test.x, f.int.vec(test.x), col="blue")
legend(x="bottomright",
col=c("black","red", "blue"),
legend=c("sin", "1-cos", "integral"),
lty=1)
Upvotes: 0
Reputation: 541
I believe you want to achieve that:
Please note that red and blue lines are not identical - that depends on number of points in which you calculate the area. If you increase number 500 in the first line of code, the lines on plot will be closer. Code:
x <- seq(from=0, to=10, length.out = 500)
n <- rep(1, length(x))
y <- sin(x)
plot(x,y, type="l")
lines(x, 1-cos(x), col="red")
lines(x, cumsum(y*x/cumsum(n)), col="blue")
legend(x="bottomright",
col=c("black","red", "blue"),
legend=c("sin", "1-cos", "integral"),
lty=1)
Upvotes: 1