Причина, по которой вышеприведенное не работает, заключается в том, что colormap
использует feval
, поэтому в исходном сообщении строка, которая не работает (colormap('my_map');
), выдает следующую ошибку:
Error using feval
Undefined function or variable 'my_map'.
Способ обойти это - создать файл .m в папке в пути MATLAB, который использует функцию feval
, и сохранить файл mat с цветовой картой rgb, к которой он обращается.Т.е. в папке в пути MATLAB создайте два файла:
% file 1: my_map.m
function my_map_1 = my_map()
load('my_map_mat');
my_map = my_map_mat; % file 2: my_map_mat.mat is a mat file with rgb values for the custom colormap.
end
Ниже приведена функция, которую я написал, которая делает это.Я не очень-то очищал ее от своей версии функции перед публикацией, но ключевые части находятся внизу, начиная со строки eval([cmap_name '_mat = cmap_1;']);
% cmap_name : name of custom colormap
% cmap_data : 1- or 3-column matrix, or name of text file with 1 or 3 columns, containing colormap data.
% by default, interpolates custom colormap to have 256 rgb values.
function cmap(cmap_name, cmap_data, varargin)
pnames = {'output_folder', 'method', 'map_length'};
dflts = {'path\to\folder\in\MATLAB\path\where\you\want\to\store\custom\colormaps\', 'nearest', 256};
[output_folder, method, map_length] = internal.stats.parseArgs(pnames, dflts, varargin{:});
if ~ strcmp(cmap_name, lower(cmap_name))
disp(['cmap_name changed from ' cmap_name 'to ' lower(cmap_name) '.']);
end
cmap_name = lower(cmap_name); % Windows has issues if you don't do this
if ~ (any(ismember(output_folder(1 : end - 1), regexp(path, pathsep, 'Split'))) || strcmp(output_folder(1 : end - 1), pwd))
error('output folder must be in present working directory or MATLAB path. To add it to MATLAB path, use addpath function.');
end
if strcmp(class(cmap_data), 'char')
fid = fopen(cmap_data);
cmap_1 = textscan(fid, '%f');
cmap_1 = cmap_1{1};
fclose(fid);
elseif strcmp(class(cmap_data), 'double')
cmap_1 = cmap_data;
else
error('cmap_data must be double arr, or name of text file containing doubles.')
end
if min(flat(cmap_1)) < 0 || max(flat(cmap_1)) > 1
error('cmap_data must not contain values below 0 or above 1.');
end
cmap_size = size(cmap_1);
if ~ ismember(cmap_size(2), [1 3])
error('cmap_data must be array or name of text file with either 1 column or 3 columns.');
end
if isequal(cmap_size(2), 1)
cmap_1 = [cmap_1 cmap_1 cmap_1];
end
if ~ (cmap_size(1) == map_length)
cmap_1 = interp1(1:length(cmap_1), cmap_1, linspace(1, length(cmap_1), map_length), method);
end
eval([cmap_name '_mat = cmap_1;']);
save([output_folder cmap_name '_mat.mat'], [cmap_name '_mat']);
fid = fopen([output_folder cmap_name '.m'], 'w');
function_str = {
['function my_map = ' cmap_name '()']...
[' load(''' cmap_name '_mat'');']...
[' my_map = ' cmap_name '_mat;']...
['end']...
};
for i = 1:length(function_str)
fprintf(fid, '%s\n', strcat(function_str{i}));
end
fclose(fid);
end
Так что теперь это можно использовать, например:, следующим образом:
hex = ['#ff0000'; '#00ff00';];
vec = [100; 0];
raw = sscanf(hex','#%2x%2x%2x',[3, size(hex,1)] ).' / 255;
my_map = interp1(vec,raw,linspace(100, 0, 256),'pchip');
cmap('my_map', my_map);
x = linspace(0, 255, 255);
y = linspace(0, 255, 255);
[X Y] = meshgrid(x, y);
figure, imagesc(x, y, X);
colormap(my_map); % this line works, as does the line below it.
colormap('my_map'); % this line works, as does the line above it.
colorbar();