I have file(s) containing N X values and M Y values. Also one containing Z at each value of (X,Y). So N rows and M columns.
I did this:
a=load('z.txt')
surf(a)
which plots Z ok but the axes are just the datapoint number. How do I get the axes to match the X and Y data?
This seems to do the trick:
x=load('x.txt')
y=load('y.txt')
z=load('z.txt')
surf(x,y,z)
Although there are probably more elegant ways.
Related
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
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.
So, I have two matrices, let's say:
set.seed(11)
a<-matrix(rnorm(10000),ncol=100)
colnames(a)<-(c(1:100))
set.seed(31)
b<-matrix(rnorm(10000),ncol=100)
colnames(b)<-colnames(a)
I want to create a scatter plot where each point will have in:
x axis -> the value of (i,j) from matrix a
y axis -> the value for the same pair (i,j) from matrix b
Somewhat is more difficult for me than it seems..
Converting them to vectors will do what you need. Every combination i,j from a will match the same combination of i,j from b:
plot(as.vector(a), as.vector(b))
I have data with very small values between -1 to 1 in X, Y and Z values between -1 to 1 like below
X,Y,Z
-0.858301,-1,1.00916
-0.929151,-1,1.0047
-0.896405,-0.940299,1.00396
-0.960967,-0.944075,1.00035
wireframe(Z~X+Y,data=sol)
Seems wireframe works only with larger values (1, 2, 3...) , How do I plot small values?
wireframe might be use in one of two ways -
With a rectangular data matrix where the values of x and y are implied by the shape of the matrix.
wireframe(matrix(rnorm(100),ncol=5),drape=TRUE)
Or with a dataframe, where the values of x and y are explicit, and here you can use a formula for the relationships between the columns.
df<-expand.grid(x = seq(0,.1,.01), y = seq(0,.1,.01))
df$z<-rnorm(121)
wireframe(z~x*y,data=df,drape=TRUE)
I've found that if you include the line defining the z axis limits, then you can't draw it below 1. But if you take out the defined axis limits, and let R graph it itself, then it works and you can graph small numbers.
I have a big file with 3 columns: density, dimension, value.
example:
10 0.3 200
10 0.4 300
20 0.3 250
20 0.4 320
I am trying to draw a 3d plot - mesh with mesh() function in octave, like this:
data = load ("file.txt");
mesh(data(:,1), data (:,2), data (:,3));
Problem I have is , I always get error:
rows (z) must be the same as length (y), columns (z) must be the same as length (x).
It worked with function plot3(), but I would like a mesh kind of plot.
The problem is that mesh(X,Y,Z) is expecting your X and Y matrices to be generated using X = meshgrid(x) and Y = meshgrid(y) where x and y only contain unique points. Your data basically already defines the meshgrid, but it is difficult to get it out.
I suggest using reshape as:
X = reshape(data(:,1),m,n);
Y = reshape(data(:,2),m,n); % might be reshape(data(:,2),n,m)
Z = reshape(data(:,3),m,n);
mesh(X,Y,Z);
In this case the assumption is that you have m unique values in Y, and n unique values in X. You may have to transpose these in your call to mesh as mesh(X',Y',Z) or something like that.