Why are there missing pixels in my "heat map" plot using pcolorm?

I am using pcolorm to produce a map showing annual mean precipitation in part of South America.
I have found that pcolorm commonly shows dropped pixels around the perimeter of the "heat map", as shown in the attached example.
The map projection is Miller. The gridded data (P_Annual) is complete, and the lat, lon limits of the map are equal to the limits of the data.

4 Comments

Thanks for the answer. Unfortunately, your solution is cartesian rather than a map projection.
The matlab codes show that pcolor is a front end for surf, and pcolorm is a front end for surfm. So, I tried surfm, in order to get my map projection (see attached code, after the more-compact example from Star Strider). This experiment shows the same result (see below), with an irregular drop of pixels aroud the margin of the "heat map". So surfm is not a solution.
A comment about the often cited "pcolor issue", which has caused many to avoid the pcolor command. Yes, when pcolor is used with "shading flat", then pcolor ends up dropping the last column and row of the C matrix. In addition, each of the color values is offset by a half a pixel length in the x and y directions. Other color mapping tools address this issue by defining two types of registration: pixel registration and grid registration. The problem with pcolor is that when used with "shading flat" it does not address the pixel registration issue. However, when pcolor is used with "shading interp", then the color values are interpolated to get a central color value for the pixel. As a result, the color value is correctly located for the location of each pixel. In addition,the full C matrix is accounted for (i.e. there are no discarded rows and columns). So pcolor works well when "shading interp" is set (or when the 'FaceColor' property for pcolor is set to 'interp').
I doubt that this "pcolor issue" is relevant to my problem given that the discarded last row and column should not cause an irregular drop out of pixel. I did test the "flat" versus "interp" option by setting the "FaceColor" property for pcolor to "interp" (see example code). The pixel-dropout problem was not resolved by this change.
In any case, I would hope that the pcolorm in the Mapping Toolbox works correctly, since there is no easy substitution for that command.
I found an "uncomfortable" solution for the problem described above. It turns out that surfacem function invokes some trimming and clipping, which are not described in the function description nor in the function itself,
My "unconformable" solution is to modifiy the surfacem.m function as follows (staring at line 82):
% Project the surface data
%[x, y, z, savepts] = map.crs.internal.mfwdtran(mstruct, lat, lon, alt, 'surface');
%%%%%%
[x, y, z, savepts] = map.crs.internal.mfwdtran(mstruct, lat, lon, alt, 'none');
%%%%%%
The 'none' option turns off the trimming and clipping going into the mfwdtran function. The successful result is follows here:
I don't like to have to change Matlab's foundation code. There may be another solution. For example, the pcolorm handle returns, as userdata, the points that have been trimmed and clipped. I was unable to return the trimmed and clipped data. Matlab has functions, undotrim and undoclip, but there is not sufficient description about how to get these functions to work.
Matlab: This situation is really sloppy. Please sort this out!! Also I beg Matlab to provide a clear resolution of the pcolor vs imagesc issue (which is also described above).
Over and out,
Mark
Rather than editing the source code, another approach I have found to this problem is to calculate the projected coordinates and use the regular version of the function (in this case pcolor instead of pcolorm). After you create the map axes, something like this:
[x,y]=projfwd(getm(gca),lat,lon)
pcolor(x,y,yourz)
I have found the mapping toolbox versions of the code to generally be less reliable than their non mapping tbx counterparts.
Andrew, Thanks for the suggestion. My experience is similar, in that the mapping functions are less reliable, but they are also more ambitous as well. I have used projected coordinates for before, and yes, one can then use pcolor rather than pcolorm. But I prefer that maps show lat, lon rather than easting, northing for the coordinates. My fix, which involves changing one line in the pcolorm source code, works without any problems. That said, I have to remember to make the edit each time I upgrade matlab.

Sign in to comment.

Answers (2)

One possible issue is the dimension of variables and I think resolving that will solve your issue.
  • Expected dimensions for “lat” is [121 1].
  • Expected dimensions for “lon” is [61 1].
Please follow the documentation below for more information about the dimensions of “x’, “y” ans and “c” in “pcolor(x, y, c)” function:

