Why contourf connect far apart points

I have a problem with the contour it connects far apart points and appear colored lines ( I already set 'LineStyle', 'none') that they shouldn't how can I avoid this problem? My data are in a cell arrays and I use cell2mat to create matrices and then I do the contour If I do it from the cell arrays I don't have this problem but is too slow and use all the memory so I don't like this approach.

14 Comments

hello
can you share a working code and some data ?
Yes the basic code is this
A1MAT=cell2mat(A1);
A2MAT=cell2mat(A2);
A3MAT=cell2mat(A3);
contourf(A3MAT,A2MAT,A1MAT,100,'LineStyle','none');
where A1,A2,A3 cell arrays with 3000 4000 or more cells with usually 10x10 matrices
I tried to do it one cell at the time for example A1{i} in for loop but although is correct takes too much time and memory
I don't know how your data has been generated and why it is stored as thousands of cells of 10 x 10 matrices
there is maybe a way to reduce the amount of data needed to perform the contour plot
is there really a need to have so much data being plotted ?
Yes I can't avoid it, I can reduce the 10x10 to 8x8 but I don't think that will make big difference, A2,A3 are matrices with coordinates caclulated on specific points and A1 is the property I want to plot
Mathieu NOE
Mathieu NOE on 29 Sep 2025
Edited: Mathieu NOE on 29 Sep 2025
ok
" A1,A2,A3 cell arrays with 3000 4000 or more cells with usually 10x10 matrices "
just wondering how the data is organized .... A1MAT size is then 10 x 10 or do you combine several cells to get the final A1MAT array ?
Actually randomly, because I want to use this code for different coordinate’s data so they will not always organized the same way, so just because this part will be in a function, if I must process the data I have to do this after they are generated if I have to order them in a certain way. Sorry maybe I didn't explained it correctly but every cell is 10x10 in A1,A2,A3 all of them have always the same number of cells and the same size matrices
abc = randi(10,10);
def = {abc};
whos abc def
Name Size Bytes Class Attributes abc 10x10 800 double def 1x1 920 cell
920 - 800 = 120 bytes of overhead, which is 15% overhead in this case, not 50%
It's not that the cell array version is double the size, Walter, it's that @Dimitrios kept both variables in memory so he has 800 + 920 = 1720 total bytes.
The suggestion was to reuse the same variable in the conversion rather than create the copy; there is no reason to keep both at the same time.
A=mat2cell(rand(10),10,10);
A1=cell2mat(A);
whos A*
Name Size Bytes Class Attributes A 1x1 920 cell A1 10x10 800 double
is OP's original syntax.
My suggestion was
clear A*
A=mat2cell(rand(10),10,10);
A=cell2mat(A);
whos A*
Name Size Bytes Class Attributes A 10x10 800 double
which keeps only the one variable instead of two and the comparative memory is 800/1720 < 0.5
It is possible MATLAB may make a temporary copy behind the scenes, that I don't know about for sure...
I think I created a confusion about my problem so I will write the 2 versions
when I write this
for i=1:4000
contourf(A3{i},A2{i},A1{i},100,'LineStyle','none');
end
I have the problems with the speed and the memory but the final contour plot is correct
when I write this
A1MAT=cell2mat(A1);
A2MAT=cell2mat(A2);
A3MAT=cell2mat(A3);
contourf(A3MAT,A2MAT,A1MAT,100,'LineStyle','none');
I don't have the problem with the speed and the memory but the plot is wrong it connects far apart points that it shouldn't.
For the first version even if I solve the memory problem I still have the speed problem which equally important.
I think that the problem is wih the second version that it interpolates all the data together but in the first version it doesn't
dpb
dpb on 29 Sep 2025
Edited: dpb on 29 Sep 2025
No, there's no confusion about the problem, @Dimitrios, Walter and I just got off onto a sidebar discussion in that he didn't catch the suggestion I had made. As noted, you can help with the memory in several ways, the simplest being to just quit making copies of the same data in different format by reusing the same variable for the assignment to the array from the cell array.
As for the display problem, those are exactly the symptoms I illustrate the reason behind in my Answer; the problem is your construction of the surface from the tilings creates sections of the whole surface that are not sequential in their coordinates and so when they are pasted together in memory storage order, the coordinates aren't in geometric order and so the surface isn't smooth when the contouring function goes to draw the isolines.
As noted, the only way to solve this is one of
  1. Reorder the pieces in the tiles in true geometric order over x and y into one set of arrays covering the whole surface or
  2. Add a NaN at the boundary of each tiling so contour will not connect the separate pieces or
  3. Don't try to draw the isolines at all.
