comparison scripts/plot/legend.m @ 15440:1db706430c96

Fix legend ('show') to work with DisplayName (bug #33757) Update m-file with Octave coding conventions. * legend.m: If legend does not exist then create it when legend ('show') is used rather than just turning visibility on.
author Rik <rik@octave.org>
date Mon, 24 Sep 2012 15:42:11 -0700
parents f3b5cadfd6d5
children e5a07d7aafcc
comparison
equal deleted inserted replaced
15439:5930d41cade1 15440:1db706430c96
133 else 133 else
134 error ("legend.m: This should not happen. File a bug report."); 134 error ("legend.m: This should not happen. File a bug report.");
135 endif 135 endif
136 ## Remove duplicates while preserving order 136 ## Remove duplicates while preserving order
137 [~, n] = unique (ca); 137 [~, n] = unique (ca);
138 ca = ca (sort (n)); 138 ca = ca(sort (n));
139 endif 139 endif
140 140
141 if (nargin > 0 && all (ishandle (varargin{1}))) 141 if (nargin > 0 && all (ishandle (varargin{1})))
142 kids = flipud (varargin{1}(:)); 142 kids = flipud (varargin{1}(:));
143 varargin(1) = []; 143 varargin(1) = [];
144 else 144 else
145 kids = ca; 145 kids = ca;
146 kids (strcmp (get (ca, "tag"), "legend")) = []; 146 kids(strcmp (get (ca, "tag"), "legend")) = [];
147 if (isscalar (kids)) 147 if (isscalar (kids))
148 kids = get (kids, "children")(:); 148 kids = get (kids, "children")(:);
149 else 149 else
150 kids = flipud ([get(kids, "children"){:}](:)); 150 kids = flipud ([get(kids, "children"){:}](:));
151 endif 151 endif
186 endif 186 endif
187 endwhile 187 endwhile
188 188
189 ## Validate the orientation 189 ## Validate the orientation
190 switch (orientation) 190 switch (orientation)
191 case {"vertical", "horizontal","default"} 191 case {"vertical", "horizontal", "default"}
192 otherwise 192 otherwise
193 error ("legend: unrecognized legend orientation"); 193 error ("legend: unrecognized legend orientation");
194 endswitch 194 endswitch
195 195
196 ## Validate the position type is valid 196 ## Validate the position type is valid
214 endswitch 214 endswitch
215 215
216 hlegend = []; 216 hlegend = [];
217 fkids = get (fig, "children"); 217 fkids = get (fig, "children");
218 for i = 1 : numel (fkids) 218 for i = 1 : numel (fkids)
219 if (ishandle (fkids (i)) && strcmp (get (fkids (i), "type"), "axes") 219 if (ishandle (fkids(i)) && strcmp (get (fkids(i), "type"), "axes")
220 && (strcmp (get (fkids (i), "tag"), "legend"))) 220 && (strcmp (get (fkids(i), "tag"), "legend")))
221 udata = get (fkids (i), "userdata"); 221 udata = get (fkids(i), "userdata");
222 if (! isempty (intersect (udata.handle, ca))) 222 if (! isempty (intersect (udata.handle, ca)))
223 hlegend = fkids (i); 223 hlegend = fkids(i);
224 break; 224 break;
225 endif 225 endif
226 endif 226 endif
227 endfor 227 endfor
228 228
229 if (nargs == 1) 229 if (nargs == 1)
230 arg = varargin{1}; 230 arg = varargin{1};
231 if (ischar (arg)) 231 if (ischar (arg))
232 if (rows (arg) == 1) 232 if (rows (arg) == 1)
233 str = tolower (deblank (arg)); 233 str = tolower (strtrim (arg));
234 switch (str) 234 switch (str)
235 case {"off"} 235 case "off"
236 delete (hlegend); 236 delete (hlegend);
237 return 237 return;
238 case {"hide"} 238 case "hide"
239 show = "off"; 239 show = "off";
240 nargs--; 240 nargs--;
241 case "show" 241 case "show"
242 show = "on"; 242 if (! isempty (hlegend))
243 show = "on";
244 else
245 show = "create";
246 textpos = "left";
247 endif
243 nargs--; 248 nargs--;
244 case "toggle" 249 case "toggle"
245 if (isempty (hlegend) || strcmp (get (hlegend, "visible"), "off")) 250 if (isempty (hlegend))
251 show = "create";
252 textpos = "left";
253 elseif (strcmp (get (hlegend, "visible"), "off"))
246 show = "on"; 254 show = "on";
247 else 255 else
248 show = "off"; 256 show = "off";
249 endif 257 endif
250 nargs--; 258 nargs--;
258 textpos = "left"; 266 textpos = "left";
259 nargs--; 267 nargs--;
260 case "right" 268 case "right"
261 textpos = "right"; 269 textpos = "right";
262 nargs--; 270 nargs--;
263 otherwise
264 endswitch 271 endswitch
265 else 272 else
266 varargin = cellstr (arg); 273 varargin = cellstr (arg);
267 nargs = numel (varargin); 274 nargs = numel (varargin);
268 endif 275 endif
295 hplots = []; 302 hplots = [];
296 text_strings = {}; 303 text_strings = {};
297 endif 304 endif
298 elseif (strcmp (box, "on")) 305 elseif (strcmp (box, "on"))
299 if (! isempty (hlegend)) 306 if (! isempty (hlegend))
300 set (hlegend, "visible", "on", "box", "on"); 307 set (hlegend, "box", "on", "visible", "on");
301 endif 308 endif
302 elseif (strcmp (box, "off")) 309 elseif (strcmp (box, "off"))
303 if (! isempty (hlegend)) 310 if (! isempty (hlegend))
304 set (hlegend, "box", "off", "visible", "off"); 311 set (hlegend, "box", "off", "visible", "off");
305 endif 312 endif
333 hplots = []; 340 hplots = [];
334 text_strings = {}; 341 text_strings = {};
335 342
336 if (nargs > 0) 343 if (nargs > 0)
337 have_data = false; 344 have_data = false;
338 for k = 1:nkids 345 for k = 1 : nkids
339 typ = get (kids(k), "type"); 346 typ = get (kids(k), "type");
340 if (strcmp (typ, "line") || strcmp (typ, "surface") 347 if (strcmp (typ, "line") || strcmp (typ, "surface")
341 || strcmp (typ, "patch") || strcmp (typ, "hggroup")) 348 || strcmp (typ, "patch") || strcmp (typ, "hggroup"))
342 have_data = true; 349 have_data = true;
343 break; 350 break;
363 endwhile 370 endwhile
364 if (k > 0) 371 if (k > 0)
365 if (strcmp (get (kids(k), "type"), "hggroup")) 372 if (strcmp (get (kids(k), "type"), "hggroup"))
366 hgkids = get (kids(k), "children"); 373 hgkids = get (kids(k), "children");
367 for j = 1 : length (hgkids) 374 for j = 1 : length (hgkids)
368 hgobj = get (hgkids (j)); 375 hgobj = get (hgkids(j));
369 if (isfield (hgobj, "displayname")) 376 if (isfield (hgobj, "displayname"))
370 set (hgkids(j), "displayname", arg); 377 set (hgkids(j), "displayname", arg);
371 hplots = [hplots, hgkids(j)]; 378 hplots = [hplots, hgkids(j)];
372 text_strings = {text_strings{:}, arg}; 379 text_strings = {text_strings{:}, arg};
373 break; 380 break;
407 endif 414 endif
408 if (k > 0) 415 if (k > 0)
409 if (strcmp (get (kids(k), "type"), "hggroup")) 416 if (strcmp (get (kids(k), "type"), "hggroup"))
410 hgkids = get (kids(k), "children"); 417 hgkids = get (kids(k), "children");
411 for j = 1 : length (hgkids) 418 for j = 1 : length (hgkids)
412 hgobj = get (hgkids (j)); 419 hgobj = get (hgkids(j));
413 if (isfield (hgobj, "displayname") 420 if (isfield (hgobj, "displayname")
414 && ! isempty (hgobj.displayname)) 421 && ! isempty (hgobj.displayname))
415 hplots = [hplots, hgkids(j)]; 422 hplots = [hplots, hgkids(j)];
416 text_strings = {text_strings{:}, hgobj.displayname}; 423 text_strings = {text_strings{:}, hgobj.displayname};
417 break; 424 break;
418 endif 425 endif
419 endfor 426 endfor
420 else 427 else
421 if (! isempty (get (kids (k), "displayname"))) 428 if (! isempty (get (kids(k), "displayname")))
422 hplots = [hplots, kids(k)]; 429 hplots = [hplots, kids(k)];
423 text_strings = {text_strings{:}, get(kids (k), "displayname")}; 430 text_strings = {text_strings{:}, get(kids(k), "displayname")};
424 endif 431 endif
425 endif 432 endif
426 if (--k == 0) 433 if (--k == 0)
427 break; 434 break;
428 endif 435 endif
522 texthandle = []; 529 texthandle = [];
523 maxwidth = 0; 530 maxwidth = 0;
524 maxheight = 0; 531 maxheight = 0;
525 for k = 1 : nentries 532 for k = 1 : nentries
526 if (strcmp (textpos, "right")) 533 if (strcmp (textpos, "right"))
527 texthandle = [texthandle, text(0, 0, text_strings {k}, 534 texthandle = [texthandle, text(0, 0, text_strings{k},
528 "horizontalalignment", "left", 535 "horizontalalignment", "left",
529 "userdata", hplots(k), 536 "userdata", hplots(k),
530 "fontsize", ca_fontsize)]; 537 "fontsize", ca_fontsize)];
531 else 538 else
532 texthandle = [texthandle, text(0, 0, text_strings {k}, 539 texthandle = [texthandle, text(0, 0, text_strings{k},
533 "horizontalalignment", "right", 540 "horizontalalignment", "right",
534 "userdata", hplots(k), 541 "userdata", hplots(k),
535 "fontsize", ca_fontsize)]; 542 "fontsize", ca_fontsize)];
536 endif 543 endif
537 units = get (texthandle (end), "units"); 544 units = get (texthandle(end), "units");
538 unwind_protect 545 unwind_protect
539 set (texthandle (end), "units", "points"); 546 set (texthandle(end), "units", "points");
540 extents = get (texthandle (end), "extent"); 547 extents = get (texthandle(end), "extent");
541 maxwidth = max (maxwidth, extents (3)); 548 maxwidth = max (maxwidth, extents(3));
542 maxheight = max (maxheight, extents (4)); 549 maxheight = max (maxheight, extents(4));
543 unwind_protect_cleanup 550 unwind_protect_cleanup
544 set (texthandle (end), "units", units); 551 set (texthandle(end), "units", units);
545 end_unwind_protect 552 end_unwind_protect
546 endfor 553 endfor
547 554
548 num1 = nentries; 555 num1 = nentries;
549 if (strcmp (orientation, "vertical")) 556 if (strcmp (orientation, "vertical"))
550 height = nentries * (ypad + maxheight); 557 height = nentries * (ypad + maxheight);
551 if (outside) 558 if (outside)
552 if (height > ca_pos (4)) 559 if (height > ca_pos(4))
553 ## Avoid shrinking the height of the axis to zero if outside 560 ## Avoid shrinking the height of the axis to zero if outside
554 num1 = ca_pos(4) / (maxheight + ypad) / 2; 561 num1 = ca_pos(4) / (maxheight + ypad) / 2;
555 endif 562 endif
556 else 563 else
557 if (height > 0.9 * ca_pos (4)) 564 if (height > 0.9 * ca_pos(4))
558 num1 = 0.9 * ca_pos(4) / (maxheight + ypad); 565 num1 = 0.9 * ca_pos(4) / (maxheight + ypad);
559 endif 566 endif
560 endif 567 endif
561 else 568 else
562 width = nentries * (ypad + maxwidth); 569 width = nentries * (ypad + maxwidth);
563 if (outside) 570 if (outside)
564 if (width > ca_pos (3)) 571 if (width > ca_pos(3))
565 ## Avoid shrinking the width of the axis to zero if outside 572 ## Avoid shrinking the width of the axis to zero if outside
566 num1 = ca_pos(3) / (maxwidth + ypad) / 2; 573 num1 = ca_pos(3) / (maxwidth + ypad) / 2;
567 endif 574 endif
568 else 575 else
569 if (width > 0.9 * ca_pos (3)) 576 if (width > 0.9 * ca_pos(3))
570 num1 = 0.9 * ca_pos(3) / (maxwidth + ypad); 577 num1 = 0.9 * ca_pos(3) / (maxwidth + ypad);
571 endif 578 endif
572 endif 579 endif
573 endif 580 endif
574 num2 = ceil (nentries / num1); 581 num2 = ceil (nentries / num1);
681 688
682 ## Now write the line segments and place the text objects correctly 689 ## Now write the line segments and place the text objects correctly
683 xk = 0; 690 xk = 0;
684 yk = 0; 691 yk = 0;
685 for k = 1 : numel (hplots) 692 for k = 1 : numel (hplots)
686 hobjects = [hobjects, texthandle (k)]; 693 hobjects = [hobjects, texthandle(k)];
687 switch (get (hplots(k), "type")) 694 switch (get (hplots(k), "type"))
688 case "line" 695 case "line"
689 color = get (hplots(k), "color"); 696 color = get (hplots(k), "color");
690 style = get (hplots(k), "linestyle"); 697 style = get (hplots(k), "linestyle");
691 if (! strcmp (style, "none")) 698 if (! strcmp (style, "none"))
722 p1 = patch ("xdata", ([0, linelength, linelength, 0] + 729 p1 = patch ("xdata", ([0, linelength, linelength, 0] +
723 xoffset + xk * xstep) / lpos(3), 730 xoffset + xk * xstep) / lpos(3),
724 "ydata", (lpos(4) - yoffset - 731 "ydata", (lpos(4) - yoffset -
725 [yk-0.3, yk-0.3, yk+0.3, yk+0.3] .* ystep) / lpos(4), 732 [yk-0.3, yk-0.3, yk+0.3, yk+0.3] .* ystep) / lpos(4),
726 "facecolor", facecolor, "edgecolor", edgecolor, "cdata", cdata, 733 "facecolor", facecolor, "edgecolor", edgecolor, "cdata", cdata,
727 "userdata", hplots (k)); 734 "userdata", hplots(k));
728 hobjects = [hobjects, p1]; 735 hobjects = [hobjects, p1];
729 endif 736 endif
730 case "surface" 737 case "surface"
731 endswitch 738 endswitch
732 set (texthandle (k), "position", [(txoffset + xk * xstep) / lpos(3), ... 739 set (texthandle (k), "position", [(txoffset + xk * xstep) / lpos(3), ...
760 if (outside) 767 if (outside)
761 for i = 1 : numel (ca) 768 for i = 1 : numel (ca)
762 units = get (ca(i), "units"); 769 units = get (ca(i), "units");
763 unwind_protect 770 unwind_protect
764 set (ca(i), "units", "points"); 771 set (ca(i), "units", "points");
765 set (ca (i), "position", new_pos); 772 set (ca(i), "position", new_pos);
766 unwind_protect_cleanup 773 unwind_protect_cleanup
767 set (ca(i), "units", units); 774 set (ca(i), "units", units);
768 end_unwind_protect 775 end_unwind_protect
769 endfor 776 endfor
770 777
873 endfor 880 endfor
874 endfunction 881 endfunction
875 882
876 function deletelegend1 (h, d, ca) 883 function deletelegend1 (h, d, ca)
877 if (ishandle (ca) && strcmp (get (ca, "type"), "axes") 884 if (ishandle (ca) && strcmp (get (ca, "type"), "axes")
878 && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"),"off")) 885 && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off"))
879 && strcmp (get (ca, "beingdeleted"), "off")) 886 && strcmp (get (ca, "beingdeleted"), "off"))
880 delete (ca); 887 delete (ca);
881 endif 888 endif
882 endfunction 889 endfunction
883 890
884 function deletelegend2 (h, d, ca, pos, outpos, t1, hplots) 891 function deletelegend2 (h, d, ca, pos, outpos, t1, hplots)
885 for i = 1 : numel (ca) 892 for i = 1 : numel (ca)
886 if (ishandle (ca(i)) && strcmp (get (ca(i), "type"), "axes") 893 if (ishandle (ca(i)) && strcmp (get (ca(i), "type"), "axes")
887 && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"),"off")) 894 && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off"))
888 && strcmp (get (ca(i), "beingdeleted"), "off")) 895 && strcmp (get (ca(i), "beingdeleted"), "off"))
889 if (!isempty (pos) && !isempty(outpos)) 896 if (!isempty (pos) && !isempty(outpos))
890 units = get (ca(i), "units"); 897 units = get (ca(i), "units");
891 unwind_protect 898 unwind_protect
892 set (ca(i), "units", "points"); 899 set (ca(i), "units", "points");
898 endif 905 endif
899 endfor 906 endfor
900 set (t1, "deletefcn", ""); 907 set (t1, "deletefcn", "");
901 delete (t1); 908 delete (t1);
902 for i = 1 : numel (hplots) 909 for i = 1 : numel (hplots)
903 if (strcmp (get (hplots (i), "type"), "line")) 910 if (strcmp (get (hplots(i), "type"), "line"))
904 dellistener (hplots (i), "color"); 911 dellistener (hplots(i), "color");
905 dellistener (hplots (i), "linestyle"); 912 dellistener (hplots(i), "linestyle");
906 dellistener (hplots (i), "marker"); 913 dellistener (hplots(i), "marker");
907 dellistener (hplots (i), "markeredgecolor"); 914 dellistener (hplots(i), "markeredgecolor");
908 dellistener (hplots (i), "markerfacecolor"); 915 dellistener (hplots(i), "markerfacecolor");
909 dellistener (hplots (i), "markersize"); 916 dellistener (hplots(i), "markersize");
910 dellistener (hplots (i), "displayname"); 917 dellistener (hplots(i), "displayname");
911 endif 918 endif
912 endfor 919 endfor
913 endfunction 920 endfunction
914 921
915 function updateline (h, d, hlegend, linelength) 922 function updateline (h, d, hlegend, linelength)
916 lm = []; 923 lm = [];
917 ll = []; 924 ll = [];
918 kids = get (hlegend, "children"); 925 kids = get (hlegend, "children");
919 for i = 1 : numel (kids) 926 for i = 1 : numel (kids)
920 if (get (kids (i), "userdata") == h 927 if (get (kids(i), "userdata") == h
921 && strcmp (get (kids(i), "type"), "line")) 928 && strcmp (get (kids(i), "type"), "line"))
922 if (strcmp (get (kids (i), "marker"), "none")) 929 if (strcmp (get (kids (i), "marker"), "none"))
923 ll = kids (i); 930 ll = kids(i);
924 else 931 else
925 lm = kids (i); 932 lm = kids(i);
926 endif 933 endif
927 endif 934 endif
928 endfor 935 endfor
929 936
930 linestyle = get (h, "linestyle"); 937 linestyle = get (h, "linestyle");
936 && (! isempty (lm) || isempty (ll))) 943 && (! isempty (lm) || isempty (ll)))
937 ## An element was removed from the legend. Need to recall the 944 ## An element was removed from the legend. Need to recall the
938 ## legend function to recreate a new legend 945 ## legend function to recreate a new legend
939 [hplots, text_strings] = __getlegenddata__ (hlegend); 946 [hplots, text_strings] = __getlegenddata__ (hlegend);
940 for i = 1 : numel (hplots) 947 for i = 1 : numel (hplots)
941 if (hplots (i) == h) 948 if (hplots(i) == h)
942 hplots(i) = []; 949 hplots(i) = [];
943 text_strings(i) = []; 950 text_strings(i) = [];
944 break; 951 break;
945 endif 952 endif
946 endfor 953 endfor
984 "userdata", h, "parent", hlegend); 991 "userdata", h, "parent", hlegend);
985 endif 992 endif
986 endif 993 endif
987 endfunction 994 endfunction
988 995
996
989 %!demo 997 %!demo
990 %! plot (rand (2)) 998 %! plot (rand (2))
991 %! legend ({'foo'}, 'bar', 'boxoff') 999 %! legend ({'foo'}, 'bar', 'boxoff')
992 %! title ('legend() should warn about an extra label') 1000 %! title ('legend() should warn about an extra label')
993 1001
1044 %! clf; 1052 %! clf;
1045 %! plot (1:10, 1:10, 1:10, fliplr (1:10)); 1053 %! plot (1:10, 1:10, 1:10, fliplr (1:10));
1046 %! title ('Legend with text to the right'); 1054 %! title ('Legend with text to the right');
1047 %! legend ({'I am blue', 'I am green'}, 'location', 'east'); 1055 %! legend ({'I am blue', 'I am green'}, 'location', 'east');
1048 %! legend right; 1056 %! legend right;
1049
1050 %!demo
1051 %! clf;
1052 %! plot (1:10, 1:10);
1053 %! title ('a very long label can sometimes cause problems');
1054 %! legend ({'hello world'}, 'location', 'northeastoutside');
1055 1057
1056 %!demo 1058 %!demo
1057 %! clf; 1059 %! clf;
1058 %! plot (1:10, 1:10); 1060 %! plot (1:10, 1:10);
1059 %! title ('a very long label can sometimes cause problems'); 1061 %! title ('a very long label can sometimes cause problems');