4 Comments

Suvansh,
Thanks for your suggestion. You pointed out that I used grid vectors for lat and lon, rather than grids. The Matlab documentation shows pcolor and pcolorm both support the used of grid vectors and grids for the x,y, or lat,lon values.
That said, I tested your suggestion by inserting the following just before the pcolorm command in the example code included above.
[lat, lon] = ndgrid(lat, lon); % Replace gridVectors with grids
The figure still has the pixel dropout problem, so I would conclude that your suggestion does not solve the problem.
In addition, keep in mind that I was able to solve the problem by modifying surfacem (as described above). And that solution used grid vectors, so I don't think that the grid vector vs grid issue is in play here.
Best,
Mark
You can use the grid vectors, but please take care of the dimensions in your ".m" script.
Current Dimensions:
>> size(lat)
ans =
61 1
>> size(lon)
ans =
121 1
Expected Dimensions in accordance with documentation:
>> size(lon)
ans =
61 1
>> size(lat)
ans =
121 1
Just replace all the occurences of "lat" with "lon", and "lot" with "lan". you will get the desired heat map without any missing pixels.
Suvansh,
Short summary: My guess is that your suggestion is based on pcolor, but my problem is related to pcolorm.
Do you have a working code where your suggestion above works? The reason I ask is that I tried your suggestion, which involves swapping lon and lat in the coded example above, and I find that pcolorm throw an error, indicating that the arrays have the wrong dimensions.
Warning: Error creating or updating Surface
Error in value of property CData
Array is wrong shape or size
The wording of your reply suggests that you have not tried your suggestion. In addition, it seems that your idea is based on documentation for pcolor, and not for the Mapping Toolbox command pcolorm.
You are right in that pcolor using a meshgrid convention for the reference grids or grid vectors. Your suggestion of reversing lon and lat implies that you are thinking in terms of that convention.
However, pcolorm using an ngrid convention!!
Also keep in mind that my example above does not throw an error, whereas your suggestion does throw an error.
Also note that the definitive documentation for pcolorm is provided in surfm (and also in the surfm code). My comments here are based on that documentation.
Best,
Mark
I would recommend changing your dataset in a way that aligns to the size requirements of MATLAB modules. However, you are right in pointing out the issue in the “pcolorm” module and will let the concerned team know about this issue.
As you already have a possible workaround to unblock yourself, I am mentioning below some other workarounds that you may try:
  • Reversing “lat” and “lon” in the code reverse.m shows the “heatmap” with changed DMS (degrees minutes seconds).
  • Using “heatmap” requires number of latvalues to be same as the number of columns in P_Annual, please follow the “heatmap.m” for more details.

Sign in to comment.

Suvansh,
I regret to say that our discussion is not getting anywhere. You have the idea that the problem I described could be fixed if I use "the size requirements of MATLAB modules". But in fact the convention I am following is the one used by the MATLAB Mapping Toolbox, and my workaround works as well.
The conventional pcolor function does NOT produce a projected map, so your examples using that function are not relevant to this discussion. (As, your heatmap script fails with an error, and your reverse script produces a blank figure.)
What would help this issue is you would let the Matlab team responsible for the Mapping Toolbox that there is a problem with the way their trimming algorithm is working in surfm (see discussion above). The simpliest fix would be to provide a property to in pcolorm, surfm, and surfacem to turn off the trimming algorithm.
Best,
Mark

2 Comments

Hello Mark,
I have informed the team responsible for Mapping Toolbox to take care of this issue. However, if you would like to have any further assistance, please contact MathWorks Support through this link: Contact_Us
To display the heatmap without drop in pixels, we can use the 'geoshow' function.
[lat, lon] = ndgrid(lat, lon); % Replace gridVectors with grids
geoshow(lat, lon, P_Annual*365.25e-3,"DisplayType","texturemap");
follow the documentation below for reference: geoshow

Sign in to comment.

Products

Release

R2022b

Tags

Asked:

on 4 Nov 2022

Commented:

on 12 Oct 2023

Community Treasure Hunt

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

Start Hunting!