Also as noted, the only way anybody here can help further will be for you to upload a small(ish) portion of a dataset in order to be able to see what the actual construction is; IF (the proverbial "big if") the x,y coordinates are specified in meshgrid fashion, it may be possible to sort the array in x and y and rearrange z to match to reconstruct the full image; whether this is possilble or not will depend upon just what the geometry actually is and how the tilings were constructed, details of which you have not shared.
Sorry I misunderstood it.
I think your suggestion with NaN can work I will try to work with this to see if I can solve my problem to have small lines is a minor problem compared to the contour I have now. Thanks a lot
Thank you all guys for the suggestions
dpb
dpb on 29 Sep 2025
Edited: dpb on 29 Sep 2025
"...your suggestion with NaN can work"
It will work to not create the isolines across the discontinuities you've introduced by the tilings; however, if you will look closely at the example plots in the Answer, you'll notice that while the shape of the distinct contours matches that of the full image, the color maps aren't identical for each adjacent tiling because the data ranges aren't going to map to the same overall range. Thus, you're still going to get discontinuities; they'll show up as horizontal and vertical lines of color visual discontinuity between adjacent tiles.
You might be able to work around this by finding the overall range of the data and then setting the color maps within each tiling based on it; I've not looked into that, but it may get messy.
The second issue is that you may have issues in creating consistent isolines across the pieces; there are subtle differences between the example and the original full image that I didn't pursue further. It may be that because I took the expedient of replacing the last row/column instead of inserting the break with the small number of points the missing values caused the internals to be different and that would go away if did insert extra rows/columns. Specifically in the example, note there is no line finishing the lobe to the lower left around the [-2,2] region in the fourth image as compared to first. Close inspection will reveal other differences as well.
BTW, I experimented some and it isn't possible to not have contourf attempt to draw the isolines whether they are displayed or not; henc, prior suggestion 3. is out of the running and you're left with only the two alternatives.
Again, the better solution would be to either
  1. Don't create the data in this fashion to begin with, or
  2. Rearrange it in proper order before plotting.
And, also yet again, if you would upload a sample dataset for folks to poke at, the latter just might be possible to figure out.
It worked just perfect, exactly the way it was supposed to be thank you so much for your help
The problem with the data is that I can't have less than 2000 with 8x8 matrices and that the way they are arranged before inserted in the function it is not known in advance so to rearrange them I must have a general function to do this. Also less data can't represent the solution to my problem which I want the contour.
Also the way I inserted the NaN didn't create white lines so it is just perfect thank you again
"...I can't have less than 2000 with 8x8 matrices and ... less data can't represent the ... contour..."
A typical HD monitor has only 1920x1080 pixels so more unique points than that are immaterial for display; closer than that will just be more than one point at the same display pixel location. That would allow an 8X decimation over the range of the x data. Even if you have 4K, it's only twice that so that would still allow roughly a 4X reduction in size with no discernible change in the plotting/visualiztion of the contour.

Sign in to comment.

 Accepted Answer

dpb
dpb on 29 Sep 2025
Edited: dpb on 29 Sep 2025
A1=cell2mat(A1);
A2=cell2mat(A2);
A3=cell2mat(A3);
would reduce the memory consumption by over half because the cell array has an overhead associated with each cell over the actual data storage and so is even larger than the double array.
You could also save half the memory by using single instead of default double since that will be more than adequate for plotting accuracy.
Back to the original Q?, I expect the problem is the data structure of having the cell arrays and plotting them as the overall matrices is that the coordinates are based on the individual pieces and not as if were one single representation of the same surface and that is why it appears ok when plot each cell array by itself as opposed to all together.
We would need to have the actual data for a small example that would produce the problem to verify, but I'd expect the actual data structure is where the problem lies.
As for speeding it up, not sure there would be much that could be done there unless can rearrange the data structure to represent the overall surface as a single x,y,z array rather than by patchwork. Doing that would then allow for decimation by a significant factor before markedly changing the visual representation. Reducing the number of contours would also help; 100, is quite large number.
As an aside on speed, which release of MATLAB are you using; the newer releases (since R2024) aren't yet up to the performance level of earlier releases, but the data size and organization are going to be the key issues to solve methinks.
ADDENDUM
Example of my hypothesis
[X,Y,Z]=peaks(40); % small, divisible by 10 surface
x=mat2cell(X,10*ones(4,1),10*ones(4,1)); % split up into 10x10 cells
y=mat2cell(Y,10*ones(4,1),10*ones(4,1));
z=mat2cell(Z,10*ones(4,1),10*ones(4,1));
ix=randperm(4); iy=randperm(4); % rearrange the cells to not be contiguous
x=x(ix,iy); y=y(ix,iy); z=z(ix,iy); % keeping same order within subsections
tiledlayout('flow')
nexttile
contourf(X,Y,Z,10)
title('Original Full Surface')
nexttile
x=cell2mat(x); y=cell2mat(y); z=cell2mat(z);
contourf(x,y,z,2,'ShowText','on')
title('Tiled Surface, Two Levels')
nexttile
contourf(x,y,z,10)
title('Tiled Surface, Ten Levels')
nexttile
x(10:10:end,:)=nan; x(:,10:10:end)=nan;
y(10:10:end,:)=nan; y(:,10:10:end)=nan;
z(10:10:end,:)=nan; z(:,10:10:end)=nan;
contourf(x,y,z,10)
title('Full Tiled Surface with Breaks')
The second shows the contour lines drawn between distant points because the coordinates in the second case aren't all sequential so the surface looks all jumbled to the contour tracing function internally. Here I set it to have only two lines and to label them so can follow which went where; with a much larger number of unlabelled contours, it would just look like scribbles as the third shows..
To avoid this if cannot reconstruct the whole surface, insert a NaN between sections to stop the connecting; the above code just replaces the right and bottom edge data with NaN instead of inserting a row/column to illustrate the difference in the resulting contour plot. Now each individual tile looks ok and, in fact, reproduces the original overall because the coordinates are still consistent in the tiles; they just aren't trying to be connected. If the dimensions are large as in OP's case, the breaks may not even be visible.

More Answers (0)

Categories

Asked:

on 29 Sep 2025

Commented:

dpb
on 30 Sep 2025

Community Treasure Hunt

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

Start Hunting!