2525
2626## -*- texinfo -*-
2727## @deftypefn {} {} colorbar
28- ## @deftypefnx {} {} colorbar (@dots{ }, @var{ loc })
28+ ## @deftypefnx {} {} colorbar (@var{ loc }, @dots{ })
2929## @deftypefnx {} {} colorbar (@var{delete_option })
3030## @deftypefnx {} {} colorbar (@var{hcb }, @dots{})
3131## @deftypefnx {} {} colorbar (@var{hax }, @dots{})
32- ## @deftypefnx {} {} colorbar (@dots{}, " peer" , @var{hax }, @dots{})
3332## @deftypefnx {} {} colorbar (@dots{}, " location" , @var{loc }, @dots{})
3433## @deftypefnx {} {} colorbar (@dots{}, @var{prop }, @var{val }, @dots{})
3534## @deftypefnx {} {@var{h } = } colorbar (@dots{})
3635## Add a colorbar to the current axes .
3736##
38- ## A colorbar displays the current colormap along with numerical rulings
39- ## so that the color scale can be interpreted .
37+ ## A colorbar displays the current colormap along with numerical rulings so
38+ ## that the color scale can be interpreted .
4039##
4140## The optional input @nospell{@var{loc }} determines the location of the
42- ## colorbar . If present , it must be the last argument to @code{colorbar}.
41+ ## colorbar . If present , it must be the first argument to @code{colorbar}.
4342## Valid values for @nospell{@var{loc }} are
4443##
4544## @table @asis
7372##
7473## If the first argument @var{hax } is an axes handle , then the colorbar is
7574## added to this axes , rather than the current axes returned by @code{gca}.
76- ## Alternatively , If the argument @qcode{"peer"} is given, then the following
77- ## argument is treated as the axes handle in which to add the colorbar . The
78- ## @qcode{" peer" } calling syntax may be removed in the future and is not
79- ## recommended .
8075##
8176## If the first argument @var{hcb } is a handle to a colorbar object , then
8277## operate on this colorbar directly .
8378##
8479## Additional property / value pairs are passed directly to the underlying axes
85- ## object . The full list of properties is documented at
86- ## @ref{Axes Properties }.
80+ ## object . The full list of properties is documented at @ref{Axes Properties }.
8781##
8882## The optional return value @var{h } is a graphics handle to the created
8983## colorbar object .
9084##
91- ## Implementation Note : A colorbar is created as an additional axes object
92- ## with the @qcode{" tag" } property set to @qcode{" colorbar" }. The created
93- ## object has the extra property @qcode{" location" } which controls the
94- ## positioning of the colorbar .
85+ ## Implementation Note : A colorbar is created as an additional axes object with
86+ ## the @qcode{" tag" } property set to @qcode{" colorbar" }. The created object
87+ ## has the extra property @qcode{" location" } which controls the positioning of
88+ ## the colorbar .
89+ ##
90+ ## If the argument @qcode{" peer" } is given , then the following argument is
91+ ## treated as the axes handle in which to add the colorbar . The @qcode{" peer" }
92+ ## calling syntax may be removed in the future and is not recommended .
9593## @seealso{colormap }
9694## @end deftypefn
9795
120118 switch (lower (arg ))
121119 case {" north" , " south" , " east" , " west" , ...
122120 " northoutside" , " southoutside" , " eastoutside" , " westoutside" }
123- if (i <= nargin )
124- error (" colorbar: LOC specification must occur as final argument" );
121+ if (i != 2 )
122+ error (" colorbar: LOC specification must occur as first argument" );
125123 endif
126124 loc = lower (arg );
127125
165163 if (! any (strcmp (loc , {" eastoutside" ; " east" ; " westoutside" ; " west" ;
166164 " northoutside" ; " north" ; " southoutside" ; " south" ;
167165 " manual" })))
168- error (" colorbar: unrecognized colorbar location" );
166+ error (" colorbar: unrecognized colorbar location '%s' " , loc );
169167 endif
170168 endif
171169
268266
269267 if (isempty (cbpos ))
270268 ## auto positioning
271- ## FIXME : Should handle user - specified " AxisLocation" property (mirror ).
272269 [axpos , cbpos , vertical , mirror ] = ...
273270 calc_cbar_position (loc , props , ancestor (hpar , " figure" ));
274271 set (hax , " position" , axpos );
275272 else
276273 ## colorbar position specified .
277274 ## 1 ) Don ' t shrink existing plot axes ,
278- ## 2 ) Assume " EastOutside" orientation ( vertical = true , mirror = true )
275+ ## 2 ) Use default " EastOutside" orientation
279276 vertical = true ;
280277 mirror = true ;
281278 endif
290287
291288 addproperty (" axislocation" , hcb , " radio" , " {out}|in" );
292289 addproperty (" axislocationmode" , hcb , " radio" , " {auto}|manual" );
293- addproperty (" label" , hcb , " handle" , get (hcb , " ylabel" ));
294290 addproperty (" direction" , hcb , " AxesYdir" , " normal" );
291+ addproperty (" label" , hcb , " handle" , get (hcb , " ylabel" ));
295292 addproperty (" limits" , hcb , " AxesYlim" );
296293 addproperty (" limitsmode" , hcb , " AxesYlimMode" , " auto" );
297294 addproperty (" location" , hcb , " radio" ,
298295 " {eastoutside}|east|westoutside|west|northoutside|north|southoutside|south|manual" ,
299296 loc );
300297 addproperty (" tickdirection" , hcb , " AxesTickdir" , " in" );
298+ addproperty (" ticklabels" , hcb , " AxesYtickLabel" );
299+ addproperty (" ticklabelsmode" , hcb , " AxesYtickLabelMode" , " auto" );
300+ addproperty (" ticks" , hcb , " AxesYtick" );
301+ addproperty (" ticksmode" , hcb , " AxesYtickMode" , " auto" );
301302 ## FIXME : Matlab uses just a scalar for ticklength , but axes already
302303 ## has a 2 - element ticklength property which cannot be overridden .
303304 ## addproperty (" ticklength" , hcb , " double" , 0.01 );
328329 " ytickmode" , " auto" , " ylim" , cext ,
329330 " yaxislocation" , " right" , " label" , get (hcb , " ylabel" ),
330331 " __vertical__" , vertical ,
331- " layer" , " top" , args{ : } );
332+ " layer" , " top" );
332333 else
333334 set (hcb , " xtick" , [], " xlim" , [-0.5 , 1.5 ],
334335 " ytickmode" , " auto" , " ylim" , cext ,
335336 " yaxislocation" , " left" , " label" , get (hcb , " ylabel" ),
336337 " __vertical__" , vertical ,
337- " layer" , " top" , args{ : } );
338+ " layer" , " top" );
338339 endif
339340 else
340341 set (hi , " xdata" , [cmin , cmax ], " ydata" , [0 ,1 ], " cdata" , [1 : clen ]);
343344 " xtickmode" , " auto" , " xlim" , cext ,
344345 " xaxislocation" , " top" , " label" , get (hcb , " xlabel" ),
345346 " __vertical__" , vertical ,
346- " layer" , " top" , args{ : } );
347+ " layer" , " top" );
347348 else
348349 set (hcb , " ytick" , [], " ylim" , [-0.5 , 1.5 ],
349350 " xtickmode" , " auto" , " xlim" , cext ,
350351 " xaxislocation" , " bottom" , " label" , get (hcb , " xlabel" ),
351352 " __vertical__" , vertical ,
352- " layer" , " top" , args{ : } );
353+ " layer" , " top" );
353354 endif
354355 endif
355356
364365
365366 set (hcb , " deletefcn" , {@cb_restore_axes , hax , props });
366367
368+ addlistener (hcb , " axislocation" , {@cb_axislocation });
369+ addlistener (hcb , " direction" , {@cb_direction });
370+ addlistener (hcb , " tickdirection" , @cb_tickdirection );
371+ addlistener (hcb , " ticks" , {@cb_ticks });
372+ addlistener (hcb , " ticksmode" , {@cb_ticksmode });
373+ addlistener (hcb , " ticklabels" , {@cb_ticklabels });
374+ addlistener (hcb , " ticklabelsmode" , {@cb_ticklabelsmode });
367375 addlistener (hcb , " xscale" , {@cb_error_on_logscale , " xscale" });
368376 addlistener (hcb , " yscale" , {@cb_error_on_logscale , " yscale" });
369- addlistener (hcb , " tickdirection" , @cb_tickdirection );
370377
371378 if (strcmp (get (hpar , " type" ), " figure" ))
372379 addlistener (hpar , " colormap" , {@cb_colormap , ...
382389 hcb , props });
383390 addlistener (hax , " position" , {@cb_colorbar_axis , hcb , props });
384391
385- ## FIXME : Need listeners for colorbar : axislocation , axislocationmode ,
386- ## direction , limits , limitsmode , location .
392+ ## FIXME : Need listeners for limits , limitsmode , location .
387393 endif
394+
395+ ## Called after listeners have been installed
396+ if (! isempty (args ))
397+ set (hcb , args{: });
398+ endif
399+
388400 unwind_protect_cleanup
389401 set (hfig , " currentaxes" , origaxes );
390402 if (! isempty (origfig ))
400412
401413## Axes to which colorbar was attached is being deleted / reset . Delete colorbar .
402414function cb_axes_deleted (~, ~, hax , hcb )
403-
404415 if (isaxes (hcb ))
405416 if (strcmp (get (hax , " beingdeleted" ), " on" ))
406417 ## Axes are being deleted . Disable call to cb_restore_axes .
407418 set (hcb , " deletefcn" , []);
408419 endif
409420 delete (hcb );
410421 endif
411-
412422endfunction
413423
414424## Error on attempt to set logscale on colorbar axes
@@ -419,7 +429,81 @@ function cb_error_on_logscale (hcb, ~, scale)
419429 endif
420430endfunction
421431
422- ## Colorbar " TickDirection" callback which just maps to axes " TickDir"
432+ ## colorbar property " AxisLocation" which maps to axes " [X|Y]AxisLocation" .
433+ function cb_axislocation (hcb , ~)
434+ vertical = strcmp (get (hcb , ' __vertical__' ), ' on' );
435+ location = get (hcb , ' axislocation' );
436+ if (vertical )
437+ location = ifelse (strcmp (location , ' in' ), ' left' , ' right' );
438+ set (hcb , ' yaxislocation' , location );
439+ else
440+ location = ifelse (strcmp (location , ' in' ), ' top' , ' bottom' );
441+ set (hcb , ' xaxislocation' , location );
442+ endif
443+ endfunction
444+
445+ ## colorbar property " Direction" which maps to axes " YDir" or " XDir" .
446+ function cb_direction (hcb , ~)
447+ vertical = strcmp (get (hcb , ' __vertical__' ), ' on' );
448+ direction = get (hcb , ' direction' );
449+ if (vertical )
450+ set (hcb , ' ydir' , direction );
451+ else
452+ set (hcb , ' xdir' , direction );
453+ endif
454+ endfunction
455+
456+ ## colorbar property " Ticks" which maps to axes " YTick" or " XTick" .
457+ function cb_ticks (hcb , ~)
458+ vertical = strcmp (get (hcb , ' __vertical__' ), ' on' );
459+ ticks = get (hcb , ' ticks' );
460+ if (vertical )
461+ set (hcb , ' YTick' , ticks );
462+ else
463+ set (hcb , ' XTick' , ticks );
464+ endif
465+ set (hcb , ' ticksmode' , ' manual' );
466+ endfunction
467+
468+ ## colorbar property " TicksMode" which maps to axes " [Y|X]TickMode" .
469+ function cb_ticksmode (hcb , ~)
470+ mode = get (hcb , ' ticksmode' );
471+ if (strcmp (mode , ' auto' ))
472+ vertical = strcmp (get (hcb , ' __vertical__' ), ' on' );
473+ if (vertical )
474+ set (hcb , ' YTickMode' , ' auto' );
475+ else
476+ set (hcb , ' XTickMode' , ' auto' );
477+ endif
478+ endif
479+ endfunction
480+
481+ ## colorbar property " TickLabels" which maps to axes " [Y|X]TickLabel" .
482+ function cb_ticklabels (hcb , ~)
483+ vertical = strcmp (get (hcb , ' __vertical__' ), ' on' );
484+ ticklabels = get (hcb , ' ticklabels' );
485+ if (vertical )
486+ set (hcb , ' YTickLabel' , ticklabels );
487+ else
488+ set (hcb , ' XTickLabel' , ticklabels );
489+ endif
490+ set (hcb , ' ticklabelsmode' , ' manual' );
491+ endfunction
492+
493+ ## colorbar property " TickLabelsMode" which maps to axes " [Y|X]TickLabelMode" .
494+ function cb_ticklabelsmode (hcb , ~)
495+ mode = get (hcb , ' ticklabelsmode' );
496+ if (strcmp (mode , ' auto' ))
497+ vertical = strcmp (get (hcb , ' __vertical__' ), ' on' );
498+ if (vertical )
499+ set (hcb , ' YTickLabelMode' , ' auto' );
500+ else
501+ set (hcb , ' XTickLabelMode' , ' auto' );
502+ endif
503+ endif
504+ endfunction
505+
506+ ## colorbar property " TickDirection" which maps to axes property " TickDir" .
423507function cb_tickdirection (hcb , ~)
424508 set (hcb , " tickdir" , get (hcb , " tickdirection" ));
425509endfunction
@@ -437,6 +521,8 @@ function cb_restore_axes (hcb, ~, hax, orig_props)
437521 ## FIXME : It is wrong to delete every listener for colormap on figure ,
438522 ## but we don ' t have a way of deleting just this instance .
439523 dellistener (hf , " colormap" );
524+ dellistener (hax , " colormap" );
525+ dellistener (hax , " clim" );
440526 dellistener (hax , " dataaspectratio" );
441527 dellistener (hax , " dataaspectratiomode" );
442528 dellistener (hax , " plotboxaspectratio" );
@@ -514,7 +600,7 @@ function cb_colorbar_axis (hax, ~, hcb, orig_props)
514600 props.position = orig_props .position ;
515601 props.outerposition = orig_props .outerposition ;
516602 [axpos , cbpos , vertical , mirror ] = ...
517- calc_cbar_position (loc , props , ancestor (hax , " figure" ));
603+ calc_cbar_position (loc , props , ancestor (hax , " figure" ));
518604
519605 set (hcb , " position" , cbpos );
520606 endif
@@ -524,8 +610,7 @@ function cb_colorbar_axis (hax, ~, hcb, orig_props)
524610## FIXME : The algorithm for positioning in legend .m is much more sophisticated
525611## and should be borrowed for colorbar . One problem is that colorbar
526612## positioning does not take in to account multi - line axes labels .
527- ## FIXME : Should handle user - specified " AxisLocation" property (mirror var ).
528- function [axpos , cbpos , vertical , mirr ] = calc_cbar_position (loc , props , cf )
613+ function [axpos , cbpos , vertical , mirror ] = calc_cbar_position (loc , props , cf )
529614
530615 ## This will always represent the position prior to adding the colorbar .
531616 axpos = props .position ;
@@ -560,47 +645,47 @@ function cb_colorbar_axis (hax, ~, hcb, orig_props)
560645 origin = axpos(1 : 2 ) + [0 ., 0.9 ] .* sz + [1 , - 1 ] .* off ;
561646 sz .*= [1.0 , 0.06 ];
562647 axpos(4 ) = 0.8 * axpos(4 );
563- mirr = true ;
648+ mirror = true ;
564649 vertical = false ;
565650 case " north"
566651 origin = axpos(1 : 2 ) + [0.05 , 0.9 ] .* sz + [1 , - 1 ] .* off ;
567652 sz .*= [1.0 , 0.06 ] * 0.9 ;
568- mirr = false ;
653+ mirror = false ;
569654 vertical = false ;
570655 case " southoutside"
571656 origin = axpos(1 : 2 ) + off ;
572657 sz .*= [1.0 , 0.06 ];
573658 axpos(2 ) = axpos(2 ) + axpos(4 ) * 0.2 ;
574659 axpos(4 ) = 0.8 * axpos(4 );
575- mirr = false ;
660+ mirror = false ;
576661 vertical = false ;
577662 case " south"
578663 origin = axpos(1 : 2 ) + [0.05 , 0.05 ] .* sz + off ;
579664 sz .*= [1.0 , 0.06 ] * 0.9 ;
580- mirr = true ;
665+ mirror = true ;
581666 vertical = false ;
582667 case " eastoutside"
583668 origin = axpos(1 : 2 ) + [0.9 , 0 ] .* sz + [-1 , 1 ] .* off ;
584669 sz .*= [0.06 , 1.0 ];
585670 axpos(3 ) = 0.8 * axpos(3 );
586- mirr = true ;
671+ mirror = true ;
587672 vertical = true ;
588673 case " east"
589674 origin = axpos(1 : 2 ) + [0.9 , 0.05 ] .* sz + [-1 , 1 ] .* off ;
590675 sz .*= [0.06 , 1.0 ] * 0.9 ;
591- mirr = false ;
676+ mirror = false ;
592677 vertical = true ;
593678 case " westoutside"
594679 origin = axpos(1 : 2 ) + off ;
595680 sz .*= [0.06 , 1.0 ];
596681 axpos(1 ) = axpos(1 ) + axpos(3 ) * 0.2 ;
597682 axpos(3 ) = 0.8 * axpos(3 );
598- mirr = false ;
683+ mirror = false ;
599684 vertical = true ;
600685 case " west"
601686 origin = axpos(1 : 2 ) + [0.05 , 0.05 ] .* sz + off ;
602687 sz .*= [0.06 , 1.0 ] .* 0.9 ;
603- mirr = true ;
688+ mirror = true ;
604689 vertical = true ;
605690 endswitch
606691
@@ -927,7 +1012,7 @@ function cb_colorbar_axis (hax, ~, hcb, orig_props)
9271012
9281013## Test input validation
9291014% !error <expected string argument at position 1> colorbar (-pi)
930- % !error <LOC specification must occur as final arg> colorbar ("east ", "p ", "v ")
1015+ % !error <LOC specification must occur as first arg> colorbar ("p ", "v ", "east ")
9311016% !error <missing value after "location"> colorbar ("location")
9321017% !error <missing axes handle after "peer"> colorbar ("peer")
9331018% !error <invalid axes handle following "peer"> colorbar ("peer", -1)
0 commit comments