简体   繁体   中英

Change 3-column data into matrix form for 2D plot

I have my data in 3 columns, denoting the values of the x, y and z coordinates respectively. The x and y points are on a grid (may be non-uniform, as here):

x y z 

1 1 5
1 2 7
1 3 0
3 1 6
3 2 9
3 3 5
7 1 4
7 2 0
7 3 8

Now I want to use a MATLAB function like pcolor to make a 2D color plot of this data where the z values will be denoted by color. Unfortunately pcolor wants the data for the x and y coordinates either as vectors or as grid matrices, and the z data also in the form of a grid matrix, and will not except column data of this form.

I don't want to use any fitting or interpolation. I only want to rearrange the data I have here. How can I attain this?

General purpose method using meshgrid and unique :

data = [1 1 5;
1 2 7;
1 3 0;
3 1 6;
3 2 9;
3 3 5;
7 1 4;
7 2 0;
7 3 8];
[tmpX1,~,tmpX3] = unique(data(:,1));
[tmpY1,~,tmpY3] = unique(data(:,2));
[X,Y] = meshgrid(tmpX1,tmpY1);
tmpZ = sub2ind(tmpX3,tmpY3); %// use the third output from unique as indices
Z = zeros(size(X)); %//preallocate Z
Z(tmpZ) = data(:,3); %// Use indices to fill the grid
pcolor(X,Y,Z)

The third output of unique can be used as an integer representation of the location within the [X,Y] grid. sub2ind function courtesy of András Deák

As opposed to @AbhranilDas's answer this solution works also if your data is not on a nice grid, eg

data = [1 1 5;
5 2 7;
1 3 0;
3 1 6;
3 2 9;
3 7 5;
7 1 4;
7 2 0;
4 3 8];

The OP's solution only works because the data when reshaped through column-major order becomes exactly the coordinate grids as output by meshgrid . Whenever your data is not that simple and nice, using reshape will get you a non-uniform coordinate matrix.

If this is for plotting purposes, where run-time performance is not a concern, I wouldn't resort to any fancy indexing trickery that's hard to understand and maintain.

Instead, I'd like to recommend a good old for loop combined with imagesc:

data = [
1 1 5
1 2 7
1 3 0
3 1 6
3 2 9
3 3 5
7 1 4
7 2 0
7 3 8
];

plt_data = NaN(max(data(:,2)), max(data(:,1)));

% iterate over the rows
for xyz = data'
    plt_data(xyz(2), xyz(1)) = xyz(3);
end

imagesc(plt_data)
colorbar()

在此处输入图片说明

Okay, so if you have data with negative axis points, then it becomes more work:

data = [
1 -1 5
1 2 7
1 -3 1
3 1 6
-3 2 9
-3 -3 5
7 1 4
7 -2 1
7 3 8
];

x0 = min(data(:,1));
x1 = max(data(:,1));

y0 = min(data(:,2));
y1 = max(data(:,2));

xrange = x1 - x0;
yrange = y1 - y0;

plt_data = NaN(yrange, xrange);

% iterate over the rows
for xyz = data'
    plt_data(xyz(2)-y0+1, xyz(1)-x0+1) = xyz(3);
end

imagesc(x0:x1, y0:y1, plt_data)
set(gca(), 'ydir', 'normal')
colorbar()

And you'll probably want to flip the y-axis so it looks like a familiar Cartesian axis:

在此处输入图片说明

X=reshape(data(:,1), [3 3]);
Y=reshape(data(:,2), [3 3]);
Z=reshape(data(:,3), [3 3]);

pcolor(X,Y,Z);

Note: this will produce a matrix with 4 colours instead of nine because pcolor drops a row and column, but that's a different issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM