Can't generate a surface plot in scilab - plot

I'm having trouble generating a three-dimensional surface plot in Scilab. I keep getting the error:
!--error 999
Objplot3d: x vector is not monotonous.
I'm using the command:
plot3d(x,y,z)
where x and y are 200X1 matrices (aka column vectors) and z is a 200X200 matrix. I thought maybe I had to transpose y, but that led to the same error as well.

help plot3d requires, indeed, that the first two arguments be monotonous (ie sorted). I wish someone could tell me why!
Since your x (and possibly y) is not ordered, which causes the error, you just need to sort them, and then pay some attention to keep the z values where they belong. Something like:
[newx,ix]=gsort(x);
[newy,iy]=gsort(y);
newz = z(ix,iy);
plot3d(newx,newy,newz)
(ix is the permutation such that x(ix)==newx)

Related

Determining the mean center and standard distance of a dataset in R

I have a dataset called mypoints and I have created a polygon and plotted the points as below:
mypoints=read.csv("d:\\data\\venus.csv",header = T)
mypoints
minx=min(mypoints[,1])
maxx=max(mypoints[,1])
miny=min(mypoints[,2])
maxy=max(mypoints[,2])
mypolygon=cbind(c(minx,maxx,maxx,minx),c(miny,miny,maxy,maxy))
plot(mypoints)
polygon(mypolygon)
I now want to write a function that calculates both the mean center and standard distance for mypoints. I then need to plot the standard distance as a circle centered on the mean center of all points with the radius equal to the standard distance. Note that the last expression evaluated in a function becomes the return value, the result of invoking the function.
So far:
#I think this how I calculate the mean center for x and y:
x1=sum(mypoints[,1])/length(mypoints[,1])
y1=sum(mypoints[,2])/length(mypoints[,2])
#This is the formula I was shown for standard distance:
sd.mypoints=sqrt(sum(x1+y1)/n)
#This is the formula I was shown for creating the circle:
symbols(sd.mypoints[1],sd.mypoints[2],sd.mypoints$sd,add=T,inches=F)
#This is the error that I get when I run the circle formula:
Error in sd.mypoints$sd : $ operator is invalid for atomic vectors
I have found it easier to find the Nearest Neighbor, do KDE, Ghat, and Fhat for this dataset than trying to figure this out. I am sure there is a easy solution for this but I just can't seem to get it. Third class in R and it has been a lot of fun up to this point.
You have the line
symbols(sd.mypoints[1],sd.mypoints[2],sd.mypoints$sd,add=T,inches=F)
in your code. As said in the comments, sd.mypoint is not a data.frame, so subsetting it with sd.mypoint$sd` causes the error you see.
From the documentation of symbols, which you can access with ?symbols you'll see that for circles the circles argument is mandatory, so the function can differentiate what sort of figure is drawing.
EDIT:
Also, please notice that you are using x and y points to symbols different to the ones you already calculated. So you need to replace that line with:
symbols(x1, y1,circles = sd.mypoints,add=T,inches=F)
Notice the use of x1 and y1. I can see the plot now.

R - using heatmaply for a 2d histogram / density

I'm rather new to programming and the site so let me know if I screw up on this explanation.
I have a rather long series of x, y coordinates representing a character in 2d space. Let's say that space is 200 x 400. I want to represent the amount of time the character is in each x, y coordinate by means of a pretty chloropleth.
I want to use heatmaply for this because I think the output is pretty and I want my audience to be able to zoom in on the data. It isn't really meant to do density estimation (I think?) so I'm trying to work around it.
I suppose the way to do this is to fill a 200x400 dataframe with counts of the number of occurrences of each x, y coordinate in the data at each x, y coordinate in the frame. Essentially, to build a 2d map out of the data frame and impose the counts upon it
So, I suppose my questions are:
1). How do I get the count of each unique x, y coordinate in my set
2). How might I pass those counts easily to the matching x, y cell in my 200x400 dataframe full of zeroes?
This seems like it should be easy but I can't seem to figure it out! I'm a novice to r and can't see the shape of what I need to do.
You can use the table function to get your matrix of counts.
table(X,Y)
X and Y should be columns of coordinates.
Output based on some sample data

3D Ploting in Scilab: Weird plot behaviour

I want to plot a function in scilab in order to find the maximum over a range of numbers:
function y=pr(a,b)
m=1/(1/270000+1/a);
n=1/(1/150000+1/a);
y=5*(b/(n+b)-b/(m+b))
endfunction
x=linspace(10,80000,50)
y=linspace(10,200000,50)
z=feval(x,y,pr)
surf(x,y,z);
disp( max(z))
For these values this is the plot:
It's obvious that increasing the X axis will not increase the maximum but Y axis will.
However from my tests it seems the two axis are mixed up. Increasing the X axis will actually double the max Z value.
For example, this is what happens when I increase the Y axis by a factor of ten (which intuitively should increase the function value):
It seems to increase the other axis (in the sense that z vector is calculated for y,x pair of numbers instead of x,y)!
What am I doing wrong here?
With Scilab's surf you have to use transposed z if comming from feval. It is easy so realize if you use a different number of points in X and Y directions, as surf will complain about the size of the third argument. So in your case, use:
surf(x,y,z')
For more information see the help page of surf.
Stephane's answer is correct, but I thought I'd try to explain better why / what is happening.
From the help surf page (emphasis mine):
X,Y:
two vectors of real numbers, of lengths nx and ny ; or two real matrices of sizes ny x nx: They define the data grid (horizontal coordinates of the grid nodes). All grid cells are quadrangular but not necessarily rectangular. By default, X = 1:size(Z,2) and Y = 1:size(Z,1) are used.
Z:
a real matrix explicitly defining the heights of nodes, of sizes ny x nx.
In other words, think of surf as surf( Col, Row, Z )
From the help feval page (changed notation for convenience):
z=feval(u,v,f):
returns the matrix z such as z(i,j)=f(u(i),v(j))
In other words, in your z output, the i become rows (and therefore u should represent your rows), and j becomes your columns (and therefore v should represent your columns).
Therefore, you can see that you've called feval with the x, y arguments the other way round. In a sense, you should have designed pr so that it should have expected to be called as pr(y,x) instead, so that when passed to feval as feval(y,x,pr), you would end up with an output whose rows increase with y, and columns increase with x.
Then you could have called surf(x, y, z) normally, knowing that x corresponds to columns, and y corresponds to rows.
However, if you don't want to change your whole function just for this, which presumably you don't want to, then you simply have to transpose z in the call to surf, to ensure that you match x to the columns or z' (i.e, the rows of z), and y to the rows of z' (i.e. the columns of z).
Having said all that, it would probably be much better to make your function vectorized, and just use the surf(x, y, pr) syntax directly.

how to intersect an interpolated surface z=f(x,y) with z=z0 in R

I found some posts and discussions about the above, but I'm not sure... could someone please check if I am doing anything wrong?
I have a set of N points of the form (x,y,z). The x and y coordinates are independent variables that I choose, and z is the output of a rather complicated (and of course non-analytical) function that uses x and y as input.
My aim is to find a set of values of (x,y) where z=z0.
I looked up this kind of problem in R-related forums, and it appears that I need to interpolate the points first, perhaps using a package like akima or fields.
However, it is less clear to me: 1) if that is necessary, or the basic R functions that do the same are sufficiently good; 2) how I should use the interpolated surface to generate a correct matrix of the desired (x,y,z=z0) points.
E.g. this post seems somewhat related to the problem I am describing, but it looks extremely complicated to me, so I am wondering whether my simpler approach is correct.
Please see below some example code (not the original one, as I said the generating function for z is very complicated).
I would appreciate if you could please comment / let me know if this approach is correct / suggest a better one if applicable.
df <- merge(data.frame(x=seq(0,50,by=5)),data.frame(y=seq(0,12,by=1)),all=TRUE)
df["z"] <- (df$y)*(df$x)^2
ta <- xtabs(z~x+y,df)
contour(ta,nlevels=20)
contour(ta,levels=c(1000))
#why are the x and y axes [0,1] instead of showing the original values?
#and how accurate is the algorithm that draws the contour?
li2 <- as.data.frame(contourLines(ta,levels=c(1000)))
#this extracts the contour data, but all (x,y) values are wrong
require(akima)
s <- interp(df$x,df$y,df$z)
contour(s,levels=c(1000))
li <- as.data.frame(contourLines(s,levels=c(1000)))
#at least now the axis values are in the right range; but are they correct?
require(fields)
image.plot(s)
fancier, but same problem - are the values correct? better than the akima ones?

Is there a way of forcing the image function in R not to normalize coordinates?

When using the image function in R it normalized the length of the dimensions of the input matrix so X and Y axes go from 0 to 1.
Is there a way of telling the image function not to normalize these numbers?
I need to do so in order to overlay different kinds of data and normalizing all these coordinates into the [0,1] space is very tedious.
EDIT: The answer provided by Greg explains the situation.
A reproducible example would be very helpful here. Generally if you only give image a z matrix then the function chooses default x and y values that work, I think this is what you are seeing. On the other hand if you give image an x vector and a y vector then it uses that information to construct the graph. If the x/y vectors have a length equal to the corresponding dimension of z then those values represent the centers of the rectangles, if x/y is 1 longer than the corresponding dimension of z then they represent the corners of the rectangles. This gives you a lot of control over the things that you mention.
If this does not answer the question then give us a self contained reproducible example to work with.
I am going to answer my question based on the answer Greg Snow provided in order to follow the best practice of this site as anything that provides information should be an answer.
If you do not provide the x nor y parameters to the image() function, then the range of the axes is from 0 to 1 as in the next example.
> image(volcano)
Then, if you want to locate a point of interest in the matrix in use, for the element of the matrix with [x,y] coordinates of [10,40] you need to do something like:
> points(x=10/length(volcano[,1]),y=40/length(volcano[1,]))
If the x and y parameters are specified, and (as Greg mentioned) they fit the dimensions of the matrix, then the axes will range withing the specified x and y vectors.
> dim(volcano)
[1] 87 61
> image(x=1:87, y=1:61, z=volcano)
> points(10,40)

Resources