1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) Bruno Pincon
3 // Copyright (C) Serge Steer (adaptation to new graphic system)
4 // Copyright (C) 2012 - 2016 - Scilab Enterprises
5 // Copyright (C) 2017 - 2019 - Samuel GOUGEON
7 // This file is hereby licensed under the terms of the GNU GPL v2.0,
8 // pursuant to article 5.3.4 of the CeCILL v.2.1.
9 // This file was originally licensed under the terms of the CeCILL v2.1,
10 // and continues to be available under such terms.
11 // For more information, see the COPYING file which you should have received
12 // along with this program.
14 function colorbar(umin, umax, colminmax, fmt)
17 // Draw a colorbar for a plot3d, fec, Sgrayplot, etc...
20 // umin : data value corresponding to the colorbar lower bound
21 // umax : data value corresponding to the colorbar upper bound
22 // colminmax : a [cmin cmax] vector providing the colors corresponding
23 // to the [umin, umax] data bounds.
24 // Is a vector of 2 colors indices, where $ stands for the
25 // total number of colors in the current colormap.
26 // Examples: [1 $] // the whole colormap
27 // [$/2 $] // The second half of the colormap
28 // May be useful to deal with a part of the colormap
29 // (for instance using fec or plot3d)
30 // fmt : optional, a C format to display colorbar graduations
33 // 2017 : http://bugzilla.scilab.org/14711 : in uicontrol frame
34 // 2018 : http://bugzilla.scilab.org/15638 : unequal color spans
35 // http://bugzilla.scilab.org/15805 : poor ticking
36 // http://bugzilla.scilab.org/15806 : syntaxes with default umin, umax..
37 // 2019 : http://bugzilla.scilab.org/16232 : Support of $ in colminmax added
38 // http://bugzilla.scilab.org/10553 : gce() is now the colorbar handle
40 // Check number of input argument
43 msg = gettext("%s: Wrong number of input arguments: %d to %d expected.\n")
44 error(msprintf(msg, "colorbar", 0, 4));
47 // TYPE OF THE ASSOCIATED PLOT
48 // ===========================
51 nColorsCM = size(f.color_map,1);
52 for h = gca().children'
53 if or(h.type==["Matplot" "Fec" "Fac3d" "Plot3d" "Grayplot"])
58 if or(g.type==["Matplot" "Fec" "Fac3d" "Plot3d" "Grayplot"])
68 if Type=="Matplot" & h.image_type~="index" then
70 //elseif Type=="Fac3d" & h.cdata_mapping=="direct"
71 // Type = "Matplot" // done later
74 // PARSING INPUT ARGUMENTS
75 // =======================
77 if isdef("colminmax","l") & type(colminmax)==2
78 colminmax = horner(colminmax, nColorsCM)
79 colminmax(colminmax < 1) = 1
80 colminmax(colminmax > nColorsCM) = nColorsCM
82 if isdef("colminmax","l") & type(colminmax)~=0 & colminmax~=[] & colminmax(1)~=-1
83 msg = _("%s: Argument #%d: Decimal number(s) expected.\n")
84 if and(type(colminmax)~=[1 2])| ~isreal(colminmax)
85 error(msprintf(msg, "colorbar", 3))
87 if length(colminmax)~=2
88 msg = _("%s: Argument #%d: Vector with %d elements expected.\n")
89 error(msprintf(msg, "colorbar", 3, 2))
91 colminmax = gsort(colminmax,"g","i");
92 if and(colminmax>=0 & colminmax<=1) // fractions of the whole colormap range
93 colminmax = round(1 + colminmax*(nColorsCM-1))
95 colminmax = [max(colminmax(1),1) min(colminmax(2), nColorsCM)];
96 elseif ~isdef("colminmax","l") | type(colminmax)==0 | colminmax==[]
97 if ~isdef("umin","l") | type(umin)==0 | umin==[] then
100 colminmax = [1, nColorsCM]
106 // Default umin, umax, colminmax
110 elseif Type=="Plot3d"
116 if or(fieldnames(h.data)=="color")
118 colorsAreZ = ~isvector(c)
119 if or(h.color_flag==[2 3 4]) & h.cdata_mapping == "direct"
122 colminmax = [min(u) max(u)]
130 // colorsAreZ = colorsAreZ & stdev(c(k)./u(k))==0 // Improvement to explore
141 case 3 // keep u as is
146 u = [] // no Z-colors mapping possible
149 elseif Type=="Grayplot"
151 u = (u(1:$-1,1:$-1)+u(2:$,1:$-1)+u(2:$,2:$)+u(1:$-1,2:$))/4;
152 if h.data_mapping=="direct"
155 elseif Type=="Matplot"
160 k = ~isinf(u) & ~isnan(u)
161 uminmax = [min(u(k)) max(u(k))]
165 if ~isdef("umin","l") | type(umin)==0 | umin==[] then
167 if colminmax~=[] & (length(colminmax)>1 | colminmax~=-1)
168 if Type=="Matplot" | ..
169 Type=="Fac3d" & or(h.color_flag==[2 3 4]) & h.cdata_mapping == "direct"
173 c = colminmax // raw bounds (not integers)
174 nc = max(1,floor(colminmax(1)))
175 // recomputing umin matching the rounded colminmax(1)
176 umin = uminmax(1) + (uminmax(2)-uminmax(1)) * ..
177 (colminmax(1)-nc)/(c(2)-c(1))
179 umin = uminmax(1) + (uminmax(2)-uminmax(1)) * ..
180 (colminmax(1)-0)/nColorsCM
187 msg =_("%s: Argument #%d: Can''t retrieve a default value: Decimal number expected.\n")
188 error(msprintf(msg, "colorbar", 1))
191 msg = _("%s: Argument #%d: Decimal number(s) expected.\n")
192 if type(umin)~=1 | ~isreal(umin)
193 error(msprintf(msg, "colorbar", 1))
196 msg = _("%s: Argument #%d: Scalar (1 element) expected.\n")
197 error(msprintf(msg, "colorbar", 1))
200 umin = uminmax(1) // umin=-%inf means umin=min(u)
205 if ~isdef("umax","l") | type(umax)==0 | umax==[] then
207 if colminmax~=[] & colminmax~=-1
208 if Type=="Matplot" | ..
209 Type=="Fac3d" & or(h.color_flag==[2 3 4]) & h.cdata_mapping == "direct"
213 c = colminmax // raw bounds (not integers)
214 nc = min(nColorsCM,ceil(colminmax(2)))
215 // recomputing umax matching the rounded colminmax(1)
216 umax = uminmax(2) + (uminmax(2)-uminmax(1)) * ..
217 (nc-c(2))/(c(2)-c(1))
219 umax = uminmax(1) + (uminmax(2)-uminmax(1)) * ..
220 (colminmax(2)-0)/nColorsCM
227 msg =_("%s: Argument #%d: Can''t retrieve a default value: Decimal number expected.\n")
228 error(msprintf(msg, "colorbar", 1))
231 msg = _("%s: Argument #%d: Decimal number(s) expected.\n")
232 if type(umax)~=1 | ~isreal(umax)
233 error(msprintf(msg, "colorbar", 2))
236 msg = _("%s: Argument #%d: Scalar (1 element) expected.\n")
237 error(msprintf(msg, "colorbar", 2))
240 umax = uminmax(2) // umax=%inf means umax=max(u)
245 if colminmax(1)==-1 // => relative color range matches relative u range
247 colminmax = [umin umax]
249 colminmax = 1 + (nColorsCM-1) * ..
250 ([umin umax]-uminmax(1)) / (uminmax(2)-uminmax(1))
254 colminmax = [max(1,round(colminmax(1))) min(nColorsCM,round(colminmax(2)))]
258 if isdef("fmt","l") then
259 if type(fmt)<>10 | size(fmt,"*")<>1 then
260 msg = gettext("%s: Wrong type for input argument #%d: %s expected.\n")
261 error(msprintf(msg, "colorbar", argn(2), "string (containing a C format)"));
269 //defer the drawing to avoid binking
270 idMem = f.immediate_drawing;
271 f.immediate_drawing = "off";
272 // get current axes and properties
274 fg_color=a.foreground
275 wr=a.axes_bounds; //get the rectangle of the current axes
277 // modify the orginal axes to let space for the colorbar
279 a_pl.axes_bounds=[wr(1) , wr(2) , 0.85*wr(3) , wr(4)]
282 // create a new axes for the colorbar et set its properties
283 a_cb = newaxes(a.parent);
284 a_cb.axes_bounds=[wr(1)+0.83*wr(3) , wr(2)+wr(4)*0.2 , 0.2*wr(3) , wr(4)*0.6];
285 a_cb.foreground = a.foreground;
286 a_cb.background = f.background;
287 a_cb.axes_visible = "on";
288 a_cb.y_location = "right";
289 a_cb.tight_limits = "on";
291 //It is not possible to set no ticks for x (should be fixed)
292 a_cb.x_ticks=tlist(["ticks","locations","labels"],-1,"");
293 a_cb.auto_ticks = ["off","on","off"];
294 a_cb.ticks_format(2) = fmt;
296 a_cb.margins=[0 0.75 0 0];
299 Matplot((colminmax(2):-1:colminmax(1))')
300 a_cb.y_location = "right";
301 a_cb.tight_limits = "on";
302 if Type~="Matplot" then
304 gce().rect = [0.5 umin 1.5 umax];
305 a_cb.data_bounds = [0.5, 1.5, umin-du/500, umax+du/500];
307 s = ((umax-umin)==(colminmax(2)-colminmax(1)))*0.5
308 gce().rect = [0.5 umin-s 1.5 umax+s];
309 a_cb.data_bounds = [0.5 1.5 umin-s umax+s];
312 //reset the initial values
313 sca(a_pl) //current axes
315 // Restoring input drawing mode
316 f.immediate_drawing = idMem;
319 set("current_entity", a_cb)