70 views (last 30 days)
Show older comments
Ira on 2 Aug 2024 at 18:27
Edited: Walter Roberson on 2 Aug 2024 at 23:14
Hello,
I have been trying to plot two surface plots on top of each other in the same figure - one that is semitransparent, and one that is opaque - using two colormaps to display them. Specifically, I would like surface plot 1 to use the 'turbo' colormap, and surface plot 2 to use the 'gray' colormap and be semitransparent. So far, I have read through a few people with similar problems but their solutions don't help me (most are requesting only 1 specific color per each map and not an entire colormap). How can I do this? Thanks. I cannot provide code due to proprietary information, so any example code given, I will gladly fit to my own.
4 Comments Show 2 older commentsHide 2 older comments
Show 2 older commentsHide 2 older comments
Umar on 2 Aug 2024 at 19:03
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2142546-plotting-two-surface-plots-in-the-same-figure-using-two-different-colormaps#comment_3227961
Hi @Ira,
First, I will generate data for the two surface plots, I will use functions like peaks , if you want yiu can define your own data matrices.
[X, Y, Z1] = peaks(30); % Data for the first surface plot
Z2 = peaks(30) - 5; % Data for the second surface plot
Then I will plot the first surface plot using the 'turbo' colormap per your description.
figure;
surf(X, Y, Z1, 'FaceColor', 'interp', 'EdgeColor', 'none');
colormap turbo;
colorbar;
Then, plot the second surface plot using the 'gray' colormap and make it semitransparent by adjusting the alpha value, again per your description.
hold on;
surf(X, Y, Z2, 'FaceColor', 'interp', 'EdgeColor', 'none', 'FaceAlpha', 0.5);
colormap gray;
Finally, you can further customize the plot by adding labels, titles, adjusting the view, or any other modifications as needed.
xlabel('X-axis');
ylabel('Y-axis');
zlabel('Z-axis');
title('Combined Surface Plots');
view(3); % Adjust the view angle if needed
Please see attached plot. Hope, this answers your question.
Walter Roberson on 2 Aug 2024 at 19:38
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2142546-plotting-two-surface-plots-in-the-same-figure-using-two-different-colormaps#comment_3227996
@Umar
That will not work. Each axes has only a single colormap. The colormap gray you invoke will override the colormap turbo that was previously set.
Umar on 2 Aug 2024 at 20:06
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2142546-plotting-two-surface-plots-in-the-same-figure-using-two-different-colormaps#comment_3228026
@Walter, thanks for pointing this out.
Umar on 2 Aug 2024 at 21:15
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2142546-plotting-two-surface-plots-in-the-same-figure-using-two-different-colormaps#comment_3228066
Edited: Umar on 2 Aug 2024 at 21:21
Hi @Ira,
The updated code snippet demonstrates adjusting the colormaps and overlaying the axes,and efficiently presents two distinct surfaces with varying color representations. Here is updated code along with attached plot.
% Define the colormap for the second axis
colormap(gray);
% Generate meshgrid data
[X, Y] = meshgrid(-2:0.1:2);
% Sample data for surface plot 1
Z1 = X.^2 - Y.^2;
% Sample data for surface plot 2
Z2 = sin(X) + cos(Y);
% Create a figure
figure;
% Create subplots for each surface plot
ax1 = subplot(1,2,1); % Axes for surface plot 1
ax2 = subplot(1,2,2); % Axes for surface plot 2
% Plot the first surface on the first axis
surf(ax1, X, Y, Z1, 'FaceColor', 'interp', 'EdgeColor', 'none');
colormap(ax1, turbo);
% Plot the second surface on the second axis
surf(ax2, X, Y, Z2, 'FaceColor', 'interp', 'EdgeColor', 'none', 'FaceAlpha', 0.5);
% Adjust the colormap for the second axis
colormap(ax2, gray);
% Overlay the second axis on top of the first axis
set(ax2, 'Position', get(ax1, 'Position'));
% Hide the second axis
axis(ax2, 'off');
Replacing Z1 & Z2 data with the following data below will display the attached plot below.
Z1 = peaks(41)-5; % Data for the first surface plot with correct dimensions
Z2 = peaks(41)-5; % Data for the second surface plot with correct dimensions
Sign in to comment.
Sign in to answer this question.
Answers (2)
Walter Roberson on 2 Aug 2024 at 19:44
You have two choices:
- Use seperate plotting axes. Each axes can have its own colormap. Make sure you pass the axes handle into the colormap() calls. You can ax2 = axes('Position', get(ax1, 'Position')) to place the second axes exactly where the first axes is, and then be careful to pass ax1 or ax2 as appropriate to each graphics operation.
- Alternately, plot normally with one colormap, and then call https://www.mathworks.com/matlabcentral/fileexchange/7943-freezecolors-unfreezecolors to convert the graphics object from indexed to RGB. Once the object is converted to RGB, colormap stops affecting it, so you can then go ahead and colormap the second palette.
2 Comments Show NoneHide None
Show NoneHide None
Sean Cupitt on 2 Aug 2024 at 19:47
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2142546-plotting-two-surface-plots-in-the-same-figure-using-two-different-colormaps#comment_3228001
Open in MATLAB Online
Choice number 1 above would look like this, building on Umar's original data:
[X, Y, Z1] = peaks(30); % Data for the first surface plot
Z2 = peaks(30) - 5; % Data for the second surface plot
figure;
ax1 = axes; % create an axis that will hold the first surface plot
s1 = surf(ax1, X, Y, Z1, 'FaceColor', 'interp', 'EdgeColor', 'none');
ax2 = axes; % create an axis for the second surface plot
s2 = surf(ax2, X, Y, Z2, 'FaceColor', 'interp', 'EdgeColor', 'none', 'FaceAlpha', 0.5);
colormap(ax1,'turbo'); colorbar; % change the color of s1
colormap(ax2,'gray'); % change the color of s2
ax2.Color = 'none'; % set the background color for ax2 to transparent
% make sure they inhabit the same space on the figure
ax2.Position = ax1.Position;
% make the scaling/rotation consistent
linkaxes([ax1 ax2]);
Walter Roberson on 2 Aug 2024 at 20:28
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2142546-plotting-two-surface-plots-in-the-same-figure-using-two-different-colormaps#comment_3228031
That code looks good, @Sean Cupitt
Sign in to comment.
Adam Danz on 2 Aug 2024 at 19:48
Edited: Adam Danz on 2 Aug 2024 at 21:43
Open in MATLAB Online
Assign two surface objects two different colormaps using Truecolor arrays
The recommended approach is to create an overlayed axes so that each surface gets its own axes and a colormap can be applied to each axes (doc link).
But let's explore a different solution. Instead of mapping colors, set the surface's color data using a Truecolor array. I've included a little helper function colormapToTruecolor to convert color map values into Truecolor values.
% Create surface data
R=20;
r=5;
[a, b] = meshgrid(0:20/180*pi:2*pi);
X=((R-r)+r*cos(a)).*cos(b);
Y=((R-r)+r*cos(a)).*sin(b);
Z=r.*sin(a);
% create the first surface using colors from the winter colormap
fig = figure();
tcl = tiledlayout(fig,1,1);
ax = nexttile(tcl);
surf1Colormap = winter();
tc = colormapToTruecolor(surf1Colormap,Z);
hsurf1 = surf(ax,X,Y,Z,tc,'FaceColor','interp','EdgeAlpha',0.3);
% create second surface using colors from the autumn colormap
hold on
surf2Colormap = spring();
tc = colormapToTruecolor(surf2Colormap,Z);
hsurf2 = surf(ax,X,Y+20,Z,tc,'FaceColor','interp','EdgeAlpha',0.3);
rotate(hsurf2,[0 1 0],45)
axis equal
view([28,24])
% Assign colormaps (which wont' affect the surfaces) and add colorbars
% A second, hidden axes is needed to host the second colormap.
axHidden = axes(tcl,'visible','off','HandleVisibility','off');
colormap(ax,surf1Colormap)
colormap(axHidden,surf2Colormap)
cb1 = colorbar(ax);
cb1.Layout.Tile = 'east';
cb1.Label.String = 'Surface 1';
cb2 = colorbar(axHidden);
cb2.Layout.Tile = 'east';
cb2.Label.String = 'Surface 2';
function tc = colormapToTruecolor(map,ZData)
% map is a n-by-3 colormap matrix
% ZData is a k-by-w matrix of ZData (or CData, I suppose)
% tc is a kxwx3 Truecolor array based on map and ZData values.
tcIdx = round(rescale(ZData,1,height(map)));
tc = reshape(map(tcIdx,:),[size(ZData),3]);
end
Why this is better than using axes overlays
Sometimes this problem is solved by overlaying two axes, assinging a surface and colormap to each axes, and making the top axes invisible. A lot of care must be taken to get this right. Several properties must match between the two sets of axes, the most important being axis position, axis limits, and axis direction, and DataAspectRatio, but other property mismatches between the two sets of axes can thrown off the correspondance. Then there's axes interactions. If you pan or zoom, the axes should move together. linkaxes along with linkprop can help with that but neither respond to pressing the restore button on the axes toolbar.
The approach above using Truecolor arrays requires a second invisible axes but its only purpose is to host the second colormap so the figure can have two colorbars. Importantly, the two objects are in the same axes so no wizardry is needed to share the same data space.
Also, the single-axes Truecolor approach allows for surfaces to intersect! The two figure below contain the same surfaces and the same viewing angles but the one on the left uses axes overlays which prevents the surfaces from intersecting!
2 Comments Show NoneHide None
Show NoneHide None
Umar on 2 Aug 2024 at 21:54
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2142546-plotting-two-surface-plots-in-the-same-figure-using-two-different-colormaps#comment_3228096
Edited: Walter Roberson on 2 Aug 2024 at 23:14
Hi @Admam Danz,
The choice between overlaying axes and using Truecolor arrays depends on the specific requirements of the visualization and the desired interactions between the surfaces and colormaps. Each approach has its advantages and considerations based on the complexity and flexibility needed in the visualization. Also, in addition to your thoughts, I might add suggesting alphamap function by overlaying colormaps in MATLAB without the complexities of overlaying axes and simplifying the process and avoiding the need for managing multiple axes properties. For more information on this function, please refer to https://www.mathworks.com/help/matlab/ref/alphamap.html It was very helpful and quite interesting about what you mentioned in “ Why this is better than using axes overlays”, it reminded me about a journal which belonged to a friend of mine whom I met few years ago , “ The Brain Is A Universe Within Us, And Neurologists Are The Explorers Of That Inner Cosmos: The Neurology Journal : A Journal for Neuro Doctor, Brain ... Insights and Discoveries about Neuroscience”.
Adam Danz on 2 Aug 2024 at 22:19
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2142546-plotting-two-surface-plots-in-the-same-figure-using-two-different-colormaps#comment_3228101
One advantage of the axes overlay approach is that the colormap and objects are still linked such that setting clim or changing the CData will update the surface and colorbar. I'd be interested in hearing any other advantages of the axes overlay approach.
Sign in to comment.
Sign in to answer this question.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- Deutsch
- English
- Français
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)
Contact your local office