Fill under line curve - r

For the sample dataset below, I would like to just plot the y as a smooth line with fill under the line using R.
I am able to get smooth line but not the color filled curve. Could someone please help me here?
date, y
2015-03-11, 71.12
2015-03-10, 34.0
2015-03-09, 11.1
2015-03-08, 9.62
2015-03-07, 25.97
2015-03-06, 49.7
2015-03-05, 38.05
2015-03-04, 38.05
2015-03-03, 29.75
2015-03-02, 35.85
2015-03-01, 30.65
The code I used to plot the smooth line is as follows. I am unable to get fill the portion under the line with a color
y <- df$y
x <- 1:length(y)
plot(x, y, type='n')
smooth = smooth.spline(x, y, spar=0.5)
lines(smooth)
EDIT
Using the polygon function does not give what is expected. The shaded area should be below the line not above
with(smooth, polygon(x, y, col="gray"))

Describe a polygon by listing its boundary vertices in order as you march around it.
This polygon's boundary consists of the curve plus two more vertices at the bottom right and bottom left. To help you see them, I have overplotted the vertices, varying their colors by position in the sequence.
Here is the R code that did it. It used predict to obtain coordinates of the curve from the spline object, then adjoined the x- and y-coordinates of the two extra points using the concatenation operator c. To make the filling go to the axis, the plot range was manually set.
y <- c(71, 34, 11, 9.6, 26, 50, 38, 38, 30, 36, 31)
n <- length(y)
x <- 1:n
s = smooth.spline(x, y, spar=0.5)
xy <- predict(s, seq(min(x), max(x), by=1)) # Some vertices on the curve
m <- length(xy$x)
x.poly <- c(xy$x, xy$x[m], xy$x[1]) # Adjoin two x-coordinates
y.poly <- c(xy$y, 0, 0) # .. and the corresponding y-coordinates
plot(range(x), c(0, max(y)), type='n', xlab="X", ylab="Y")
polygon(x.poly, y.poly, col=gray(0.95), border=NA) # Show the polygon fill only
lines(s)
points(x.poly, y.poly, pch=16, col=rainbow(length(x.poly))) # (Optional)

Related

R: Point colours determined by X, Y and Z values with scatterplot3d

I have this R script that uses scatterplot3d:
library(scatterplot3d)
attach(mtcars)
rgb <- read.csv(file="rgb-data.csv",head=TRUE,sep=",")
scatterplot3d(rgb$R,rgb$G,rgb$B,
xlim=c(0,255), ylim=c(0,255),zlim=c(0,255),
xlab="R", ylab="G", zlab="B", pch=".",
main=paste("Feature Space"))
Sample data for rgb-data.csv is:
R,G,B
12,48,126
127,12,48
46,127,12
It produces the plot:
I'm looking for 4 changes:
Have the (0,0,0) point being the front most point in the cube, most central, rather than the point in the bottom left of the plot. Is this possible?
Have the colour of each point reflect the R, G and B values of each point. E.g. (12,48,126) in the above dataset, the R value of the point is 12, G is 48 and B is 126. Is this possible?
The X, Y and Z axis range from 0 to 255 in the R script. However, in the plot they range from 0 to 300. I'd like the axis ranges to be 0 to 255 in the generated plot. Is this possible?
The "B" and "G" axis labels are rotated 270 degrees. I'd like them the same orientation as the "R" axis label. Is this possible?
I am not sure if I understood the 1st question correctly. But, here's the code.
Control with xlim, ylim, zlim
Use RGB function (note that you probably need to change your variable name since the function is called rgb)
Control with x.ticklabs, y.ticklabs, z.ticklabs
The code
library(scatterplot3d)
R <- sample(0:255, 100)
G <- sample(0:255, 100)
B <- sample(0:255, 100)
RGB_ <- rgb(R/255, G/255, B/255)
r_ticks <- c(-255, -200, -100, 0, 100, 200, 255)
ticks <- c(0, 50, 100, 150, 200, 250, 255)
scatterplot3d(R, G, B,
xlim=c(-255, 255),
ylim=c(0, 255),
zlim=c(0, 255),
color=RGB_,
x.ticklabs=r_ticks,
y.ticklabs=ticks,
z.ticklabs=ticks)
Have the (0,0,0) point being the front most point in the cube, most central, rather than the point in the bottom left of the plot. Is this possible?
Setting angle=140 in scatterplot3d( ) provided something close the desired plot:
The (0,0,0) position is more central at the bottom of the plot. I was also envisaging the R and G axes to be sloped slightly upwards into the distance from 0 to 255.
Have the colour of each point reflect the R, G and B values of each point. E.g. (12,48,126) in the above dataset, the R value of the point is 12, G is 48 and B is 126. Is this possible?
Based on Mo K's answer, adding
color=rgb(dat$R, dat$G, dat$B, maxColorValue = 255)
to scatterplot3d( ) gives the desired effect, provided renaming the original variable to dat i.e.
dat <- read.csv(file="rgb-data.csv",head=TRUE,sep=",")
The X, Y and Z axis range from 0 to 255 in the R script. However, in the plot they range from 0 to 300. I'd like the axis ranges to be 0 to 255 in the generated plot. Is this possible?
Mo K's answer works. Adding
ticks <- c(0, 50, 100, 150, 200, 250, 255)
Then
x.ticklabs=ticks,
y.ticklabs=ticks,
z.ticklabs=ticks
to scatterplots3d( ).
The "B" and "G" axis labels are rotated 270 degrees. I'd like them the same orientation as the "R" axis label. Is this possible?
I haven't found a solution to this yet.

