1 ## Copyright (C) 2010-2012 David Bateman
3 ## This file is part of Octave.
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
20 ## @deftypefn {Function File} {} legend (@var{str1}, @var{str2}, @dots{})
21 ## @deftypefnx {Function File} {} legend (@var{matstr})
22 ## @deftypefnx {Function File} {} legend (@var{cell})
23 ## @deftypefnx {Function File} {} legend (@dots{}, "location", @var{pos})
24 ## @deftypefnx {Function File} {} legend (@dots{}, "orientation", @var{orient})
25 ## @deftypefnx {Function File} {} legend (@var{hax}, @dots{})
26 ## @deftypefnx {Function File} {} legend (@var{hobjs}, @dots{})
27 ## @deftypefnx {Function File} {} legend (@var{hax}, @var{hobjs}, @dots{})
28 ## @deftypefnx {Function File} {} legend ("@var{option}")
30 ## Display a legend for the axes with handle @var{hax}, or the current axes,
31 ## using the specified strings as labels. Legend entries may be specified
32 ## as individual character string arguments, a character array, or a cell
33 ## array of character strings. If the handles, @var{hobjs}, are not specified
34 ## then the legend's strings will be associated with the axes' descendants.
35 ## Legend works on line graphs, bar graphs, etc.
36 ## A plot must exist before legend is called.
38 ## The optional parameter @var{pos} specifies the location of the legend
41 ## @multitable @columnfractions 0.06 0.14 0.80
43 ## @headitem @tab @var{pos} @tab
44 ## location of the legend
46 ## @item @tab north @tab
49 ## @item @tab south @tab
52 ## @item @tab east @tab
55 ## @item @tab west @tab
58 ## @item @tab northeast @tab
59 ## right top (default)
61 ## @item @tab northwest @tab
64 ## @item @tab southeast @tab
67 ## @item @tab southwest @tab
72 ## @item @tab outside @tab
73 ## can be appended to any location string
76 ## The optional parameter @var{orient} determines if the key elements
77 ## are placed vertically or horizontally. The allowed values are "vertical"
78 ## or "horizontal" with the default being "vertical".
80 ## The following customizations are available using @var{option}:
84 ## Show legend on the plot
87 ## Hide legend on the plot
90 ## Toggles between "hide" and "show"
93 ## Show a box around legend
96 ## Hide the box around legend
99 ## Place text to the left of the keys
102 ## Place text to the right of the keys
105 ## Delete the legend object
109 function [hlegend2, hobjects2, hplot2, text_strings2] = legend (varargin)
112 && (! ishandle (varargin{1})
113 || (strcmp (get (varargin{1}, "type"), "axes")
114 && ! strcmp (get (varargin{1}, "tag"), "legend"))))
115 [ca, varargin, nargs] = __plt_get_axis_arg__ ("legend", varargin{:});
116 fig = get (ca, "parent");
118 fig = get (0, "currentfigure");
125 if (ishandle (ca) && isprop (ca, "__plotyy_axes__"))
126 plty = get (ca, "__plotyy_axes__");
127 if (isscalar (plty) && ishandle (plty))
129 elseif (iscell (plty))
131 elseif (all (ishandle (plty)))
132 ca = [ca, plty(:).'];
134 error ("legend.m: This should not happen. File a bug report.")
136 ## Remove duplicates while preserving order
137 [~, n] = unique (ca);
141 if (nargin > 0 && all (ishandle (varargin{1})))
142 kids = flipud (varargin{1}(:));
146 kids (strcmp (get (ca, "tag"), "legend")) = [];
148 kids = get(kids, "children")(:);
150 kids = [get(kids, "children"){:}](:);
153 nargs = numel (varargin);
154 nkids = numel (kids);
156 orientation = "default";
157 position = "default";
163 pos = varargin{nargs};
164 if (isnumeric (pos) && isscalar (pos) && pos == fix (pos))
165 if (pos >= -1 && pos <= 4)
166 position = [{"northeastoutside", "best", "northeast",
167 "northwest", "southwest", "southeast"}] {pos + 2};
170 error ("legend: invalid position specified");
176 pos = varargin{nargs-1};
177 str = varargin{nargs};
178 if (strcmpi (pos, "location") && ischar (str))
179 position = lower (str);
181 elseif (strcmpi (pos, "orientation") && ischar (str))
182 orientation = lower (str);
189 ## Validate the orientation
191 case {"vertical", "horizontal","default"}
193 error ("legend: unrecognized legend orientation");
196 ## Validate the position type is valid
198 inout = findstr (position, "outside");
199 if (! isempty (inout))
201 position = position(1:inout-1);
207 case {"north", "south", "east", "west", "northeast", "northwest", ...
208 "southeast", "southwest", "default"}
210 warning ("legend: 'Best' not yet implemented for location specifier\n");
211 position = "northeast";
213 error ("legend: unrecognized legend position");
217 fkids = get (fig, "children");
218 for i = 1 : numel(fkids)
219 if (ishandle (fkids (i)) && strcmp (get (fkids (i), "type"), "axes")
220 && (strcmp (get (fkids (i), "tag"), "legend")))
221 udata = get (fkids (i), "userdata");
222 if (! isempty (intersect (udata.handle, ca)))
233 str = tolower (deblank (arg));
245 if (isempty (hlegend) || strcmp (get (hlegend, "visible"), "off"))
266 varargin = cellstr (arg);
267 nargs = numel (varargin);
269 elseif (iscellstr (arg))
271 nargs = numel (varargin);
273 error ("legend: expecting argument to be a character string");
277 if (strcmp (show, "off"))
278 if (! isempty (hlegend))
279 set (get (hlegend, "children"), "visible", "off");
285 elseif (strcmp (show, "on"))
286 if (! isempty (hlegend))
287 set (get (hlegend, "children"), "visible", "on");
293 elseif (strcmp (box, "on"))
294 if (! isempty (hlegend))
295 set (hlegend, "visible", "on", "box", "on");
297 elseif (strcmp (box, "off"))
298 if (! isempty (hlegend))
299 set (hlegend, "box", "off", "visible", "off");
301 elseif (nargs == 0 && !(strcmp (position, "default") &&
302 strcmp (orientation, "default")))
303 if (! isempty (hlegend))
304 hax = getfield (get (hlegend, "userdata"), "handle");
305 [hplots, text_strings] = __getlegenddata__ (hlegend);
307 if (strcmp (position, "default"))
308 h = legend (hax, hplots, text_strings, "orientation", orientation);
309 elseif (strcmp (orientation, "default"))
311 h = legend (hax, hplots, text_strings, "location",
312 strcat (position, "outside"));
314 h = legend (hax, hplots, text_strings, "location", position);
318 h = legend (hax, hplots, text_strings, "location",
319 strcat (position, "outside"), "orientation", orientation);
321 h = legend (hax, hplots, text_strings, "location", position,
322 "orientation", orientation);
334 typ = get (kids(k), "type");
335 if (strcmp (typ, "line") || strcmp (typ, "surface")
336 || strcmp (typ, "patch") || strcmp (typ, "hggroup"))
343 warning ("legend: plot data is empty; setting key labels has no effect");
347 if (strcmp (textpos, "default"))
353 typ = get (kids(k), "type");
355 && ! (strcmp (typ, "line") || strcmp (typ, "surface")
356 || strcmp (typ, "patch") || strcmp (typ, "hggroup")))
357 typ = get (kids(--k), "type");
360 if (strcmp (get (kids(k), "type"), "hggroup"))
361 hgkids = get (kids(k), "children");
362 for j = 1 : length (hgkids)
363 hgobj = get (hgkids (j));
364 if (isfield (hgobj, "displayname"))
365 set (hgkids(j), "displayname", arg);
366 hplots = [hplots, hgkids(j)];
367 text_strings = {text_strings{:}, arg};
372 set (kids(k), "displayname", arg);
373 hplots = [hplots, kids(k)];
374 text_strings = {text_strings{:}, arg};
384 error ("legend: expecting argument to be a character string");
387 if (i < nargs && ! warned)
388 warning ("legend: ignoring extra labels");
393 typ = get (kids(k), "type");
395 && ! (strcmp (typ, "line") || strcmp (typ, "surface")
396 || strcmp (typ, "patch") || strcmp (typ, "hggroup")))
397 typ = get (kids(--k), "type");
399 if (! (strcmp (typ, "line") || strcmp (typ, "surface")
400 || strcmp (typ, "patch") || strcmp (typ, "hggroup")))
404 if (strcmp (get (kids(k), "type"), "hggroup"))
405 hgkids = get (kids(k), "children");
406 for j = 1 : length (hgkids)
407 hgobj = get (hgkids (j));
408 if (isfield (hgobj, "displayname")
409 && ! isempty (hgobj.displayname))
410 hplots = [hplots, hgkids(j)];
411 text_strings = {text_strings{:}, hgobj.displayname};
416 if (! isempty (get (kids (k), "displayname")))
417 hplots = [hplots, kids(k)];
418 text_strings = {text_strings{:}, get(kids (k), "displayname")};
428 if (isempty (hplots))
429 if (! isempty (hlegend))
430 fkids = get (fig, "children");
431 delete (fkids (fkids == hlegend));
438 ## Delete the old legend if it exists
439 if (! isempty (hlegend))
440 if (strcmp (textpos, "default"))
441 textpos = get (hlegend, "textposition");
443 if (strcmp (position, "default"))
444 position = get (hlegend, "location");
445 inout = findstr (position, "outside");
446 if (! isempty (inout))
448 position = position(1:inout-1);
453 if (strcmp (orientation, "default"))
454 orientation = get (hlegend, "orientation");
456 box = get (hlegend, "box");
457 fkids = get (fig, "children");
462 if (strcmp (textpos, "default"))
465 if (strcmp (position, "default"))
466 position = "northeast";
468 if (strcmp (orientation, "default"))
469 orientation = "vertical";
474 ## Get axis size and fontsize in points.
475 ## Rely on listener to handle coversion.
476 units = get (ca(1), "units");
477 fontunits = get (ca(1), "fontunits");
479 set (ca(1), "units", "points");
480 set (ca(1), "fontunits", "points");
481 ca_pos = get (ca(1), "position");
482 ca_outpos = get (ca(1), "outerposition");
483 ca_fontsize = get (ca(1), "fontsize");
484 unwind_protect_cleanup
485 set (ca(1), "units", units);
486 set (ca(1), "fontunits", fontunits);
489 ## Padding between legend entries horizontally and vertically
493 ## Length of line segments in the legend in points
496 ## Create the axis first
497 ## FIXME hlegend should inherit properties from "ca"
498 curaxes = get (fig, "currentaxes");
500 ud = ancestor(hplots, "axes");
502 ud = unique ([ud{:}]);
504 if (isempty (hlegend))
506 hlegend = axes ("tag", "legend", "userdata", struct ("handle", ud),
508 "xtick", [], "ytick", [], "xticklabel", "",
509 "yticklabel", "", "zticklabel", "",
510 "xlim", [0, 1], "ylim", [0, 1], "visible", "off",
511 "activepositionproperty", "position");
515 delete (get (hlegend, "children"));
518 ## Add text label to the axis first, checking their extents
519 nentries = numel (hplots);
524 if (strcmp (textpos, "right"))
525 texthandle = [texthandle, text(0, 0, text_strings {k},
526 "horizontalalignment", "left",
527 "userdata", hplots(k))];
529 texthandle = [texthandle, text(0, 0, text_strings {k},
530 "horizontalalignment", "right",
531 "userdata", hplots(k))];
533 units = get (texthandle (end), "units");
535 set (texthandle (end), "units", "points");
536 extents = get (texthandle (end), "extent");
537 maxwidth = max (maxwidth, extents (3));
538 maxheight = max (maxheight, extents (4));
539 unwind_protect_cleanup
540 set (texthandle (end), "units", units);
545 if (strcmp (orientation, "vertical"))
546 height = nentries * (ypad + maxheight);
548 if (height > ca_pos (4))
549 ## Avoid shrinking the height of the axis to zero if outside
550 num1 = ca_pos(4) / (maxheight + ypad) / 2;
553 if (height > 0.9 * ca_pos (4))
554 num1 = 0.9 * ca_pos(4) / (maxheight + ypad);
558 width = nentries * (ypad + maxwidth);
560 if (width > ca_pos (3))
561 ## Avoid shrinking the width of the axis to zero if outside
562 num1 = ca_pos(3) / (maxwidth + ypad) / 2;
565 if (width > 0.9 * ca_pos (3))
566 num1 = 0.9 * ca_pos(3) / (maxwidth + ypad);
570 num2 = ceil (nentries / num1);
572 xstep = 3 * xpad + (maxwidth + linelength);
573 if (strcmp (textpos, "right"))
575 txoffset = 2 * xpad + linelength;
577 xoffset = 2 * xpad + maxwidth;
578 txoffset = xpad + maxwidth;
580 ystep = (ypad + maxheight);
583 ## Place the legend in the desired position
584 if (strcmp (orientation, "vertical"))
585 lpos = [0, 0, num2 * xstep, num1 * ystep];
587 lpos = [0, 0, num1 * xstep, num2 * ystep];
592 lpos = [ca_pos(1) + (ca_pos(3) - lpos(3)) / 2, ...
593 ca_outpos(2) + ca_outpos(4) - lpos(4) - ypad, lpos(3), ...
596 new_pos = [ca_pos(1), ca_pos(2), ca_pos(3), ca_pos(4) - lpos(4)];
598 lpos = [ca_pos(1) + (ca_pos(3) - lpos(3)) / 2, ...
599 ca_pos(2) + ca_pos(4) - lpos(4) - ypad, lpos(3), lpos(4)];
603 lpos = [ca_pos(1) + (ca_pos(3) - lpos(3)) / 2, ...
604 ca_outpos(2) + ypad, lpos(3), lpos(4)];
605 new_pos = [ca_pos(1), ca_pos(2) + lpos(4), ca_pos(3), ...
606 ca_pos(4) - lpos(4)];
608 lpos = [ca_pos(1) + (ca_pos(3) - lpos(3)) / 2, ...
609 ca_pos(2) + ypad, lpos(3), lpos(4)];
613 lpos = [ca_outpos(1) + ca_outpos(3) - lpos(3) - ypad, ...
614 ca_pos(2) + (ca_pos(4) - lpos(4)) / 2, lpos(3), lpos(4)];
615 new_pos = [ca_pos(1), ca_pos(2), ca_pos(3) - lpos(3), ca_pos(4)];
617 lpos = [ca_pos(1) + ca_pos(3) - lpos(3) - ypad, ...
618 ca_pos(2) + (ca_pos(4) - lpos(4)) / 2, lpos(3), lpos(4)];
622 lpos = [ca_outpos(1) + ypad, ...
623 ca_pos(2) + (ca_pos(4) - lpos(4)) / 2, ...
625 new_pos = [ca_pos(1) + lpos(3), ca_pos(2), ...
626 ca_pos(3) - lpos(3), ca_pos(4)];
628 lpos = [ca_pos(1) + ypad, ...
629 ca_pos(2) + (ca_pos(4) - lpos(4)) / 2, lpos(3), lpos(4)];
633 lpos = [ca_outpos(1) + ca_outpos(3) - lpos(3) - ypad, ...
634 ca_pos(2) + ca_pos(4) - lpos(4), lpos(3), lpos(4)];
635 new_pos = [ca_pos(1), ca_pos(2), ca_pos(3) - lpos(3), ca_pos(4)];
637 lpos = [ca_pos(1) + ca_pos(3) - lpos(3) - ypad, ...
638 ca_pos(2) + ca_pos(4) - lpos(4) - ypad, lpos(3), lpos(4)];
642 lpos = [ca_outpos(1) + ypad , ca_pos(2) + ca_pos(4) - lpos(4), ...
644 new_pos = [ca_pos(1) + lpos(3), ca_pos(2), ...
645 ca_pos(3) - lpos(3), ca_pos(4)];
647 lpos = [ca_pos(1) + ypad, ...
648 ca_pos(2) + ca_pos(4) - lpos(4) - ypad, lpos(3), lpos(4)];
652 lpos = [ca_outpos(1) + ca_outpos(3) - lpos(3) - ypad, ...
653 ca_pos(2), lpos(3), lpos(4)];
654 new_pos = [ca_pos(1), ca_pos(2), ...
655 ca_pos(3) - lpos(3), ca_pos(4)];
657 lpos = [ca_pos(1) + ca_pos(3) - lpos(3) - ypad, ...
658 ca_pos(2) + ypad, lpos(3), lpos(4)];
662 lpos = [ca_outpos(1) + ypad, ca_pos(2), lpos(3), lpos(4)];
663 new_pos = [ca_pos(1) + lpos(3), ca_pos(2), ...
664 ca_pos(3) - lpos(3), ca_pos(4)];
666 lpos = [ca_pos(1) + ypad, ca_pos(2) + ypad, lpos(3), lpos(4)];
670 units = get (hlegend, "units");
672 set (hlegend, "units", "points");
673 set (hlegend, "position", lpos);
674 unwind_protect_cleanup
675 set (hlegend, "units", units);
678 ## Now write the line segments and place the text objects correctly
681 for k = 1 : numel (hplots)
682 hobjects = [hobjects, texthandle (k)];
683 switch (get (hplots(k), "type"))
685 color = get (hplots(k), "color");
686 style = get (hplots(k), "linestyle");
687 if (! strcmp (style, "none"))
688 l1 = line ("xdata", ([xoffset, xoffset + linelength] + xk * xstep) / lpos(3),
689 "ydata", [1, 1] .* (lpos(4) - yoffset - yk * ystep) / lpos(4),
690 "color", color, "linestyle", style, "marker", "none",
691 "userdata", hplots (k));
692 hobjects = [hobjects, l1];
694 marker = get (hplots(k), "marker");
695 if (! strcmp (marker, "none"))
696 l1 = line ("xdata", (xoffset + 0.5 * linelength + xk * xstep) / lpos(3),
697 "ydata", (lpos(4) - yoffset - yk * ystep) / lpos(4),
698 "color", color, "linestyle", "none", "marker", marker,
699 "markeredgecolor", get (hplots (k), "markeredgecolor"),
700 "markerfacecolor", get (hplots (k), "markerfacecolor"),
701 "markersize", get (hplots (k), "markersize"),
702 "userdata", hplots (k));
703 hobjects = [hobjects, l1];
706 addlistener(hplots(k), "color", {@updateline, hlegend, linelength});
707 addlistener(hplots(k), "linestyle", {@updateline, hlegend, linelength});
708 addlistener(hplots(k), "marker", {@updateline, hlegend, linelength});
709 addlistener(hplots(k), "markeredgecolor", {@updateline, hlegend, linelength});
710 addlistener(hplots(k), "markerfacecolor", {@updateline, hlegend, linelength});
711 addlistener(hplots(k), "markersize", {@updateline, hlegend, linelength});
712 addlistener(hplots(k), "displayname", {@updateline, hlegend, linelength});
716 set (texthandle (k), "position", [(txoffset + xk * xstep) / lpos(3), ...
717 (lpos(4) - yoffset - yk * ystep) / lpos(4)]);
718 if (strcmp (orientation, "vertical"))
733 ## Add an invisible text object to original axis
734 ## that when it is destroyed will remove the legend
735 t1 = text (0, 0, "", "parent", ca(1), "tag", "legend",
736 "handlevisibility", "off", "visible", "off",
737 "xliminclude", "off", "yliminclude", "off");
738 set (t1, "deletefcn", {@deletelegend1, hlegend});
740 ## Resize the axis the legend is attached to if the
741 ## legend is "outside" the plot and create listener to
742 ## resize axis to original size if the legend is deleted,
745 for i = 1 : numel (ca)
746 units = get (ca(i), "units");
748 set (ca(i), "units", "points");
749 set (ca (i), "position", new_pos);
750 unwind_protect_cleanup
751 set (ca(i), "units", units);
755 set (hlegend, "deletefcn", {@deletelegend2, ca, ...
756 ca_pos, ca_outpos, t1, hplots});
757 addlistener (hlegend, "visible", {@hideshowlegend, ca, ...
760 set (hlegend, "deletefcn", {@deletelegend2, ca, [], [], t1, hplots});
764 addproperty ("edgecolor", hlegend, "color", [0, 0, 0]);
765 addproperty ("textcolor", hlegend, "color", [0, 0, 0]);
766 addproperty ("location", hlegend, "radio", "north|south|east|west|{northeast}|southeast|northwest|southwest|northoutside|southoutside|eastoutside|westoutside|northeastoutside|southeastoutside|northwestoutside|southwestoutside");
767 addproperty ("orientation", hlegend, "radio",
768 "{vertical}|horizontal");
769 addproperty ("string", hlegend, "any", text_strings);
770 addproperty ("textposition", hlegend, "radio", "{left}|right");
772 set (hlegend, "string", text_strings);
776 set (hlegend, "location", strcat (position, "outside"),
777 "orientation", orientation, "textposition", textpos);
779 set (hlegend, "location", position, "orientation", orientation,
780 "textposition", textpos);
783 addlistener (hlegend, "edgecolor", @updatelegendtext);
784 addlistener (hlegend, "textcolor", @updatelegendtext);
785 addlistener (hlegend, "interpreter", @updatelegendtext);
786 addlistener (hlegend, "location", @updatelegend);
787 addlistener (hlegend, "orientation", @updatelegend);
788 addlistener (hlegend, "string", @updatelegend);
789 addlistener (hlegend, "textposition", @updatelegend);
791 unwind_protect_cleanup
792 set (fig, "currentaxes", curaxes);
799 hobjects2 = hobjects;
801 text_strings2 = text_strings;
806 function updatelegend (h, d)
807 persistent recursive = false;
811 hax = getfield (get (h, "userdata"), "handle");
812 [hplots, text_strings] = __getlegenddata__ (h);
813 h = legend (hax, hplots, get (h, "string"));
814 unwind_protect_cleanup
820 function updatelegendtext (h, d)
821 hax = get (h, "userdata").handle;
822 kids = get (h, "children");
823 text_kids = findobj (kids, "-property", "interpreter", "type", "text");
824 interpreter = get (h, "interpreter");
825 textcolor = get (h, "textcolor");
826 set (kids, "interpreter", interpreter, "color", textcolor);
827 hobj = cell2mat (get (kids, "userdata"));
828 set (hobj, "interpreter", interpreter);
831 function hideshowlegend (h, d, ca, pos1, pos2)
832 isvisible = strcmp (get (h, "visible"), "off");
834 kids = get (h, "children");
835 for i = 1 : numel (kids)
836 if (! strcmp (get (kids(i), "visible"), "off"))
843 for i = 1 : numel (ca)
844 if (ishandle (ca(i)) && strcmp (get (ca(i), "type"), "axes")
845 && (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off"))
846 && strcmp (get (ca(i), "beingdeleted"), "off"))
847 units = get (ca(i), "units");
849 set (ca(i), "units", "points");
851 set (ca(i), "position", pos2);
853 set (ca(i), "position", pos1);
855 unwind_protect_cleanup
856 set (ca(i), "units", units);
862 function deletelegend1 (h, d, ca)
863 if (ishandle (ca) && strcmp (get (ca, "type"), "axes")
864 && (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off"))
865 && strcmp (get (ca, "beingdeleted"), "off"))
870 function deletelegend2 (h, d, ca, pos, outpos, t1, hplots)
871 for i = 1 : numel (ca)
872 if (ishandle (ca(i)) && strcmp (get (ca(i), "type"), "axes")
873 && (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off"))
874 && strcmp (get (ca(i), "beingdeleted"), "off"))
875 if (!isempty (pos) && !isempty(outpos))
876 units = get (ca(i), "units");
878 set (ca(i), "units", "points");
879 set (ca(i), "position", pos, "deletefcn", "");
880 unwind_protect_cleanup
881 set (ca(i), "units", units);
886 set (t1, "deletefcn", "");
888 for i = 1 : numel (hplots)
889 if (strcmp (get (hplots (i), "type"), "line"))
890 dellistener (hplots (i), "color");
891 dellistener (hplots (i), "linestyle");
892 dellistener (hplots (i), "marker");
893 dellistener (hplots (i), "markeredgecolor");
894 dellistener (hplots (i), "markerfacecolor");
895 dellistener (hplots (i), "markersize");
896 dellistener (hplots (i), "displayname");
901 function updateline (h, d, hlegend, linelength)
904 kids = get (hlegend, "children");
905 for i = 1 : numel (kids)
906 if (get (kids (i), "userdata") == h
907 && strcmp (get (kids(i), "type"), "line"))
908 if (strcmp (get (kids (i), "marker"), "none"))
916 linestyle = get (h, "linestyle");
917 marker = get (h, "marker");
918 displayname = get (h, "displayname");
920 if ((isempty (displayname)
921 || (strcmp (marker, "none") && strcmp (linestyle, "none")))
922 && (! isempty (lm) || isempty (ll)))
923 ## An element was removed from the legend. Need to recall the
924 ## legend function to recreate a new legend
925 [hplots, text_strings] = __getlegenddata__ (hlegend);
926 for i = 1 : numel (hplots)
929 text_strings(i) = [];
933 legend (hplots, text_strings);
934 elseif ((!isempty (displayname)
935 && (! strcmp (marker, "none") || ! strcmp (linestyle, "none")))
936 && isempty (lm) && isempty (ll))
937 ## An element was added to the legend. Need to recall the
938 ## legend function to recreate a new legend
939 [hplots, text_strings] = __getlegenddata__ (hlegend);
940 hplots = [hplots, h];
941 text_strings = {text_strings{:}, displayname};
942 legend (hplots, text_strings);
945 ypos1 = get (ll,"ydata");
946 xpos1 = get (ll,"xdata");
948 xpos2 = sum(xpos1) / 2;
954 ypos2 = get (lm,"ydata");
955 xpos2 = get (lm,"xdata");
956 ypos1 = [ypos2, ypos2];
957 xpos1 = xpos2 + [-0.5, 0.5] * linelength;
960 if (! strcmp (linestyle, "none"))
961 line ("xdata", xpos1, "ydata", ypos1, "color", get (h, "color"),
962 "linestyle", get (h, "linestyle"), "marker", "none",
963 "userdata", h, "parent", hlegend);
965 if (! strcmp (marker, "none"))
966 line ("xdata", xpos2, "ydata", ypos2, "color", get (h, "color"),
967 "marker", marker, "markeredgecolor", get (h, "markeredgecolor"),
968 "markerfacecolor", get (h, "markerfacecolor"),
969 "markersize", get (h, "markersize"), "linestyle", "none",
970 "userdata", h, "parent", hlegend);
978 %! plot (x, x, ";I am Blue;", x, 2*x, ";I am Green;", x, 3*x, ";I am Red;")
983 %! plot (x, x, ";I am Blue;", x, 2*x, x, 3*x, ";I am Red;")
984 %! title ("Blue and Green keys, with Green mising")
988 %! plot(1:10, 1:10, 1:10, fliplr(1:10));
989 %! title("incline is blue and decline is green");
990 %! legend({"I am blue", "I am green"}, "location", "east");
991 %! legend({"I am blue", "I am green"}, "location", "east");
997 %! plot(1:10, 1:10, 1:10, fliplr(1:10));
998 %! title("Legend is hidden")
999 %! legend({"I am blue", "I am green"}, "location", "east");
1004 %! plot(1:10, 1:10, 1:10, fliplr(1:10));
1005 %! title("Legend with box on")
1006 %! legend({"I am blue", "I am green"}, "location", "east");
1011 %! plot(1:10, 1:10, 1:10, fliplr(1:10));
1012 %! title("Legend with text to the right")
1013 %! legend({"I am blue", "I am green"}, "location", "east");
1018 %! plot(1:10, 1:10);
1019 %! title("a very long label can sometimes cause problems");
1020 %! legend({"hello world"}, "location", "northeastoutside");
1024 %! plot(1:10, 1:10);
1025 %! title("a very long label can sometimes cause problems");
1026 %! legend("hello world", "location", "northeastoutside");
1031 %! colororder = get (gca, "colororder");
1033 %! h = plot(1:100, i + rand(100,1)); hold on;
1034 %! set (h, "color", colororder(i,:))
1035 %! labels = {labels{:}, cstrcat("Signal ", num2str(i))};
1038 %! title("Signals with random offset and uniform noise")
1039 %! xlabel("Sample Nr [k]"); ylabel("Amplitude [V]");
1040 %! legend(labels, "location", "southoutside");
1046 %! colororder = get (gca, "colororder");
1048 %! h = plot(1:100, i + rand(100,1)); hold on;
1049 %! set (h, "color", colororder(i,:))
1050 %! labels = {labels{:}, cstrcat("Signal ", num2str(i))};
1053 %! title("Signals with random offset and uniform noise")
1054 %! xlabel("Sample Nr [k]"); ylabel("Amplitude [V]");
1055 %! legend(labels{:}, "location", "southoutside")
1060 %! x = linspace (0, 10);
1063 %! stem (x, x.^2, 'g')
1064 %! legend ("linear");
1069 %! x = linspace (0, 10);
1070 %! plot (x, x, x, x.^2);
1071 %! legend ("linear");
1075 %! x = linspace (0, 10);
1076 %! plot (x, x, x, x.^2);
1077 %! legend ("linear", "quadratic");
1081 %! rand_2x3_data1 = [0.341447, 0.171220, 0.284370; 0.039773, 0.731725, 0.779382];
1082 %! bar (rand_2x3_data1);
1084 %! legend ({"1st Bar", "2nd Bar", "3rd Bar"});
1088 %! rand_2x3_data2 = [0.44804, 0.84368, 0.23012; 0.72311, 0.58335, 0.90531];
1089 %! bar (rand_2x3_data2);
1091 %! legend ("1st Bar", "2nd Bar", "3rd Bar");
1097 %! h = plot (x, sin(x), x, cos(x), x, sin(x.^2/10), x, cos(x.^2/10));
1098 %! title ("Only the sin() objects have keylabels");
1099 %! legend (h([1, 3]), {"sin(x)", "sin(x^2/10)"}, "location", "southwest");
1104 %! plot (x, sin(x), ";sin(x);")
1106 %! plot (x, cos(x), ";cos(x);")
1112 %! plot (x, sin(x), ";sin(x);")
1114 %! plot (x, cos(x), ";cos(x);")
1116 %! legend ({"sin(x)", "cos(x)"}, "location", "northeastoutside")
1121 %! plot (x, rand (11));
1122 %! xlabel ("Indices")
1123 %! ylabel ("Random Values")
1124 %! title ("Legend ""off"" should delete the legend")
1125 %! legend (cellstr (num2str ((1:10)')), "location", "northeastoutside")
1127 %! axis ([0, 10, 0 1])
1132 %! subplot (2, 2, 1)
1133 %! plot (x, rand (numel (x)));
1134 %! legend (cellstr (num2str (x')), "location", "northwestoutside")
1136 %! subplot (2, 2, 2)
1137 %! plot (x, rand (numel (x)));
1138 %! legend (cellstr (num2str (x')), "location", "northeastoutside")
1140 %! subplot (2, 2, 3);
1141 %! plot (x, rand (numel (x)));
1142 %! legend (cellstr (num2str (x')), "location", "southwestoutside")
1144 %! subplot (2, 2, 4)
1145 %! plot (x, rand (numel (x)));
1146 %! legend (cellstr (num2str (x')), "location", "southeastoutside")
1152 %! title ("Warn of extra labels")
1153 %! legend ("Hello", "World", "interpreter", "foobar")
1158 %! title ("Turn off TeX interpreter")
1159 %! h = legend ("Hello_World", "foo^bar");
1160 %! set (h, "interpreter", "none")