I have a dataset of spatial locations data. I want to do a point pattern analysis using the spatstat package in R using this data. I want the best polygon area for the analysis instead of the rectangle area. The code I have is
original_data = read.csv("/home/hudamoh/PhD_Project_Moh_Huda/Dataset_files/my_coordinates.csv")
plot(original_data$row, original_data$col)
which results in a plot that looks like this
Setting the data for point pattern data
point_pattern_data = ppp(original_data$row, original_data$col, c(0, 77), c(0, 116))
plot(point_pattern_data)
summary(point_pattern_data)
resulting in a plot that looks like this
#The observed data has considerably wide white spaces, which I want to remove for a better analysis area. Therefore, I want to make the point pattern a polygon instead of a rectangle. The vertices for the polygon are the pairs of (x,y) below to avoid white space as much as possible.
x = c(3,1,1,0.5,0.5,1,2,2.5,5.5, 16,21,28,26,72,74,76,75,74,63,58,52,47,40)
y = c(116,106,82.5,64,40,35,25,17.5,5,5,5,10,8,116,100,50,30,24,17,10,15,15,8)
I find these vertices above manually by considering the plot below (with the grid lines)
plot(original_data$row,original_data$col)
grid(nx = 40, ny = 25,
lty = 2, # Grid line type
col = "gray", # Grid line color
lwd = 2) # Grid line width
So I want to make the point pattern polygon. The code is
my_data_poly = owin(poly = list(x = c(3,1,1,0.5,0.5,1,2,2.5,5.5, 16,21,28,26,72,74,76,75,74,63,58,52,47,40), y = c(116,106,82.5,64,40,35,25,17.5,5,5,5,10,8,116,100,50,30,24,17,10,15,15,8)))
plot(my_data_poly)
but it results in an error. The error is
I fix it by
my_data_poly = owin(poly = list(x = c(116,106,82.5,64,40,35,25,17.5,5,5,5,10,8,116,100,50,30,24,17,10,15,15,8), y = c(3,1,1,0.5,0.5,1,2,2.5,5.5, 16,21,28,26,72,74,76,75,74,63,58,52,47,40)))
plot(my_data_poly)
It results in a plot
However, this is not what I want. How to get the observed area as a polygon in point pattern data analysis?
This should be a reasonable solution to the problem.
require(sp)
poly = Polygon(
cbind(original_data$col,
original_data$row)
))
This will create a polygon from your points. You can use this document to understand the sp package better
We don’t have access to the point data you read in from file, but if you just want to fix the polygonal window that is not a problem.
You need to traverse the vertices of your polygon sequentially and anti-clockwise.
The code connects the first point you give to the next etc. Your vertices are:
library(spatstat)
x = c(3,1,1,0.5,0.5,1,2,2.5,5.5, 16,21,28,26,72,74,76,75,74,63,58,52,47,40)
y = c(116,106,82.5,64,40,35,25,17.5,5,5,5,10,8,116,100,50,30,24,17,10,15,15,8)
vert <- ppp(x, y, window = owin(c(0,80),c(0,120)))
plot.ppp(vert, main = "", show.window = FALSE, chars = NA)
text(vert)
Point number 13 is towards the bottom left and 14 in the top right, which gives the funny crossing in the polygon.
Moving the order around seems to help:
xnew <- c(x[1:11], x[13:12], x[23:14])
ynew <- c(y[1:11], y[13:12], y[23:14])
p <- owin(poly = cbind(xnew, ynew))
plot(p, main = "")
It is unclear from your provided plot of the data that you really should apply point pattern analysis.
The main assumption underlying point process modelling as implemented in spatstat
is that the locations of events (points) are random and the process that
generated the random locations is of interest.
Your points seem to be on a grid and maybe you need another tool for your analysis.
Of course spatstat has a lot of functionality for simply handling and summarising data like this so you may still find useful tools in there.
If i've 2 points
First one "29.98671,31.21431"
2nd points "29.97864,31.17557"
i put them in Google Maps, get the route between two of them, and i've another one "29.987201, 31.188547" , want to get the nearest point on the road which near to "29.987201, 31.188547".
is there away to do this using R ?help please .
1) Get route between two points.
library(ggmap)
# output = 'all' so we get the polyline of the path along the road
my_route <- route(from = "29.98671,31.21431",
to = "29.97864,31.17557",
structure = "route",
output = "all")
my_polyline <- my_route$routes[[1]]$legs[[1]]$steps[[1]]$polyline$points
2) Decode polyline to series of points, using function from this linked question
How to decode encoded polylines from OSRM and plotting route geometry?
# DecodeLineR <- function(encoded) {... see linked question ...}
route_points <- DecodeLineR(my_polyline)
3) Plot all the route points, along with our new point
new_point <- data.frame(lat=29.987201, lng=31.188547)
ggplot(route_points, aes(x=lng, y=lat)) +
geom_point(shape=21, alpha=0.5) +
geom_point(data = new_point, color = 'red') +
coord_quickmap() +
theme_linedraw()
4) Find which "route point" is closest to the new point
# get each distance in miles (great circle distance in miles)
library(fields)
route_points$distance_to_new <- t(rdist.earth(new_point, route_points))
# it's this one:
route_points[which.min(route_points$distance_to_new), ]
Answer: The 76th point on the poly line is closest, at ~0.19 miles away
lat lng distance_to_new
76 29.98688 31.18853 0.01903183
I am trying to create a figure like the one depicted in the third column of the following image:
Link for the image in case of backup.
Basically I have x and y positions of 200 particles and I have the MSD data for these 200 positions. I'd like MSD to be the value that should determine a color map for the particles in coordinates (x,y). So MSD should be like the height, or the z position corresponding to each particle in (x,y).
I am surprised at my incompetence, because I have been trying to solve this problem for the last couple of days but none of the Google searches gave me any result. The closest thing that I have found is the concept of "self-organizing map" in Matlab and R, but I do not know how to use R and Matlab's toolbox for SOM was utterly useful for my needs.
I tried the following code in Matlab and get the attached plot as a result:
clear all; close all; clc;
x = (dlmread('xdata.dat'))'; % x is 1x200 array
y = (dlmread('ydata.dat'))'; % y is 1x200 array
msd = (dlmread('msd_field.txt'))'; % msd is 1x200 array
[X,Y] = meshgrid(x,y);
Z = meshgrid(msd);
z = [X; Y; Z];
surf(z)
But I think this plot is not useful at all. What I want is a 2D scatter plot of (x,y) depicting particle positions and on top of that color code this scatter plot with the values stored in msd like the plot I showed in the beginning. How can I create this through Matlab, or any other visualization tool? Thank you in advance.
It is not clear whay you want to have. Here a scatter plot using ggplot2.
## some reproducible data
set.seed(1)
dat <- data.frame(
x = round(runif(200,-30,30),2),
y = round(runif(200,-2,30),2),
msd = sample(c(0,2,3),200,rep=T))
## scatter plot where the size/color of points depends in msd
library(ggplot2)
ggplot(dat) +
geom_point(aes(x,y,size=msd,color=msd)) +
theme_bw()
I have this map of California I generated with the following code:
states = geoshape(shaperead('usastatehi', 'UseGeoCoords', true));
figure
ax = usamap('california');
oceanColor = [.5 .7 .9];
setm(ax, 'FFaceColor', oceanColor)
geoshow(states)
title({ 'California map'})
Now I want to plot specific points on the map using latitude and longitude coordinates. I can't "guesstimate" because I have to plot 100 or so points. How do I do that? I look everywhere and couldn't find a syntax. Thanks.
Use plotm or linem, the equivalent of MATLAB's plot and line functions respectively (they accept the same "line style specifications").
Here is an example:
% California map axes
figure; ax = usamap('california');
setm(ax, 'FFaceColor', [.5 .7 .9])
title('California map')
% read shapefile of US states with names and locations
states = geoshape(shaperead('usastatehi.shp', 'UseGeoCoords', true));
% display map
geoshow(states, 'Parent',ax)
% find states within the shown axes limits (California and Nevada)
latlim = getm(ax, 'MapLatLimit');
lonlim = getm(ax, 'MapLonLimit');
idx = ingeoquad(states.LabelLat, states.LabelLon, latlim, lonlim);
% latitude/longitude coordinates and corresponding labels
lat = states(idx).LabelLat;
lon = states(idx).LabelLon;
txt = states(idx).Name;
% plot coordinates
%plot(lat, lon, 'rx')
linem(lat, lon, 'LineStyle','none', 'LineWidth',2, 'Color','r', ...
'Marker','x', 'MarkerSize',10)
textm(lat, lon, txt, 'HorizontalAlignment', 'left', 'VerticalAlignment','top')
I'm trying to plot flat maps in RGL's 3d environment because it should enable maps to be custom zoomed/tilted for a projection that best suits both the data and required output image aspect. This thread describes the process for plotting images using rgl.surface(). But its not clear if this method is adaptable for OSM/other map objects. Very grateful for any ideas you may have.
This is the starting point, which fails because Error in is.matrix(z) : 'z' is missing. Any idea how I can insert some zeros for z coordinates?
require(rgl)
open3d() # R crashes if this is done later(?)
#Sys.setenv(NOAWT=1) # fix an {OSM} X11 issue in Mac
require(OpenStreetMap)
require(ggplot2)
lat <- c(53, 50); lon <- c(-5, 1)
map <- openmap(c(lat[1],lon[1]),c(lat[2],lon[2]), 5, 'osm')
map <- openproj(map)
rgl.surface(map)
You need to create a matrix of zeroes for heights and use the col= argument to surface3d to set the colour of the image.
Getting all the dimensions and ordering and all that out of the map object is a faff, so here's a function to do it:
map3d <- function(map,...){
if(length(map$tiles)!=1){
stop("multiple tiles not implemented")
}
nx = map$tiles[[1]]$xres
ny = map$tiles[[1]]$yres
xmin = map$tiles[[1]]$bbox$p1[1]
xmax = map$tiles[[1]]$bbox$p2[1]
ymin = map$tiles[[1]]$bbox$p1[2]
ymax = map$tiles[[1]]$bbox$p2[2]
xc = seq(xmin,xmax,len=ny)
yc = seq(ymin,ymax,len=nx)
colours = matrix(map$tiles[[1]]$colorData,ny,nx)
m = matrix(0,ny,nx)
surface3d(xc,yc,m,col=colours,...)
}
Which gives us:
Now, note it only works if there's one tile in the returned map, but the principle is there.
Also, I'm not totally convinced the coordinate alignment is exact. The coordinates may be centre of pixels or edges of the image, so maybe there's a +1 missing somewhere. And I'm not sure if it applies to the gray border or not.