如何在Matlab中为冰川三层3D表面配置独立色图?
解决Matlab中冰川3D地图多图层独立色图问题
Matlab的坐标轴默认共享一个色图,直接修改colormap会覆盖所有图层颜色,freezeColors兼容性较差。最可靠的方案是直接为每个曲面生成独立的RGB颜色矩阵,脱离对坐标轴色图系统的依赖。
修改思路
- 对每个图层的高程数据做归一化,映射到对应色图的索引范围
- 使用
ind2rgb将索引转换为RGB颜色矩阵,直接赋值给曲面的CData - 每个曲面的颜色完全独立,不受全局色图影响
修改后的完整代码
close all; clear; clc; % Load data bedrock = double(geotiffread('bedrock_oct2023.tif')); icethick = ncread(file_name, 'icethick'); h_debris = ncread(file_name, 'h_debris'); % Define grid for plotting [X, Y] = meshgrid(1:size(bedrock, 2), 1:size(bedrock, 1)); % Compute initial elevations elevation_glacier = bedrock + icethick(:, :, 1); elevation_debris = bedrock + icethick(:, :, 1) + h_debris(:, :, 1); % Create figure figure('Position', [100 100 1200 800]); ax = axes; hold(ax, 'on'); % Define colormaps bedrock_cmap = copper(256); glacier_cmap = winter(256); debris_cmap = parula(256); % 定义统一的高程范围(根据实际数据调整) elev_min = 2000; elev_max = 4500; % -------------------------- 基岩图层 -------------------------- bedrock_alpha = double(icethick(:, :, 1) == 0); % 冰川覆盖区域透明 % 归一化高程到色图索引范围 bedrock_norm = round((bedrock - elev_min)/(elev_max - elev_min)*255 + 1); bedrock_norm(bedrock_norm < 1) = 1; bedrock_norm(bedrock_norm > 256) = 256; % 转换为RGB颜色矩阵 bedrock_rgb = ind2rgb(bedrock_norm, bedrock_cmap); % 绘制基岩,直接使用RGB颜色 bedrock_surf = surf(ax, X, Y, bedrock, ... 'FaceColor', 'texturemap', 'FaceAlpha', 1, ... 'AlphaData', bedrock_alpha, 'EdgeColor', 'none'); set(bedrock_surf, 'CData', bedrock_rgb); % -------------------------- 冰川图层 -------------------------- glacier_norm = round((elevation_glacier - elev_min)/(elev_max - elev_min)*255 + 1); glacier_norm(glacier_norm < 1) = 1; glacier_norm(glacier_norm > 256) = 256; glacier_rgb = ind2rgb(glacier_norm, glacier_cmap); glacier_surf = surf(ax, X, Y, elevation_glacier, ... 'FaceColor', 'texturemap', 'FaceAlpha', 1, 'EdgeColor', 'none'); set(glacier_surf, 'CData', glacier_rgb); % -------------------------- 碎屑图层 -------------------------- debris_norm = round((elevation_debris - elev_min)/(elev_max - elev_min)*255 + 1); debris_norm(debris_norm < 1) = 1; debris_norm(debris_norm > 256) = 256; debris_rgb = ind2rgb(debris_norm, debris_cmap); debris_surf = surf(ax, X, Y, elevation_debris, ... 'FaceColor', 'texturemap', 'FaceAlpha', 1, 'EdgeColor', 'none'); set(debris_surf, 'CData', debris_rgb); % -------------------------- 冰川遮罩 -------------------------- glacier_mask_elev = bedrock + icethick(:, :, 1); mask_surf = surf(ax, X, Y, glacier_mask_elev, ... 'FaceAlpha', 'interp', 'EdgeColor', 'w'); set(mask_surf, 'FaceColor', 'white'); alpha_data = (glacier_mask_elev ~= bedrock); set(mask_surf, 'AlphaData', alpha_data); % -------------------------- 颜色条设置 -------------------------- % 基岩颜色条 cb1 = colorbar('Position', [0.92 0.1 0.02 0.2]); colormap(cb1, bedrock_cmap); caxis(cb1, [elev_min elev_max]); title(cb1, 'Bedrock'); % 冰川颜色条 cb2 = colorbar('Position', [0.92 0.4 0.02 0.2]); colormap(cb2, glacier_cmap); caxis(cb2, [elev_min elev_max]); title(cb2, 'Glacier'); % 碎屑颜色条 cb3 = colorbar('Position', [0.92 0.7 0.02 0.2]); colormap(cb3, debris_cmap); caxis(cb3, [elev_min elev_max]); title(cb3, 'Debris'); % -------------------------- 轴与视图设置 -------------------------- xlabel('X (m)'); ylabel('Y (m)'); zlabel('Elevation (m)'); set(ax, 'XDir', 'reverse', 'FontSize', 14); title('3D View of Glacier, Debris, Bedrock, and Glacier Mask Surface'); set(gcf, 'color', 'white'); view(45, 35); shading interp; camlight('left'); camlight('right'); material dull; lighting phong;
关键修改点说明
- 将每个曲面的
FaceColor设置为texturemap,支持直接使用RGB矩阵作为CData - 对高程数据做归一化处理,确保各图层颜色映射的范围一致
- 移除了依赖全局色图的
caxis和freezeColors调用,完全通过RGB矩阵控制图层颜色
内容的提问来源于stack exchange,提问作者Yoni Verhaegen
相关产品推荐
相关产品推荐

