Interactively select points in Julia plot - julia

I want to select interactively points from a plot (I usually use Makie, but it is not necessary). I would like to perform an area selection creating a polygon over points. My idea is to click with the mouse around the points I want to select and create a polygon box, but i don't know how.
I alrady have a function that select points from polygon areas, but I would like to make it interactive.
I use a function like this to select points:
using PolygonOps
# Box
xv = [-10 210 210 -10 -10]
yv = [-10 -10 10 10 -10]
# Poligon over the Box
polygon = SVector.(xv, yv)
# Points from coordinates
points = vec(SVector.(coord[:, 2], coord[:, 3]))
# Find inside
inside = [inpolygon(p, polygon; in=true, on=false, out=false) for p in points]
I would like to make it interactive, meaning that xv and yv vectors should be made by selecting points on plot using mouse click

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 to animate 3D scatter plot by adding each point at a time in R or MATLAB

I have a set of 3D coordinates here. The data has 52170 rows and 4 columns. Each row represent one point. The first column is point index number, increasing from 1 to 52170. The second to fourth columns are coordinates for x, y, and z axis, respectively. The first 10 lines are as follow:
seq x y z
1 7.126616 -102.927567 19.692112
2 -10.546907 -143.824966 50.77417
3 7.189214 -107.792068 18.758278
4 7.148852 -101.784027 19.905006
5 -14.65788 -146.294952 49.899158
6 -37.315742 -116.941185 12.316169
7 8.023512 -103.477882 19.081482
8 -14.641933 -145.100098 50.182739
9 -14.571636 -141.386322 50.547684
10 -15.691803 -145.66481 49.946281
I want to create a 3D scatter plot in which each point is added sequentially to this plot using R or MATLAB. The point represented by the first line is added first, then the point represented by the second line, ..., all the way to the last point.
In addition, I wish to control the speed at which points are added.
For 2D scatter plot, I could use the following code:
library(gganimate)
x <- rnorm(50, 5, 1)
y <- 7*x +rnorm(50, 4, 4)
ind <- 1:50
data <- data.frame(x, y, ind)
ggplot(data, aes(x, y)) + geom_point(aes(group = seq_along(x))) + transition_reveal(ind)
But I cannnot find information on how to do this for 3D scatter plot. Can anyone show me how this could be done? Thank you.
This is an answer for MATLAB
In a general fashion, animating a plot (or 3d plot, or scatter plot, or surface, or other graphic objects) can be done following the same approach:
Do the first plot/plot3/scatter/surf, and retrieve its handle. The first plot can incorporate the first "initial" sets of points or even be empty (use NaN value to create a plot with invisible data point).
Set axis limits and all other visualisation options which are going to be fixed (view point, camera angle, lightning...). No need to set the options which are going to evolove during the animation.
In a loop, update the minimum set of plot object properties: XData, YData ( ZData if 3D plot, CData if the plot object has some and you want to animate the color).
The code below is an implementation of the approach above adapted to your case:
%% Read data and place coordinates in named variables
csvfile = '3D scatter plot.csv' ;
data = csvread(csvfile,2) ;
% [optional], just to simplify notations further down
x = data(:,2) ;
y = data(:,3) ;
z = data(:,4) ;
%% Generate empty [plot3] objects
figure
% create an "axes" object, and retrieve the handle "hax"
hax = axes ;
% create 2 empty 3D point plots:
% [hp_new] will contains only one point (the new point added to the graph)
% [hp_trail] will contains all the points displayed so far
hp_trail = plot3(NaN,NaN,NaN,'.b','Parent',hax,'MarkerSize',2) ;
hold on
hp_new = plot3(NaN,NaN,NaN,'or','Parent',hax,'MarkerSize',6,'MarkerEdgeColor','r','MarkerFaceColor','g','LineWidth',2) ;
hold off
%% Set axes limits (to limit "wobbling" during animation)
xl = [min(x) max(x)] ;
yl = [min(y) max(y)] ;
zl = [min(z) max(z)] ;
set(hax, 'XLim',xl,'YLim',yl,'ZLim',zl)
view(145,72) % set a view perspective (optional)
%% Animate
np = size(data,1) ;
for ip=1:np
% update the "new point" graphic object
set( hp_new , 'XData',x(ip), 'YData',y(ip), 'ZData',z(ip) )
% update the "point history" graphic object
% we will display points from index 1 up to the current index ip
% (minus one) because the current index point is already displayed in
% the other plot object
indices2display = 1:ip-1 ;
set(hp_trail ,...
'XData',x(indices2display), ...
'YData',y(indices2display), ...
'ZData',z(indices2display) )
% force graphic refresh
drawnow
% Set the "speed"
% actually the max speed is given by your harware, so we'll just set a
% short pause in case you want to slow it down
pause(0.01) % <= comment this line if you want max speed
end
This will produce:

Gnuplot "vector line"

