What exactly is this 3D object inside my axis and how to attach it to a colormap?
1 view (last 30 days)
Show older comments
Commented: Alexei M on 12 May 2020
I have a figure that was generated by a collaborator, and it's a result of some kind of integration with COMSOL, a software for doing simulations. The simulation was done in COMSOL, and the output is generated as a .fig file so it can be viewed in Matlab. This is what I get (though I removed the x and y-axis labels):
I can't quite figure out exactly what kind object (is that the correct terminology?) is actually inside the axis. Because it looks like a surface plot in the sense that I can look at the 3D structure from any angle. But when I try to change the colormap, only the color bar changes. From browsing other questions, etc., my understanding is that only some objects that can be inside an axis are actually tied to a colormap. And a surface plot is one of them. But if this is not a surface plot, then what is it? How can it still have a 3D shape?
And--more importantly for practical purposes--how do I force it to use a colormap which I can then control and change? Ultimately I want to manipulate the colors to make it match the coloring scheme in my other figures.
EDIT: attached figure file
Stephen23 on 8 May 2020
Edited: Stephen23 on 11 May 2020
That figure contains four objects, the fourth one listed is the main axes:
>> fgh = openfig('Resultplot_ID3.fig');
4x1 graphics array:
Axes (Surface: Displacement field, Z component (m))
The main axes has just one child object, which is a patch object:
>> pah = fgh.Children(4).Children;
Patches have several ways of defining their colors based on the axes colormap, explained here:
But the patch in your figure does not use any of those. It uses what the MATLAB documentation calls "truecolor", where the color is explicitly defined using RGB values, and has absolutely nothing to do with the axes colormap.
>> size(pah.CData) % truecolor (i.e. RGB), nothing to do with the colormap!
3 114912 3
You can read more about how that works in the patch documentation, e.g.:
"... how to attach it to a colormap?"
The answer is that you would have to replace the truecolor RGB values in CData and/or FaceVertexCData with indices into the colormap, following the array sizes given in the documentation. Unfortunately MATLAB makes it a bit tricky to get the original colormap data (does anyone know a better way?), but the rest is quite simple:
>> warning off
>> S = load('Resultplot_ID3.fig','-mat'); % import as a structure
>> warning on
>> old = S.hgS_070000.children(2).properties.Colormap; % old colormap
>> image(permute(old,[3,1,2])) % optional: view the colormap
>> [idx,idy] = ismember(pah.FaceVertexCData,old,'rows'); % indices of patch colors in colormap
>> all(idx) % check that all colors used in patch exist in colormap
>> pah.FaceVertexCData = idy; % replace truecolor with indices
>> pah.CDataMapping = 'direct';
Now the patch colors are "attached" to the colormap, exactly as you requested. This only needs to be done once: after that you can simply change the figure colormap to any which has 256 colors, e.g.:
>> colormap(fgh,autumn(256)) % any colormap you want, must be 256 colors!
Alternatively you could have to update the CData and/or the FaceVertexCdata properties with new RGB values, but this requires updating those arrays everytime you want to change the colormap (i.e. it does not actually "attach" the patch colors to the colormap as you request).
More Answers (1)
Ameer Hamza on 8 May 2020
Edited: Ameer Hamza on 9 May 2020
I am not sure why anyone would use patches instead of a surface object to make such a plot. However, the following shows a simple way to modify the "colormap" of the patches and colorbar
fig = openfig('Resultplot_ID3.fig');
p = findobj(fig, 'type', 'patch');
[clrs, ~, idx] = unique(p.FaceVertexCData, 'rows');
new_colormap = cool; % <<==== new colormap name. It you make a custom colormap, it must have 256 RGB colors
new_colormap(171:end,:) = flipud(new_colormap(171:end,:));
p.FaceVertexCData = new_colormap(idx, :);
Note: As pointed out by Stephen in the comments, the output of unique() is not necessarily an ordered colormap. For the figure you attached in the question, there was just a single discontinuity, so fixing it was easy. However, for a general case, you need another method to first arrange the output of unique() into a colormap. One interesting method is to use HSV colorspace as described here: https://stackoverflow.com/questions/2245842/sorting-colors-in-matlab
Also read the following links
Find more on Red in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!Start Hunting!