2

I have a table with values extracted from a csv I want to make a contour plot from. Let's use this table as an example

tdata.x = [1;2;1;2];
tdata.y = [3;3;4;4];
tdata.z = randn(4,1);
tdata=struct2table(tdata);
>> tdata
tdata =
  4×3 table
    x    y       z   
    _    _    _______
    1    3    0.53767
    2    3     1.8339
    1    4    -2.2588
    2    4    0.86217

I would like to pivot this such that I can use it for plotting a contour, so in principle I want a 2x2 z matrix where rows/columns are given by y and x respectively, something in this direction:

 x 1        2
y                                                                           
3  0.53767  1.8339
4  -2.2588  0.86217

where the first row are the x coordinates, the first columns is the y coordinates and in-between are the corresponding z-values. So that is to say the z-value corresponding to (x,y)=(1,4) is -2.2588.

Note, I am going to use this grid for other things down the road so solutions involving interpolation are not valid, as well the data is guaranteed to be given on a grid.

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
Morten Nissov
  • 392
  • 3
  • 13
  • 1
    Note that contour plots, if I'm not mistaken, always imply some interpolation between points in whichever mesh you will be creating. – Matteo V Apr 08 '21 at 13:25
  • Mentioning the contour plot was maybe misleading, I just wanted X, Y, and Z mesh grid matrices which one could then use to make contours. I wanted the matrices themselves to only contain data because I had other uses in mind as well. I have nothing against the interpolation necessary for a contour/surf type plot. – Morten Nissov Apr 08 '21 at 15:23

2 Answers2

2

You can use unstack, i.e.

t = unstack( tdata, {'z'}, {'x'} );

Which will give you this:

enter image description here

Note that the column names are all prefixed with x because you can't have a column name beginning with a number. You should be able to extract the x values back again, especially if they're always integers it won't be too hard, for whatever operations you want from here...

Wolfie
  • 27,562
  • 7
  • 28
  • 55
2

Here's the approach I would use:

result = full(sparse(findgroups(tdata.y), findgroups(tdata.x), tdata.z));

Equivalently, you could use the third output of unique instead of findgroups, or accumarray instead of sparse:

[~, ~, ux] = unique(tdata.x);
[~, ~, uy] = unique(tdata.y);
result = accumarray([uy ux], tdata.z);
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147