|
| 1 | +.. _plotting-guide-legend: |
| 2 | + |
| 3 | +************ |
| 4 | +Legend guide |
| 5 | +************ |
| 6 | + |
| 7 | +Do not proceed unless you already have read :func:`~matplotlib.pyplot.legend` and |
| 8 | +:class:`matplotlib.legend.Legend`! |
| 9 | + |
| 10 | + |
| 11 | +What to be displayed |
| 12 | +==================== |
| 13 | + |
| 14 | +The legend command has a following call signature:: |
| 15 | + |
| 16 | + legend(*args, **kwargs) |
| 17 | + |
| 18 | +If len(args) is 2, the first argument should be a list of artist to be |
| 19 | +labeled, and the second argument should a list of string labels. If |
| 20 | +len(args) is 0, it automatically generate the legend from label |
| 21 | +properties of the child artists by calling |
| 22 | +:meth:`~matplotlib.axes.Axes.get_legend_handles_labels` method. |
| 23 | +For example, *ax.legend()* is equivalaent to:: |
| 24 | + |
| 25 | + handles, labels = ax.get_legend_handles_labels() |
| 26 | + ax.legend(handles, labels) |
| 27 | + |
| 28 | +The :meth:`~matplotlib.axes.Axes.get_legend_handles_labels` method |
| 29 | +returns a tuple of two lists, i.e., list of artists and list of labels |
| 30 | +(python string). However, it does not return all of its child |
| 31 | +artists. It returns all artists in *ax.lines* and *ax.patches* and |
| 32 | +some artists in *ax.collection* which are instance of |
| 33 | +:class:`~matplotlib.collections.LineCollection` or |
| 34 | +:class:`~matplotlib.collections.RegularPolyCollection`. The label |
| 35 | +attributes (returned by get_label() method) of collected artists are |
| 36 | +used as text labels. If label attribute is empty string or starts with |
| 37 | +"_", that artist will be ignored. |
| 38 | + |
| 39 | + |
| 40 | + * Note that not all kind of artists are supported by the legend. The |
| 41 | + following is the list of artists that are currently supported. |
| 42 | + |
| 43 | + * :class:`~matplotlib.lines.Line2D` |
| 44 | + * :class:`~matplotlib.patches.Patch` |
| 45 | + * :class:`~matplotlib.collections.LineCollection` |
| 46 | + * :class:`~matplotlib.collections.RegularPolyCollection` |
| 47 | + |
| 48 | + Unfortunately, there is no easy workaround when you need legend for |
| 49 | + an artist not in the above list (You may use one of the supported |
| 50 | + artist as a proxy. See below), or customize it beyond what is |
| 51 | + supported by :class:`matplotlib.legend.Legend`. |
| 52 | + |
| 53 | + * Remember that some *pyplot* commands return artist not supported by |
| 54 | + legend, e.g., :func:`~matplotlib.pyplot.fill_between` returns |
| 55 | + :class:`~matplotlib.collections.PolyCollection` that is not |
| 56 | + supported. Or some return mupltiple artists. For example, |
| 57 | + :func:`~matplotlib.pyplot.plot` returns list of |
| 58 | + :class:`~matplotlib.lines.Line2D` instances, and |
| 59 | + :func:`~matplotlib.pyplot.errorbar` returns a length 3 tuple of |
| 60 | + :class:`~matplotlib.lines.Line2D` instances. |
| 61 | + |
| 62 | + * The legend does not care about the axes that given artists belongs, |
| 63 | + i.e., the artists may belong to other axes or even none. |
| 64 | + |
| 65 | + |
| 66 | +Adjusting the Order of Legend items |
| 67 | +----------------------------------- |
| 68 | + |
| 69 | +When you want to customize the list of artists to be displayed in the |
| 70 | +legend, or their order of appearance. There are a two options. First, |
| 71 | +you can keep lists of artists and labels, and explicitly use these for the first two argument of the legend call.:: |
| 72 | + |
| 73 | + p1, = plot([1,2,3]) |
| 74 | + p2, = plot([3,2,1]) |
| 75 | + p3, = plot([2,3,1]) |
| 76 | + legend([p2, p1], ["line 2", "line 1"]) |
| 77 | + |
| 78 | +Or you may use :meth:`~matplotlib.axes.Axes.get_legend_handles_labels` |
| 79 | +to retrieve list of artist and labels and manipulate them before |
| 80 | +feeding them to legend call.:: |
| 81 | + |
| 82 | + ax = subplot(1,1,1) |
| 83 | + p1, = ax.plot([1,2,3], label="line 1") |
| 84 | + p2, = ax.plot([3,2,1], label="line 2") |
| 85 | + p3, = ax.plot([2,3,1], label="line 3") |
| 86 | + |
| 87 | + handles, labels = ax.get_legend_handles_labels() |
| 88 | + |
| 89 | + # reverse the order |
| 90 | + ax.legend(handles[::-1], labels[::-1]) |
| 91 | + |
| 92 | + # or sort them by labels |
| 93 | + import operator |
| 94 | + hl = sorted(zip(handles, labels), |
| 95 | + key=operator.itemgetter(1)) |
| 96 | + handles2, labels2 = zip(*hl) |
| 97 | + |
| 98 | + ax.legend(handles2, labels2) |
| 99 | + |
| 100 | + |
| 101 | +Using Proxy Artist |
| 102 | +------------------ |
| 103 | + |
| 104 | +When you want to display legend for an artist not supported by the |
| 105 | +matplotlib, you may use other supported artist as a proxy. For |
| 106 | +example, you may creates an proxy artist without adding it to the axes |
| 107 | +(so the proxy artist will not be drawn in the main axes) and feet it |
| 108 | +to the legend function.:: |
| 109 | + |
| 110 | + p = Rectangle((0, 0), 1, 1, fc="r") |
| 111 | + legend([p], ["Red Rectangle"]) |
| 112 | + |
| 113 | + |
| 114 | +Multicolumn Legend |
| 115 | +================== |
| 116 | + |
| 117 | +By specifying the keyword argument *ncol*, you can have a multi-column |
| 118 | +legend. Also, mode="expand" horizontally expand the legend to fill the |
| 119 | +axes area. See `legend_demo3.py |
| 120 | +<http://matplotlib.sourceforge.net/examples/pylab_examples/legend_demo3.html>`_ |
| 121 | +for example. |
| 122 | + |
| 123 | + |
| 124 | +Legend location |
| 125 | +=============== |
| 126 | + |
| 127 | +The location of the legend can be specified by the keyword argument |
| 128 | +*loc*, either by string or a integer number. |
| 129 | + |
| 130 | +============= ====== |
| 131 | + String Number |
| 132 | +============= ====== |
| 133 | + upper right 1 |
| 134 | + upper left 2 |
| 135 | + lower left 3 |
| 136 | + lower right 4 |
| 137 | + right 5 |
| 138 | + center left 6 |
| 139 | + center right 7 |
| 140 | + lower center 8 |
| 141 | + upper center 9 |
| 142 | + center 10 |
| 143 | +============= ====== |
| 144 | + |
| 145 | +By default, the legend will anchor to the bbox of the axes |
| 146 | +(for legend) or the bbox of the figure (figlegend). You can specify |
| 147 | +your own bbox using *bbox_to_anchor* argument. *bbox_to_anchor* can be an |
| 148 | +instance of :class:`~matplotlib.transforms.BboxBase`, a tuple of 4 |
| 149 | +floats (x, y, width, height of the bbox), or a tuple of 2 floats (x, y |
| 150 | +with width=height=0). Unless *bbox_transform* argument is given, the |
| 151 | +coordinates (even for the bbox instance) are considered as normalized |
| 152 | +axes coordinates. |
| 153 | + |
| 154 | +For example, if you want your axes legend located at the figure corner |
| 155 | +(instead of the axes corner):: |
| 156 | + |
| 157 | + l = legend(bbox_to_anchor=(0, 0, 1, 1), transform=gcf().transFigure) |
| 158 | + |
| 159 | +Also, you can place above or outer right-hand side of the axes, |
| 160 | + |
| 161 | +.. plot:: users/plotting/examples/simple_legend01.py |
| 162 | + :include-source: |
| 163 | + |
| 164 | + |
| 165 | +Multiple Legend |
| 166 | +=============== |
| 167 | + |
| 168 | +Sometime, you want to split the legend into multiple ones.:: |
| 169 | + |
| 170 | + p1, = plot([1,2,3]) |
| 171 | + p2, = plot([3,2,1]) |
| 172 | + legend([p1], ["Test1"], loc=1) |
| 173 | + legend([p2], ["Test2"], loc=4) |
| 174 | + |
| 175 | +However, the above code only shows the second legend. When the legend |
| 176 | +command is called, a new legend instance is created and old ones are |
| 177 | +removed from the axes. Thus, you need to manually add the removed |
| 178 | +legend. |
| 179 | + |
| 180 | +.. plot:: users/plotting/examples/simple_legend02.py |
| 181 | + :include-source: |
0 commit comments