How to plot two contour filled plots of two different datasets using different colormap and caxis range in the same axis?
17 views (last 30 days)
Show older comments
Dear all,
I want to plot two contour filled plots of two different variables with different colormaps and caxis ranges in the same axis. I tried with 'hold on' to plot two contour filled plots in the same axis, but it didn't work. Maybe it doesn't work with two contour filled plots?? I have gone through a previous conversation here (https://www.matlab.com/matlabcentral/answers/827960-setting-color-scale-of-two-datasets-in-the-same-axis-in-matlab), and modfied the code as per my case. But, I had no luck. I want the kind of figure like the figure shown in Ding et al. (2020).
I am attaching this figure as a sample for your convenience.
Can anyone please help me to solve the issue? That will be really helpful for me. My modifed MATLAB code is given below:
figure(1)
% one axes
contourf(X,Y,A,100,'linecolor','none')
cb1 = colorbar;
caxis([-2 2])
xlim([20 26])
ylim([100 1000])
h1 = gca;
h2 = axes;
% the other axes
contourf(X,Y,B,100,'linecolor','none')
% set(h2,'Color','none')
caxis([-0.25 0.25])
xlim([20 26])
ylim([100 1000])
cb2 = colorbar;
box on
set(h1,'yscale','log','YDir','reverse','Position', [0.45,0.48,0.26,0.42],'YTick','','YTickLabel','','XTick','','XTickLabel','',...
'FontName', 'Arial','FontSize',18,'FontWeight','bold','LineWidth', 1.5)
set(h2,'yscale','log','YDir','reverse','Position', [0.45,0.48,0.26,0.42],'YTick','','YTickLabel','','XTick','','XTickLabel','',...
'FontName', 'Arial','FontSize',18,'FontWeight','bold','LineWidth', 1.5)
% store the position and limits because adjusting the colorbar will mess these up
axpos = get(h1,'position');
xl = get(h1,'xlim');
yl = get(h1,'ylim');
set(cb1,'Position',[0.718,0.483,0.007,0.199],'YTick',-2:0.5:2,'FontName', 'Arial','FontSize',10.5,'FontWeight','bold','LineWidth', 1.5)
set(cb2,'Position',[0.718,0.698,0.007,0.199],'YTick',-0.25:0.1:0.25,'FontName', 'Arial','FontSize',10.5,'FontWeight','bold','LineWidth', 1.5)
% reassert axes geometry so they match
set(h1,'position',axpos,'xlim',xl,'ylim',yl);
set(h2,'position',axpos,'color','none','xlim',xl,'ylim',yl);
% set one colormap for each axes
cmap1 =jet(40); % Specify the desired number of colors
colormap(h1,cmap1)
cmap2 =parula(60); % Specify the desired number of colors
colormap(h2,cmap2)
4 Comments
DGM
on 20 Nov 2023
I'm a bit distracted at the moment, but as I'm sure you've found out by now, you can't do this in a single parent axes (or at least not reasonably). As in the linked thread, you need to use two overlaid axes and you'd then also need to manipulate the transparency of the upper contour() object accordingly.
Manipulating the contour transparency is a bit of an obstacle, depending on the version.
Contour objects had a scalar FaceAlpha property added in R2022b, so that doesn't help you either way. The first two options may be useful.
There may be other simpler options available via strategic selection of the LevelList property of the contour object. Having relevant example data would help.
Accepted Answer
DGM
on 21 Nov 2023
Edited: DGM
on 21 Nov 2023
I just threw together two different examples using the ways I mentioned. Neither is ideal. Manipulating contour() objects is just problematic. Some part of my brain is telling me that there's something I'm missing, but that's probably just the sleep deprivation talking.
This example demonstrates how truncating the LevelList can be used to open up the periphery of a contour. This only works if the "background" of the upper contour at its periphery corresponds to its minimal values (like a 2D gaussian or something)
% make some fake Z data from some images
A = imread('a.png');
B = imread('b.png');
A = im2double(A)*50 - 25;
B = im2double(B)*100;
% the background axes
contourf(A,'edgecolor','none');
cb1 = colorbar;
h1 = gca;
h2 = axes;
% the foreground axes
[~,hc2] = contourf(B,'edgecolor','none');
set(h2,'color','none') % make the axes background itself invisible
cb2 = colorbar;
% make the base of the upper contour transparent by truncating LevelList
% this approach really only works if you're truncating the lower levels
% is there a workaround? i don't know.
hc2.LevelList(1) = [];
% store the position and limits because adjusting
% the colorbar will mess these up
axpos = get(h1,'position');
xl = get(h1,'xlim');
yl = get(h1,'ylim');
% adjust the colorbars so they don't overlap
barl = 0.48;
cb1.Position(2) = cb1.Position(2)+cb1.Position(4)*(1-barl);
cb1.Position(4) = cb1.Position(4)*barl;
cb2.Position(4) = cb2.Position(4)*barl;
% reassert axes geometry so they match
set(h1,'position',axpos,'xlim',xl,'ylim',yl);
set(h2,'position',axpos,'color','none','xlim',xl,'ylim',yl);
% set one colormap for each axes
colormap(h1,turbo)
colormap(h2,summer)
This uses manipulation of undocumented properties to control transparency. This is ugly, and will probably become problematic. Changes to the figure will cause the transparency to be reverted. Other than setting up an update function, is there a way to avoid this problem? I don't know.
figure
% make some fake Z data from some images
A = imread('a.png');
B = imread('b.png');
A = im2double(A)*50 - 25;
B = im2double(B)*100;
% the background axes
contourf(A,'edgecolor','none');
cb1 = colorbar;
h1 = gca;
h2 = axes;
% the foreground axes
[~,hc2] = contourf(B,'edgecolor','none');
set(h2,'color','none') % make the axes background itself invisible
cb2 = colorbar;
% store the position and limits because adjusting
% the colorbar will mess these up
axpos = get(h1,'position');
xl = get(h1,'xlim');
yl = get(h1,'ylim');
% adjust the colorbars so they don't overlap
barl = 0.48;
cb1.Position(2) = cb1.Position(2)+cb1.Position(4)*(1-barl);
cb1.Position(4) = cb1.Position(4)*barl;
cb2.Position(4) = cb2.Position(4)*barl;
% reassert axes geometry so they match
set(h1,'position',axpos,'xlim',xl,'ylim',yl);
set(h2,'position',axpos,'color','none','xlim',xl,'ylim',yl);
% set one colormap for each axes
colormap(h1,turbo)
colormap(h2,summer)
% manipulate transparency via undocumented descendant objects
% this is copied from 1659975, though you may not need the flexibility
% need to force the object to be initialized
% otherwise it may take a second or two before it exists
% all these changes are volatile and will need to be reasserted if the figure is changed
drawnow
filltriangles = hc2.FacePrims;
% set the fill objects to transparent
for k = 1:length(filltriangles)
% Have to set this. The default is 'truecolor' which ignores alpha.
filltriangles(k).ColorType = 'truecoloralpha';
% The 4th element is the 'alpha' value. First 3 are RGB. Note, the
% values expected are in range 0-255.
%filltriangles(k).ColorData(4) = 128;
end
% if you want to make the contour background regions fully transparent
filltriangles(1).ColorData(4) = 0;
With any luck, this junk answer will invoke Cunningham's law.
More Answers (0)
See Also
Categories
Find more on Contour Plots 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!