How to specify z axis range and add add circle or ellipse in 3D plot in R

3-D graphing with Google(http://www.r-bloggers.com/3-d-graphing-with-google/)
(mu1=0 mu2=0 sigma1=1 sigma2=1 pho=0)
exp((-1/2)*(x^2+y^2))/(2*pi) from -3 to 3
The rotate plot will be showd from google. The profile was a circle.
Dear Prof. Bolker gave me the R code:
library("emdbook")
library("rgl")
curve3d(dmvnorm(c(x,y),mu=c(0,0),Sigma=diag(2)),
sys3d="rgl",front="line",back="line",
xlim=c(-3,3),ylim=c(-3,3))
How to specify z axis range and get the plot like google's plot?
If pho=0 then the profile parallel to XY plane was circle.If pho<>0 then the profile parallel to XY plane was ellipse. How to add circle or ellipse in 3D plot? Thanks.
I am not sure that I fully understand your question but:
1/ I do not think rgl allow to specify z axis range (and curve3d seems to allow it only for xlim, ylim) so you probably need to do it by hand
2/ You can rescale axis in rgl using rgl.viewpoint : e.g., rgl.viewpoint(scale=c(1,1,0.1))
3/ You can draw circle or ellipse using:
t <- matrix(seq(-pi/2,pi/2, len=50), 50, 50, byrow=TRUE)
p <- matrix(seq(-pi, pi, len=50), 50, 50)
r <- 10
x <- r*cos(t)*cos(p)
y <- r*cos(t)*sin(p)
z <- r*sin(t)
persp3d(x, y, z)

R: Counting points on a grid of rectangles:

I have a grid of rectangles, whose coordinates are stored in the variable say, 'gridPoints' as shown below:
gridData.Grid=GridTopology(c(min(data$LATITUDE),min(data$LONGITUDE)),c(0.005,0.005),c(32,32));
gridPoints = as.data.frame(coordinates(gridData.Grid))[1:1000,];
names(gridPoints) = c("LATITUDE","LONGITUDE");
plot(gridPoints,col=4);
points(data,col=2);
When plotted, these are the black points in the image,
Now, I have another data set of points called say , 'data', which when plotted are the blue points above.
I would want a count of how many blue points fall within each rectangle in the grid. Each rectangle can be represented by the center of the rectangle, along with the corresponding count of blue points within it in the output. Also, if the blue point lies on any of the sides of the rectangle, it can be considered as lying within the rectangle while making the count. The plot has the blue and black points looking like circles, but they are just standard points/coordinates and hence, much smaller than the circles. In a special case, the rectangle can also be a square.
Try this,
x <- seq(0,10,by=2)
y <- seq(0, 30, by=10)
grid <- expand.grid(x, y)
N <- 100
points <- cbind(runif(N, 0, 10), runif(N, 0, 30))
plot(grid, t="n", xaxs="i", yaxs="i")
points(points, col="blue", pch="+")
abline(v=x, h=y)
binxy <- data.frame(x=findInterval(points[,1], x),
y=findInterval(points[,2], y))
(results <- table(binxy))
d <- as.data.frame.table(results)
xx <- x[-length(x)] + 0.5*diff(x)
d$x <- xx[d$x]
yy <- y[-length(y)] + 0.5*diff(y)
d$y <- yy[d$y]
with(d, text(x, y, label=Freq))
A more general approach (may be overkill for this case, but if you generalize to arbitrary polygons it will still work) is to use the over function in the sp package. This will find which polygon each point is contained in (then you can count them up).
You will need to do some conversions up front (to spatial objects) but this method will work with more complicated polygons than rectangles.
If all the rectangles are exactly the same size, then you could use k nearest neighbor techniques using the centers of the rectangles, see the knn and knn1 functions in the class package.

R: 3D surface plot (persp3d) with fixed coordinates like in Excel

I have my R data in x, y, and z format, x and y being vectors of length 10 and 19 respectively and z being a matrix of 10x19 integers. I have the following code that prints my 3D surface:
height <- (z - range(z)[1]) / diff(range(z))
r.prop <- height
g.prop <- 0
b.prop <- 1 - height
color <- rgb(r.prop, g.prop, b.prop, maxColorValue=1)
persp3d(x, y, z, theta=50, phi=25, expand=0.75, col=color, ticktype="detailed",
xlab="filesize [kb]", ylab="record size [kb]", zlab="speed [b/s]",
axes=TRUE)
My problem is that the y axis contains powers of 2 (4, 8, 16, 32, 64, ..., 2048,..), which squeezes most of my data points into the low-range part of the plot. What I want is an even distribution of the data points, i.e. between point 4 and 8 should be the same space as between 1024 and 2048 just like it is in the Excel spreadsheet surface plot.
Can you tell me which command or parameter would make that happen with persp3d?
Thanks a bunch!
Loddi
Addition:
After changing the the axes to log2, or just doing a c(1:length(x)) and c(1:length(y)) instead of the actual axis values, it looks better but now has these weird jigsaw shape that is not at all represented in my data. Do you guys have a clue what is going on here?
see picture here http://i.stack.imgur.com/WBI3r.png
Try log2(y) instead of y
persp3d(x, log2(y), z, theta=50, phi=25, expand=0.75, col=color, ticktype="detailed",
xlab="filesize [kb]", ylab="record size [kb]", zlab="speed [b/s]", axes=FALSE,
normal_x=x, normal_y=y, normal_z=z)

Draw an ellipse based on its foci

Is there a way to draw a simple ellipse based on the following definition (instead of eigenvalue) in R?
The definition I want to use is that an ellipse is the set of points in a plane for which the sum of the distances to two fixed points F1 and F2 is a constant.
Should I just use a polar cordinate?
This may be more algorithmic question.
As #DWin suggested, there are several implementations for plotting ellipses (such as function draw.ellipse in package plotrix). To find them:
RSiteSearch("ellipse", restrict="functions")
That being said, implementing your own function is fairly simple if you know a little geometry. Here is an attempt:
ellipse <- function(xf1, yf1, xf2, yf2, k, new=TRUE,...){
# xf1 and yf1 are the coordinates of your focus F1
# xf2 and yf2 are the coordinates of your focus F2
# k is your constant (sum of distances to F1 and F2 of any points on the ellipse)
# new is a logical saying if the function needs to create a new plot or add an ellipse to an existing plot.
# ... is any arguments you can pass to functions plot or lines (col, lwd, lty, etc.)
t <- seq(0, 2*pi, by=pi/100) # Change the by parameters to change resolution
k/2 -> a # Major axis
xc <- (xf1+xf2)/2
yc <- (yf1+yf2)/2 # Coordinates of the center
dc <- sqrt((xf1-xf2)^2 + (yf1-yf2)^2)/2 # Distance of the foci to the center
b <- sqrt(a^2 - dc^2) # Minor axis
phi <- atan(abs(yf1-yf2)/abs(xf1-xf2)) # Angle between the major axis and the x-axis
xt <- xc + a*cos(t)*cos(phi) - b*sin(t)*sin(phi)
yt <- yc + a*cos(t)*sin(phi) + b*sin(t)*cos(phi)
if(new){ plot(xt,yt,type="l",...) }
if(!new){ lines(xt,yt,...) }
}
An example:
F1 <- c(2,3)
F2 <- c(1,2)
plot(rbind(F1, F2), xlim=c(-1,5), ylim=c(-1, 5), pch=19)
abline(h=0, v=0, col="grey90")
ellipse(F1[1], F1[2], F2[1], F2[2], k=2, new=FALSE, col="red", lwd=2)
points((F1[1]+F2[1])/2, (F1[2]+F2[2])/2, pch=3)

Resources