R: creating DEM of an imaginary map from png - r

I have drawn an imaginary map for fun, and I thought it would be even more fun to make a DEM for the imaginary country using R, just to add to the visualization. :)
Basically, I now have a png with the outline of the country. Just only with a black border, the rest is left white.
My plan was to create a raster from it, so I could eventually add values to every pixel in the map. Since it's a imaginary map, it doesn't have a coordinate system. I just set the extent as it is as png:
drawing <- raster('drawing.png')
extent(drawing) <- c(0, 388, 0, 348)
Then I create a dataframe with the points of which eventually the DEM is calculated from. Basically, I just randomly select pixel locations within the country (name them x and y) and assign a random value as height. For this I use a simple excel sheet:
samples <- read_excel('samples.xlsx')
coordinates(samples) <- ~x+y
spatlocations <- SpatialPoints(samples)
vectlocations <- vect(samples)
Then, I thought, I could create a map using Inverse Distance Weighting (IDW), just to get a nice smooth gradient looking map. So it would possibly something like this:
result <- idw(unsampled, samples)
However, I fail to do this. I for example don't really know how to exactly work with the raster I created from the png, and the same for the sample points.
As you maybe can see, I am what you could consider a beginner :).
Is this possible at all? Is this methodology correct? How can I achieve such a map? Thanks in advance!

Related

R generate points with condition using runifpoint function