I am trying to generate a plot which uses arrows as markers in Gnuplot. These arrows I want to turn in a specific angle which I know. So I have value triples of x1 ... xn, y1...yn, alpha1...alphan. Sorry, I wasn't able to include a pic from my hard drive to illustrate what I want to achieve.
Basically, for every (15th or so) x-y pair, the marker should be an arrow which uses a certain angle.
The measured data is tightly packed so I suppose I will have to define an increment between the markers. The length of the arrow can be the same all over.
I would appreciate your ideas.
Gnuplot has a plot mode with vectors that is what you want
Given that your file has the following format, x y angle and assuming that
your angle is in radians, you have to take into account that
with vectors requires 4 parameters, namely x y dx dy where dx
and dy are the projections of the lenght of the arrow.
this draws only the arrows, if you want a line you have to make
two passes on the data.
you want to draw an arrow for a data point over, say, 10 points.
That said, I'd proceed like this
dx(a) = 0.2*cos(a) # 0.2 is an arbitrary scaling factor
dy(a) = 0.2*sin(a)
# this draws the arrows
plot 'mydata.dat' every 10 using 1:2:(dx(a)):(dy(a)) with vectors
# this draws the line
plot 'mydata.dat'
You may want to use help plot to find the detailed explanation of all the parameters that you can apply to a with vectors plot.
Credits: An article on the gnuplotting site

create hexagonal cells grid using lat/lon coordinates

I would like to create a spatial grid with hexagonal cells using WGS84 coordinates (ie cells defined by 2 coordinates X=Latitude and Y=Longitude)
So, this is what I was thinkin about :
library(ggplot2);library(hexbin)
X<-seq(-10,20,by=0.1) # create coordinates vectors X and Y
Y<-seq(35,65,by=0.1)
z<-rnorm(301,0.5,1)
df<-as.data.frame(cbind(X,Y,z)) # create data frame with a z value for each cells (X,Y)
pl<-ggplot2(data=mat,aes(x=X,y=Y,z=z))+stat_summury_hex(fun=function(x) sum(x))
plot(pl)
But doing this does not provide what I wanted.
So, my question is : how to do a spatial grid with hexagonal cells using lat/lon coordinates ?
And second question : how to create a grid centered from one point (that would represent the centroid, and not the left bottom corner as usual?)
If I understand properly, you're looking for expand.grid():
xy <- expand.grid(X=X,Y=Y)
z<-rnorm(nrow(xy),0.5,1)
df<-as.data.frame(cbind(xy,z)) # create data frame with a z value for each cells (X,Y)
head(df)
pl<-ggplot(data=df,aes(x=X,y=Y,z=z))+stat_summary_hex(fun=function(x) sum(x))
plot(pl)
As for the second question, I'm not sure, but since all hexagons are the same size and will require the same operation to center, you can shift them uniformly by changing X and Y appropriately. Perhaps this can also be done via arguments also, not sure.
[[Edit July 23]]
second question was how to get a data.frame of hex coordinates. Took some digging, but here's an example:
library(hexbin)
coords <- hcell2xy( hexbin(x=X,y=Y))
head(coords)
x y
1 -10.0 35.00000
2 -9.5 35.86603
3 -8.5 35.86603
4 -9.0 36.73205
5 -8.0 36.73205
6 -7.5 37.59808
hcell2xy() is the key function called by ggplot2, and you may need to be explicit about specifying the argument xbins, which is determined automatically inside ggplot2, but appears to default to 30 in both cases.
[[Edit 3, to include z level]]
This is an answer to the comment asking for z levels as well. Ripped from ggplot2:::hexBin
hb <- hexbin(x=X,y=Y)
# Convert to data frame
data.frame(
hcell2xy(hb),
count = hb#count,
density = hb#count / sum(hb#count, na.rm=TRUE)
)
You can choose whether to use count or density for colors later, but warning: those are different from your z variable fed to ggplot2. If you'd like to summarize based on some other statistic, then I suggest you also look into the guts of those functions to see how things are passed around. That's what I've been doing.

Draw a translucent sphere using rgl in R

I have a set of data, looks like:
x y z
1 1 2 1
2 3 5 7
3 -3 2 4
4 -2 1 1
so each row record the dot coordinate in a 3-D space. I want to plot all the dot as points except for one, say no.15 as a translucent sphere, with radius I can set. Then I can see from the plot that which of those points in the data are included in the sphere. I'm using RGL package right now and did the following:
> open3d()
> plot3d(readin,col=3,type="p")
> plot3d(readin[15,],col=2,add=T,type="s",radius=0.1)
So the first plot command plotted the whole set as scatter plots and the second plot command picked the 15th row of the data and plot it as a sphere and add it to the previous canvas. I just wondering if I can make the sphere translucent so that I can see which dots a included in the sphere which means those dots are very near to the one I select.
Is there a way to do this by RGL Or you can provide me another ways to complete this task?
Thanks!
I think what you are looking for is the argument alpha.
Example
df <- data.frame(x=c(1,3,-3,-2), y=c(2,5,2,1),z=c(1,7,4,1))
library(rgl)
open3d()
plot3d(df,col=3,type="p", radius=0.5)
plot3d(df,col=rgb(1,0,0.3),alpha=0.5, add=T,type="s",radius=1)
You can plot transparent spheres using the alpha argument to spheres3d. You can rotate the plot to move the box line behind the sphere to prove it's transparent.
spheres3d(dat[4,],col=rgb(1,0,0), alpha=0.9) # transparent red.
(I tried to do it with the alpha argument to rgb but it failed.)
If you just want to find out which points are within a certain radius of point 15 then you can calculate the Euclidean distance from each point to point 15 and see which of those distances are less than the radius. No plotting needed (though you could plot those points as a different color to highlight them. The dist function is one way to compute the distances, or it is simple to program yourself.

Resources