Why does pcolor not display the full matrix?

There are several questions on here asking why pcolor does not display the full matrix. Most answers say something along the lines of "use image/imagesc instead". And then other people jump in and say pcolor is more powerful (because it allows irregularly spaced grids). In my case, I use irregularly spaced grids to display geophysical modelling results so image/imagesc does not work. Some people suggest first interpolating your irregularly-spaced data and then using image/imagesc. But, for me, the actual x and y vectors matter a lot (e.g. the location of a given model cell is very important).
I understand that pcolor removes the right column and the top row.
My question is: Why does this happen? Is this a feature or a bug?
From the pcolor help:
"The grid covers the region X=1:n and Y=1:m, where [m,n] = size(C)."
Maybe I'm misunderstanding, but doesn't the grid cover the region X = 1:n-1 and Y=1:m-1? Why does it say it covers the full region if, in reality, it cuts off the top row and right column of the data matrix?
To me this is a bug that should be fixed and everyone seems to complain about it. But I figure there must be some deeper reason why it is not (or can't be) fixed.
Here's an example script:
%Some irregularly spaced vectors:
x = [0.5 0.8 1 1.6];
y = [1.2 1.4 2 2.2];
%Some data
r = ones(4,4); %Size = 4 by 5
r(1,1) = 3;
r(4,4) = 10;
r(2,2) = 10;
pcolor(x,y,r)
colorbar
% r(2,2) is in the correct spot
% and you can see r(1,1) as well.
% But you cannot see r(4,4) = 10

1 Comment

Just running the code from the OP to get a clearer understanding of the question.
%Some irregularly spaced vectors:
x = [0.5 0.8 1 1.6];
y = [1.2 1.4 2 2.2];
%Some data
r = ones(4,4); %Size = 4 by 5
r(1,1) = 3;
r(4,4) = 10;
r(2,2) = 10;
pcolor(x,y,r)
colorbar
% r(2,2) is in the correct spot
% and you can see r(1,1) as well.
% But you cannot see r(4,4) = 10

Sign in to comment.

Answers (2)

This is not a bug. The perceived bug is the result of the 2-dimensional fencepost error. From the description of the C input argument on the documentation page for the pcolor function:
"The values in C map colors in the colormap array to the vertices surrounding each face. The color of a face depends on the color at one of its four vertices. Of the four vertices, the one that come first in X and Y determines the color of the face. If you do not specify X and Y, MATLAB uses X=1:n and Y=1:m, where [m,n] = size(C). Because of this relationship between the vertex colors and face colors, none of the values in the last row and column of C are represented in the plot."
The values in C do not represent the colors of the faces but represent the colors of the vertices. If you look at the picture included in that input argument description the corresponding C is 3-by-3 but only the four (2-by-2) elements with arrows pointing to the faces are used in determining the colors of the pcolor plot. Similarly, if you wanted to draw a 9-by-9 Sudoku grid on a piece of paper you need to draw 10 horizontal and 10 vertical lines to fully enclose the 81 squares where numbers would be placed.

8 Comments

Why would they write such a convoluted program though? Why require all the nastiness of making the color face depend on the data values at the four vertices?
Why not make pcolor plot the cell faces directly based on the data matrix (as would be much more intuitive) and require the user to input cell edges? If your matrix is size M by N, then you would be required to input vectors of cell edges with length (M+1) and (N+1), respectively.
This would:
(a) avoid the fencepost error
(b) allow full plotting of the data matrix
(c) be more intuitive and;
(d) likely avoid extra computation time when deciding what color to plot.
I assume there must be some deeper reason for the choice of implementation.
Just make something like imagesc with variable data spacing, how hard can it be?
Use warp()
Coincidentally, I just ran into this exact pcolor v. imagesc issue yesterday. pcolor returns a surface, which gives control over some things that imagesc does not, like EdgeColor.
Yet again running into this problem. IMHO this pcolor behaviour is a bug, even if it works as specified (i.e., the specification is wrong). This does not make any sense, why would anyone want it to work like it does?
imagesc is broken, because it does not respect the x and y vectors when those are not uniformly spaced. pcolor is broken as described by the OP. heatmap makes more sense, but has a completely differerent interface and other limitations, e.g., it is not possible to plot other graphics on top of the heatmap (at least hold on gives an error with heatmap).
They are all broken in various ways. I have to implement my own... Wait, someone has already done it, there is sanePColor in file exchange...
It's not a fencepost error until someone starts arguing that the number of posts should equal the number of boards.
For anybody else looking for quick fix, just make a n+1 x m+1 nan matrix and place your data (nxm) into this letting the last rows stay nan. Then when you plot pcolor those nan's are cut off and you are left with your data plotted
Can you illustrate your quick fix with the example from this question? I tried it, assuming that you mean to have the last row and column stay NaN, and the x and y vectors are both extended with a single NaN. But the result doesn't change.
%Some irregularly spaced vectors:
x = [0.5 0.8 1 1.6];
y = [1.2 1.4 2 2.2];
%Some data
r = ones(4,4); %Size = 4 by 5
r(1,1) = 3;
r(4,4) = 10;
r(2,2) = 10;
R = nan(5,5);
R(1:4,1:4) = r;
X = [x,NaN];
Y = [y,NaN];
pcolor(X,Y,R)
colorbar
DGM
DGM on 7 Feb 2026 at 5:16
Edited: DGM on 7 Feb 2026 at 9:01
@Lena As I intimated before, there's a conceptual difference between the fenceposts and boards. Disregarding whether your suggestion works as described, where do you propose the "fenceposts" (vertices as defined in the x,y data) exist in relation the the centroid of the "boards" (the face value of the image as mapped by the colormap)?
Remember that the face value of a pcolor() plot is interpolated based on the bounding z-values as defined strictly at the specified x,y coordinates. There are no z-values defined explicitly at the centers of the faces. The face values are all interpolated.
Again, pcolor() is as conceptually consistent as surf(). The x,y and z data all define the vertices of a mesh. If that's not what you want, you have to state what you propose to accomplish.
If it's a matter of suggesting that established function behaviors are inadequate, then I assert that the complaint shouldn't be that pcolor() is "wrong" but that image()/imagesc() should be extended to accept explicit xdata and ydata. Again, to be self-consistent, x,y data would define the face centers, not the mesh vertices. Which do we want?

Sign in to comment.

Jan
Jan on 5 Feb 2026 at 2:09
Edited: Jan on 5 Feb 2026 at 2:25
c = [1, 2, 3; 4, 5, 6; 7, 8, 9];
x = [1, 2, 4];
y = [1, 3, 4];
H = pcolor(x, y, c);
Fine. PCOLOR does exactly, what it is wanted to do. The upper row and right colum of the data are not displayed with flat coloring:
disp(H.FaceColor)
flat
But with interpolated colors, the value on the top and right matter:
H2 = pcolor(x, y, c, 'FaceColor', 'interp');
PCOLOR is a tool, which works as explained in the documentation. The ability to use it with as well flat as interpolated colors has the effect, that with flat colors a row and a column is ignored in the coloring. An alternativ would be to offer two different commands for the different shadings. MathWorks decided in one of the first releases (I assume 1984), that PCOLOR should handle both coloring methods.
Use a programming language to solve a problem. If there is a 2-way hammer like PCOLOR, it might look strange from one side. Instead of discussing, if this is nasty or a bug, just use it to create the wanted output as explained in the docs.
By the way: The code of PCOLOR contains the underlying SURFACE command, so it is easy to check how to call SURFACE directly to do exactly, what you want to do.

Categories

Find more on Graphics Performance in Help Center and File Exchange

Products

Release

R2020a

Asked:

on 3 Dec 2020

Edited:

DGM
on 7 Feb 2026 at 9:01

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!