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.