-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcbrewer2.m
260 lines (233 loc) · 8.24 KB
/
cbrewer2.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
%CBREWER2 Interpolated versions of Cynthia Brewer's ColorBrewer colormaps
% CBREWER2(CNAME, NCOL) returns the colour scheme CNAME with the number
% of colours equal to NCOL. If there is a ColorBrewer scheme with exactly
% this number of colours, the color scheme is returned as-is. If NCOL
% larger (or smaller) than the designed colormaps for this scheme, the
% largest (smallest) one is interpolated to provide enough colours,
% unless the requested colour scheme CNAME is a qualitative palette. For
% a qualitative scheme, the colours are repeated, cycling from the
% beginning again, to output the requested NCOL colours.
%
% CBREWER2(CNAME) without an NCOL input will use the same number of
% colours as the current colormap.
%
% CBREWER2(CNAME, NCOL, INTERP_METHOD) allows you to change the method
% used for the interpolation. The default is 'cubic'.
%
% CBREWER2(CNAME, NCOL, INTERP_METHOD, INTERP_SPACE) allows you to
% change the colorspace used for the interpolation. By default, this is
% in the CIELAB colorspace, which is approximately perceptually uniform.
% Options for INTERP_SPACE are
% 'rgb' : interpolation in sRGB (as used in original CBREWER)
% 'lab' : interpolation in CIELAB (default)
% 'lch' : interpolation in CIELCH_ab (not recommended due to the
% discontinuities at C=0 and H=0)
% Anything else supported by COLORSPACE will also function.
%
% The input format CBREWER2(TYPE, ...) can also be used, where TYPE is
% one of 'seq', 'div', 'qual'. This input is redandant and will be
% ignored. This input format is provided for backwards compatibility with
% the original CBREWER.
%
% Example 1 (sequential heatmap):
% C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
% imagesc(C);
% colorbar;
% colormap(cbrewer('YlOrRd', 256);
%
% Example 2 (line plot):
% x = 0:0.01:2;
% sc = [0.5; 1; 2];
% t0 = [0; 0.2; 0.4];
% t = bsxfun(@rdivide, bsxfun(@plus, x, t0), sc);
% y = sin(t * 2 * pi);
% cmap = cbrewer2('Set1', numel(sc));
% axes('ColorOrder', cmap, 'NextPlot', 'ReplaceChildren');
% plot(x, y);
%
% Example 3 (divergent heatmap):
% [X,Y,Z] = peaks(30);
% surfc(X,Y,Z);
% colormap(cbrewer2('RdBu'));
%
% This product includes color specifications and designs developed by
% Cynthia Brewer (http://colorbrewer.org/). For more information on
% ColorBrewer, please visit http://colorbrewer.org/.
%
% CBREWER2 uses a cached copy of the Cynthia Brewer color schemes which
% was converted to .mat format by Charles Robert for use with CBREWER.
% CBREWER is available from the MATLAB FileExchange under the MIT license.
%
% See also CBREWER, BREWERMAP, COLORSPACE, INTERP1.
% Copyright (c) 2016 Scott Lowe
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.
function colormap = cbrewer2(...
cname, ncol, interp_method, interp_space, varargin)
% Definitions -------------------------------------------------------------
% List of all of Cynthia Brewer's colormaps and their types
% seq: sequential
% div: divergent
% qual: qualitative
cbdict = {...
'Blues', 'seq'; ...
'BuGn', 'seq'; ...
'BuPu', 'seq'; ...
'GnBu', 'seq'; ...
'Greens', 'seq'; ...
'Greys', 'seq'; ...
'Oranges', 'seq'; ...
'OrRd', 'seq'; ...
'PuBu', 'seq'; ...
'PuBuGn', 'seq'; ...
'PuRd', 'seq'; ...
'Purples', 'seq'; ...
'RdPu', 'seq'; ...
'Reds', 'seq'; ...
'YlGn', 'seq'; ...
'YlGnBu', 'seq'; ...
'YlOrBr', 'seq'; ...
'YlOrRd', 'seq'; ...
'BrBG', 'div'; ...
'PiYG', 'div'; ...
'PRGn', 'div'; ...
'PuOr', 'div'; ...
'RdBu', 'div'; ...
'RdGy', 'div'; ...
'RdYlBu', 'div'; ...
'RdYlGn', 'div'; ...
'Spectral', 'div'; ...
'Accent', 'qual'; ...
'Dark2', 'qual'; ...
'Paired', 'qual'; ...
'Pastel1', 'qual'; ...
'Pastel2', 'qual'; ...
'Set1', 'qual'; ...
'Set2', 'qual'; ...
'Set3', 'qual'; ...
};
% Input handling ----------------------------------------------------------
narginchk(1, 5);
% Initialise variables if not supplied
if nargin<2
ncol = [];
end
if nargin<3
interp_method = [];
end
if nargin<4
interp_space = [];
end
if nargin<5
varargin = {[]};
end
% Check if the colormap type was unnecessarily input
types = unique(cbdict(:, 2));
if nargin > 1 && ischar(cname) && ischar(ncol)
LI = ismember({cname ncol}, types);
if ~any(LI); error('Number of colors cannot be a string'); end;
if all(LI); error('Incorrect colormap name'); end;
if LI(1)
vgn = {cname; ncol; interp_method; interp_space};
cname = vgn{2};
ncol = vgn{3};
interp_method = vgn{4};
interp_space = varargin{1};
ctype_input = vgn{1};
elseif LI(2)
vgn = {cname; ncol; interp_method; interp_space};
cname = vgn{1};
ncol = vgn{3};
interp_method = vgn{4};
interp_space = varargin{1};
ctype_input = vgn{2};
end
else
ctype_input = '';
end
% Default values
if isempty(ncol)
% Number of colours in the colormap
ncol = size(get(gcf,'colormap'), 1);
end
if isempty(interp_method)
interp_method = 'pchip';
end
if isempty(interp_space)
interp_space = 'lab';
end
% Load colorbrewer data ---------------------------------------------------
Tmp = load('colorbrewer.mat');
colorbrewer = Tmp.colorbrewer;
[TF, idict] = ismember(lower(cname), lower(cbdict(:, 1)));
if ~TF
error('%s is not a recognised Brewer colormap',cname);
end
cname = cbdict{idict, 1};
ctype = cbdict{idict, 2};
if (~isfield(colorbrewer.(ctype), cname))
error('Colormap %s is not present in loaded data',cname);
end
% Main script -------------------------------------------------------------
if ncol > length(colorbrewer.(ctype).(cname))
% If we specified too many colours, we take the maximum and interpolate
colormap = colorbrewer.(ctype).(cname){length(colorbrewer.(ctype).(cname))};
colormap = colormap ./ 255;
elseif isempty(colorbrewer.(ctype).(cname){ncol})
% If we specified too few colours, we take the minimum and interpolate
nmin = find(~cellfun(@isempty, colorbrewer.(ctype).(cname)), 1);
colormap = colorbrewer.(ctype).(cname){nmin};
colormap = colormap./255;
else
% If we specified a number of colours in the pre-designed range, no
% need to interpolate
colormap = (colorbrewer.(ctype).(cname){ncol}) ./ 255;
return;
end
% Don't interpolate if qualitative type
if strcmp(ctype,'qual')
if size(colormap, 1) >= ncol
colormap = colormap(1:ncol, :);
return;
end
warning('CBREWER2:QualTooManyColors', ...
['Too many colors requested: cannot interpolate a qualitative' ...
' colorscheme']);
% Cycle the colours from the beginning again, so we have enough to
% return
colormap = repmat(colormap, ceil(ncol / size(colormap, 1)), 1);
colormap = colormap(1:ncol, :);
return;
end
% Make sure we have colorspace downloaded from the FEX
if ~strcmpi(interp_space, 'rgb') && ~exist('colorspace.m', 'file')
P = requireFEXpackage(28790);
if isempty(P);
error(...
['You need to download COLORSPACE from the MATLAB FEX and' ...
' add it to the MATLAB path.']);
end;
end
% Move to perceptually uniform space
if ~strcmpi(interp_space,'rgb')
colormap = colorspace(['rgb->' interp_space], colormap);
end
% Linearly interpolate
X = linspace(0, 1, size(colormap, 1));
XI = linspace(0, 1, ncol);
colormap = interp1(X, colormap, XI, interp_method);
% Move from perceptually uniform space back to sRGB
if ~strcmpi(interp_space,'rgb')
colormap = colorspace(['rgb<-' interp_space], colormap);
end
end