Control output of a sequence of contourf plots of X,Y,Z in the same figure of data sets with different ranges of magnitudes in Z so all use the same colormap and colorbar

2 views (last 30 days)
I have a set of arrays, {Z sub i}, and a single corresponding positional meshgrid [X,Y] such that each ith array corresponds to the intensity of a function (for which I am trying to display contours) on the meshgrid at regular, increasing values of time, indexed by i=1:N. I am trying to use contourf to plot each Zsubi in the same figure iteratvely to display the time evolution of the function values. That is, I first plot contourf [X,Y,Zsub1], then pause slightly, then plot contourf [X,Y,Zsub2] in the same figure, pause again slightly, then plot contourf[X,Y,Zsub3], and so on. Each time contourf displays the current result in the figure and it appears to be a time lapse view of the evolution of the contours.
The numerical values of Z are log10 of the underlying physics based quantity of interest and I am using integer values for desired levels (input in the contourf call) such as [-4 -3 -2 -1 0 1 2], although sometimes I want to use half integer values, but the resulting problem is still the same. The problem the data presents me is due to the ranges (i.e. the levels) of Zsubi differing as i increases, i.e with increasing time, particularly at early times, say the first 100 or so values of i. By differ I mean that for example, Zsub1 values might range over levels [-2 -1 0 1 2], and Zsub2 might range over [-3 -2 -1 0 1], Zsub3 might range over [-2 -1 0 1 2] again, and later on at larger i, Zsubi might range over [-4 -3 -2 -1 0], and so on.
The display feature I would like to implement is for each subsequent contourf call to use the same assignment of levels to colors in the colormap, regardless of how many and which levels are in that particular contour. I would also like the colorbar to display the entire range of colors (used for all Z) and the same color-value correspondence for all contours. What I am finding is that the contourf with levels of [-2 -1 0 1 2] assigns the 'hottest' color, say red, to the level 2 and moves through the colors starting with that hottest color. (I have tried this with the default color assignments as well as a manual colormap array I input). Then, a subsequent array which has levels [-3 -2 -1 0 1] would assign red to level 1 and step through the colors from there. Subsequent arrays with levels [[-4 -3 -2 -1 0] have the color red assigned to the level 0, and as the array values vary slightly from i value to i value, the color assignments to levels changes back and forth from Zsubi to Zsubj. The colorbar displayed also corresponds to the current plotted contour and bounces back and forth from plot to plot.
I have tried pre-testing all my arrays to find the total range covered by all of them and using an input set of levels to cover the whole range for each call to contourf, and inputting a colormap array that spans the total number of levels. I get the same undesired behavior, namely, the highest value actually present in the contour is assigned to the 'hottest' color, even if it is not the largest value in the input levels, and the color map and colorbar reflects the actual range of the data in Z, not the total set of input levels. My most successful attempt so far has been to get the levels of each Zsubi before calling the contourf, then setting the colormap so that the color value I want to be always assigned to the largest values of Z for that particular case to be the one that is assigned first. (It appears the assignments may work from the bottom up in the colormap-level assignment, i.e. the last color is assigned the highest level, and so on.) This fixes the value-assignment issue (mostly), but the colorbar keeps bouncing back and forth so that it corresponds to the current plot and does not include colors-values that are not on that particular plot. I would like to keep the same full range colorbar visible for all plots. A fix I am trying to figure out now is to just generate a contour that has the full range I would like to see, and get an image of that colorbar. Then I could in principle display that image after each contour plot, but I can't figure out how to position that image (of the universal colorbar) in the current figure but outside of the current axes in the position it is usually displayed by contourf.
I hope this is clear enough. The code itself is entirely unremarkable. Any helpful suggestions would be appreciated.

Accepted Answer

Kartik Saxena
Kartik Saxena on 21 Nov 2023
Hi,
To achieve the desired behavior where each 'contourf' call uses the same assignment of levels to colors in the colormap and keeps the colorbar consistent across all plots, you will need to define a fixed set of contour levels and a consistent colormap. Additionally, you'll have to manually create a colorbar that reflects the entire range of values you want to display, regardless of the current data range.
Here's a step-by-step guide on how to do this in MATLAB:
  1. Determine the full range of contour levels you want to use across all plots. Let's say your levels range from -4 to 2, and you want to include half-integer values.
  2. Define a colormap that spans the total number of levels. You can use one of MATLAB's built-in colormaps or create your own.
  3. Use 'contourf' to plot your data, specifying the fixed set of levels.
  4. Create a custom colorbar that displays the full range of contour levels.
  5. Use a loop to iterate through your data arrays, pausing between each plot to create a time-lapse effect.
I hope this resolves your issue.
Refer to the following MathWorks documentation for detailed information regarding use of 'contourf' function :

More Answers (0)

Categories

Find more on Colormaps in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!