Problem with double colorbar in matlab
56 ビュー (過去 30 日間)
古いコメントを表示
I have two sets of points, z1 and z2, from the same function, sampled at different points: z1 is sampled at (x1, y1) and z2 at (x2, y2). I would like to plot both functions on the same scatter 3D plot, but with two different colorbars: one using the "autumn" colormap and the other using the "winter" colormap.
In MATLAB 2024b, everything works as expected. However, when I run the same code (provided below) in MATLAB 2023b, sometimes the two colorbars display the same color (matching the last set, x2, y2, z2). It seems random when the code works properly and when it instead results in two identical colorbars.
Does anyone have an idea of what could be causing this issue and how to resolve it? Any help would be greatly appreciated!
EDIT : I have modified the code, and now it doesn’t work even in the online MATLAB compiler. I want to use two colormaps from Crameri’s scientific colormaps (see crameri perceptually uniform scientific colormaps - File Exchange - MATLAB Central and Scientific colour maps – colour-blind friendly and accurate palettes). If those colormaps are not installed, I would like to fall back on MATLAB’s "autumn" and "winter" colormaps.
At the end of the code, I check whether the colormap vectors for ax1 and ax2 are the same, and the result is no. Any ideas on why this happens?
clear all; close all; clc
% First sample point set
x1 = deg2rad(linspace(0, 360, 10));
x2 = deg2rad(linspace(0, 360, 10) + 360/20);
% Second sample point set
y1 = deg2rad(linspace(0, 360, 12));
y2 = deg2rad(linspace(0, 360, 12) + 360/24);
% Sampling
[xx1, yy1] = meshgrid(x1, y1); xx1 = reshape(xx1, 120, 1); yy1 = reshape(yy1, 120, 1);
[xx2, yy2] = meshgrid(x2, y2); xx2 = reshape(xx2, 120, 1); yy2 = reshape(yy2, 120, 1);
z1 = cos(2*xx1 + 1*yy1);
z2 = cos(2*xx2 + 1*yy2);
figure();
% First set (x1, y1, z1)
ax1 = axes;
% I would like to use just 80% of the color bar, so I scale the z-values up to 0.8*256
zscaled = (0.8*256-1)/(max(z1, [], "all")-min(z1, [], "all")).* z1 ...
+ 1 - (0.8*256-1)/(max(z1, [], "all")-min(z1, [], "all")) * min(z1, [], "all");
% Try to use a colormap from scientific colormaps of Crameri. See:
% https://it.mathworks.com/matlabcentral/fileexchange/68546-crameri-perceptually-uniform-scientific-colormaps
try
load("lajolla.mat")
cm1 = colormap(lajolla);
catch e % Otherwise use autumn
if strcmp(e.identifier,'MATLAB:load:couldNotReadFile')
cm1 = colormap(autumn);
else
rethrow(e)
end
end
scatter3(ax1, xx1, yy1, z1, 50, cm1(ceil(zscaled), :), "filled");
grid on;
hold on;
ylabel("x")
xlabel("y")
% Second set (x2, y2, z2)
ax2 = axes;
zscaled = (0.8*256-1)/(max(z2, [], "all")-min(z2, [], "all")).* z2 ...
+ 1 - (0.8*256-1)/(max(z2, [], "all")-min(z2, [], "all")) * min(z2, [], "all");
% As above, try to use a colormap from scientific colormaps of Crameri
try
load("oslo.mat")
cm2 = colormap(oslo);
catch e % Otherwise use winter
if strcmp(e.identifier,'MATLAB:load:couldNotReadFile')
cm2 = colormap(winter);
else
rethrow(e)
end
end
scatter3(ax2, xx2, yy2, z2, 30, cm2(ceil(zscaled), :), "filled");
% Linking axes
linkaxes([ax1,ax2])
ax2.Visible = 'off';
ax2.XTick = [];
ax2.YTick = [];
% Giving colormap for each axis
% I scale the colormaps up to 80% of their range, in order to not plot in the colorbar the 20% not used.
if exist("lajolla", "var")
colormap(ax1, lajolla(1:ceil(0.8*256)+1, :));
else
cm1 = colormap(autumn);
colormap(ax1, cm1(1:ceil(0.8*256)+1, :));
end
if exist("oslo", "var")
colormap(ax2, oslo(1:ceil(0.8*256)+1, :));
else
cm2 = colormap(winter);
colormap(ax2, cm2(1:ceil(0.8*256)+1, :));
end
set([ax1, ax2], 'Position', [0.17,0.11,0.685,0.815]);
% Plot first colorbar
hcb1 = colorbar(ax1);
hcb1.Position = [0.077666666666667,0.11,0.021333333333333,0.815];
hcb1.Label.String = 'Data 1';
clim(ax1, [min(z1, [], "all"), max(z1, [], "all")])
drawnow
% Plot second colorbar
hcb2 = colorbar(ax2);
hcb2.Position = [0.896,0.11,0.021333333333333,0.815];
hcb2.Label.String = 'Data 2';
clim(ax2, [min(z2, [], "all"), max(z2, [], "all")])
drawnow
% Check if the two axes have the same colormap
isequal(ax1.Colormap, ax2.Colormap)
2 件のコメント
Matt J
2025 年 2 月 22 日 2:10
I've run it a dozen times in 2023b and it always produces different colorbars. But try issuing drawnow() when it happens to see if that impacts anything.
回答 (1 件)
Voss
約11時間 前
The cause of the problem is that the colormap() function sets not only the axes' Colormaps but also the figure's Colormap. Exactly why this is a problem I didn't look into in detail, but you can avoid it by avoiding using the colormap() function and instead set the axes Colormaps as required directly. When this is done, the result seems as intended.
% First sample point set
x1 = deg2rad(linspace(0, 360, 10));
x2 = deg2rad(linspace(0, 360, 10) + 360/20);
% Second sample point set
y1 = deg2rad(linspace(0, 360, 12));
y2 = deg2rad(linspace(0, 360, 12) + 360/24);
% Sampling
[xx1, yy1] = meshgrid(x1, y1); xx1 = reshape(xx1, 120, 1); yy1 = reshape(yy1, 120, 1);
[xx2, yy2] = meshgrid(x2, y2); xx2 = reshape(xx2, 120, 1); yy2 = reshape(yy2, 120, 1);
z1 = cos(2*xx1 + 1*yy1);
z2 = cos(2*xx2 + 1*yy2);
figure();
% First set (x1, y1, z1)
ax1 = axes;
% I would like to use just 80% of the color bar, so I scale the z-values up to 0.8*256
zscaled = (0.8*256-1)/(max(z1, [], "all")-min(z1, [], "all")).* z1 ...
+ 1 - (0.8*256-1)/(max(z1, [], "all")-min(z1, [], "all")) * min(z1, [], "all");
% Try to use a colormap from scientific colormaps of Crameri. See:
% https://it.mathworks.com/matlabcentral/fileexchange/68546-crameri-perceptually-uniform-scientific-colormaps
try
load("lajolla.mat")
cm1 = lajolla;
catch e % Otherwise use autumn
if strcmp(e.identifier,'MATLAB:load:couldNotReadFile')
cm1 = autumn();
else
rethrow(e)
end
end
scatter3(ax1, xx1, yy1, z1, 50, cm1(ceil(zscaled), :), "filled");
grid on;
hold on;
ylabel("x")
xlabel("y")
% Second set (x2, y2, z2)
ax2 = axes;
zscaled = (0.8*256-1)/(max(z2, [], "all")-min(z2, [], "all")).* z2 ...
+ 1 - (0.8*256-1)/(max(z2, [], "all")-min(z2, [], "all")) * min(z2, [], "all");
% As above, try to use a colormap from scientific colormaps of Crameri
try
load("oslo.mat")
cm2 = oslo;
catch e % Otherwise use winter
if strcmp(e.identifier,'MATLAB:load:couldNotReadFile')
cm2 = winter();
else
rethrow(e)
end
end
scatter3(ax2, xx2, yy2, z2, 30, cm2(ceil(zscaled), :), "filled");
% Linking axes
linkaxes([ax1,ax2])
ax2.Visible = 'off';
ax2.XTick = [];
ax2.YTick = [];
% Giving colormap for each axis
% I scale the colormaps up to 80% of their range, in order to not plot in the colorbar the 20% not used.
if exist("lajolla", "var")
tmp = lajolla;
else
tmp = autumn();
end
ax1.Colormap = tmp(1:ceil(0.8*256)+1, :);
if exist("oslo", "var")
tmp = oslo;
else
tmp = winter();
end
ax2.Colormap = tmp(1:ceil(0.8*256)+1, :);
set([ax1, ax2], 'Position', [0.17,0.11,0.685,0.815]);
% Plot first colorbar
hcb1 = colorbar(ax1);
hcb1.Position = [0.077666666666667,0.11,0.021333333333333,0.815];
hcb1.Label.String = 'Data 1';
clim(ax1, [min(z1, [], "all"), max(z1, [], "all")])
drawnow
% Plot second colorbar
hcb2 = colorbar(ax2);
hcb2.Position = [0.896,0.11,0.021333333333333,0.815];
hcb2.Label.String = 'Data 2';
clim(ax2, [min(z2, [], "all"), max(z2, [], "all")])
drawnow
% Check if the two axes have the same colormap
isequal(ax1.Colormap, ax2.Colormap)
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Colormaps についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!