I am trying to generate randomly distributed points in a rectangle.
To create 50 random points in a rectangle, I used
i=50
pp<-runifpoint(i, win=owin(c(0,19.5),c(0,3.12))
If I were to add conditions on the coordinates before randomly generating points,
e.g. 0.24 <x<19.26 ,0.24<y<2.64 ,
then generate random points, what code can I imply?
The ultimate goal is to generate points in the rectangle except for the grey shaded area, in the below image
This is a question about the R package spatstat.
The argument win specifies the spatial region in which the points will be generated. In your example you have specified this region to be a rectangle. You just need to replace this rectangle by the region in which you want the points to be generated.
You can construct spatial regions (objects of class owin) in many ways. See help(owin), or help(spatstat) for an overview.
In your example, you could build up the shape by forming the union of several rectangles. For example to make a simple cross shape, I could just write
require(spatstat)
A <- owin(c(-1,1), c(-4, 4))
B <- owin(c(-4,4), c(-1,1))
U <- union.owin(A, B)
plot(U)
Another way would be to specify the corners of the polygon shape and use W <- owin(poly=p) where p = list(x, y) contains the coordinates of the corners, listed in anticlockwise order without repetition. See help(owin).
This is also covered in Section 3.5 of the spatstat book. You can download Chapter 3 for free.

How can I get the area of each Voronoi Polygon in R?

I have a set of coordinates X and Y for my points and used the deldir to create determine and plot the Voronoi Polygons. (I've used this tutorial here)
This is my plot: (sorry that its so small, but you get the idea).
I need to determine the area of each polygon. How can I do that?
I looked up in the deldirpackage page and couldnt find anything related to the Voronoi polygons, only about other
Based on the reference manual (https://cran.r-project.org/web/packages/deldir/index.html), the output of the deldir function is a list. One of the list element, summary, is a data frame, which contains a column called dir.area. This is the the area of the Dirichlet tile surrounding the point, which could be what you are looking for.
Below I am using the example from the reference manual. Use $ to access the summary data frame.
library(deldir)
x <- c(2.3,3.0,7.0,1.0,3.0,8.0)
y <- c(2.3,3.0,2.0,5.0,8.0,9.0)
dxy1 <- deldir(x,y)
dxy1$summary

R: Is it possible to plot a grid from x, y spatial coordinates?

I've been working with a spatial model which contains 21,000 grid cells of unequal size (i by j, where i is [1:175] and j is[1:120]). I have the latitude and longitude values in two seperate arrays (lat_array,lon_array) of i and j dimensions.
Plotting the coordinates:
> plot(lon_array, lat_array, main='Grid Coordinates')
Result:
My question: Is it possible to plot these spatial coordinates as a grid rather than as points? Does anyone know of a package or function that might be able to do this? I haven't been able to find anything online to this nature.
Thanks.
First of all it is always a bit dangerous to plot inherently spherical coordinates (lat,long) directly in the plane. Usually you should project them in some way, but I will leave it for you to explore the sp package and the function spTransform or something like that.
I guess in principle you could simply use the deldir package to calculate the Dirichlet tessellation of you points which would give you a nice grid. However, you need a bounding region for this to avoid large cells radiating out from the border of your region. I personally use spatstat to call deldir so I can't give you the direct commands in deldir, but in spatstat I would do something like:
library(spatstat)
plot(lon_array, lat_array, main='Grid Coordinates')
W <- clickpoly(add = TRUE) # Now click the region that contains your grid
i_na <- is.na(lon_array) | is.na(lat_array) # Index of NAs
X <- ppp(lon_array[!i_na], lat_array[!i_na], window = W)
grid <- dirichlet(X)
plot(grid)
I have not tested this yet and I will update this answer once I get the chance to test it with some artificial data. A major problem is the size of your dataset which may take a long time to calculate the Dirichlet tessellation of. I have only tried to call dirichlet on dataset of size up to 3000 points...

Png image crop, and plot

Is there a simple way to crop a specified pixel location of a png image, and raster that image onto a plot.
Currently i am working with dissociated cells (up to 1000 cells in a field of view). Each cell has a center x (in pixels) and a center y (in pixels). We gather data in trace format, so i would like a way of displaying the picture of the cells next to the trace.
I have tried rasterImage, and grid.raster. Unfortunately i have no idea how to call upon the image array to specify the location.
Also, i do not want to use the zoom package since the functions work extremely slow and are not able to raster onto a current plot.
Take a look at the raster package. The raster::raster function, for importing or coercing your png and raster::crop for subsetting to a specific extent.
Here is an example from the crop functions help.
Create an example raster
r <- raster(nrow=45, ncol=90)
r[] <- 1:ncell(r)
Subset the raster based on a define extent
e <- extent(-160, 10, 30, 60)
rc <- crop(r, e)
Plot results
par(mfrow=c(1,2))
plot(r)
plot(rc)
It was alot easier than expected. My PNG image was an array with 3 layers.
img[xpos, ypos, layer]
Therefore i could simply specify the location of my cells increased by a factor,
rasterImage(img[(x-x*.2):(x+x*.2), (y-y*.2):(y+y*.2),],-2, 4, 3, 1)
Now i need to code around for cells at the limits of my plots.

Make a 3D rendered plot of time-series

I have a set of 3D coordinates (below - just for a single point, in 3D space):
x <- c(-521.531433, -521.511658, -521.515259, -521.518127, -521.563416, -521.558044, -521.571228, -521.607178, -521.631165, -521.659973)
y <- c(154.499557, 154.479568, 154.438705, 154.398682, 154.580688, 154.365189, 154.3564, 154.559189, 154.341309, 154.344223)
z <- c(864.379272, 864.354675, 864.365479, 864.363831, 864.495667, 864.35498, 864.358582, 864.50415, 864.35553, 864.359863)
xyz <- data.frame(x,y,z)
I need to make a time-series plot of this point with a 3D rendering (so I can rotate the plot, etc.). The plot will visualize a trajectory of the point above in time (for example in the form of solid line). I used 'rgl' package with plot3d method, but I can't make it to plot time-series (below, just plot a single point from first frame in time-series):
require(rgl)
plot3d(xyz[1,1],xyz[1,2],xyz[1,3],axes=F,xlab="",ylab="",zlab="")
I found this post, but it doesn't really deal with a real-time rendered 3D plots. I would appreciate any suggestions. Thank you.
If you read help(plot3d) you can see how to draw lines:
require(rgl)
plot3d(xyz$x,xyz$y,xyz$z,type="l")
Is that what you want?
How about this? It uses rgl.pop() to remove a point and a line and draw them as a trail - change the sleep argument to control the speed:
ts <- function(xyz,sleep=0.3){
plot3d(xyz,type="n")
n = nrow(xyz)
p = points3d(xyz[1,])
l = lines3d(xyz[1,])
for(i in 2:n){
Sys.sleep(sleep)
rgl.pop("shapes",p)
rgl.pop("shapes",l)
p=points3d(xyz[i,])
l=lines3d(xyz[1:i,])
}
}
The solution was simpler than I thought and the problem was that I didn't use as.matrix on my data. I was getting error (list) object cannot be coerced to type 'double' when I was simply trying to plot my entire dataset using plot3d (found a solution for this here). So, if you need to plot time-series of set of coordinates (in my case motion capture data of two actors) here is my complete solution (only works with the data set below!):
download example data set
read the above data into a table:
data <- read.table("Bob12.txt",sep="\t")
extract XYZ coordinates into a separate matrixes:
x <- as.matrix(subset(data,select=seq(1,88,3)))
y <- as.matrix(subset(data,select=seq(2,89,3)))
z <- as.matrix(subset(data,select=seq(3,90,3)))
plot the coordinates on a nice, 3D rendered plot using 'rgl' package:
require(rgl)
plot3d(x[1:nrow(x),],y[1:nrow(y),],z[1:nrow(z),],axes=F,xlab="",ylab="",zlab="")
You should get something like on the image below (but you can rotate it etc.) - hope you can recognise there are joint centers for people there. I still need to tweak it to make it visually better - to have first frame as a points (to clearly see actor's joints), then a visible break, and then the rest of frames as a lines.

Resources