|
27 | 27 | def legend_artist(self, legend, orig_handle, fontsize, handlebox)
|
28 | 28 | """
|
29 | 29 |
|
| 30 | +from collections.abc import Sequence |
30 | 31 | from itertools import cycle
|
31 | 32 |
|
32 | 33 | import numpy as np
|
33 | 34 |
|
34 |
| -from matplotlib import cbook |
| 35 | +from matplotlib import _api, cbook |
35 | 36 | from matplotlib.lines import Line2D
|
36 | 37 | from matplotlib.patches import Rectangle
|
37 | 38 | import matplotlib.collections as mcoll
|
@@ -119,6 +120,9 @@ def legend_artist(self, legend, orig_handle,
|
119 | 120 | xdescent, ydescent, width, height,
|
120 | 121 | fontsize, handlebox.get_transform())
|
121 | 122 |
|
| 123 | + if isinstance(artists, _Line2DHandleList): |
| 124 | + artists = [artists[0]] |
| 125 | + |
122 | 126 | # create_artists will return a list of artists.
|
123 | 127 | for a in artists:
|
124 | 128 | handlebox.add_artist(a)
|
@@ -204,10 +208,12 @@ def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize):
|
204 | 208 | return ydata
|
205 | 209 |
|
206 | 210 |
|
207 |
| -class HandlerLine2D(HandlerNpoints): |
| 211 | +class HandlerLine2DCompound(HandlerNpoints): |
208 | 212 | """
|
209 |
| - Handler for `.Line2D` instances. |
| 213 | + Original handler for `.Line2D` instances, that relies on combining |
| 214 | + a line-only with a marker-only artist. May be deprecated in the future. |
210 | 215 | """
|
| 216 | + |
211 | 217 | def __init__(self, marker_pad=0.3, numpoints=None, **kwargs):
|
212 | 218 | """
|
213 | 219 | Parameters
|
@@ -252,6 +258,77 @@ def create_artists(self, legend, orig_handle,
|
252 | 258 | return [legline, legline_marker]
|
253 | 259 |
|
254 | 260 |
|
| 261 | +class _Line2DHandleList(Sequence): |
| 262 | + def __init__(self, legline): |
| 263 | + self._legline = legline |
| 264 | + |
| 265 | + def __len__(self): |
| 266 | + return 2 |
| 267 | + |
| 268 | + def __getitem__(self, index): |
| 269 | + if index != 0: |
| 270 | + # Make HandlerLine2D return [self._legline] directly after |
| 271 | + # deprecation elapses. |
| 272 | + _api.warn_deprecated( |
| 273 | + "3.5", message="Access to the second element returned by " |
| 274 | + "HandlerLine2D is deprecated since %(since)s; it will be " |
| 275 | + "removed %(removal)s.") |
| 276 | + return [self._legline, self._legline][index] |
| 277 | + |
| 278 | + |
| 279 | +class HandlerLine2D(HandlerNpoints): |
| 280 | + """ |
| 281 | + Handler for `.Line2D` instances. |
| 282 | +
|
| 283 | + See Also |
| 284 | + -------- |
| 285 | + HandlerLine2DCompound : An earlier handler implementation, which used one |
| 286 | + artist for the line and another for the marker(s). |
| 287 | + """ |
| 288 | + |
| 289 | + def __init__(self, marker_pad=0.3, numpoints=None, **kw): |
| 290 | + """ |
| 291 | + Parameters |
| 292 | + ---------- |
| 293 | + marker_pad : float |
| 294 | + Padding between points in legend entry. |
| 295 | + numpoints : int |
| 296 | + Number of points to show in legend entry. |
| 297 | + **kwargs |
| 298 | + Keyword arguments forwarded to `.HandlerNpoints`. |
| 299 | + """ |
| 300 | + HandlerNpoints.__init__(self, marker_pad=marker_pad, |
| 301 | + numpoints=numpoints, **kw) |
| 302 | + |
| 303 | + def create_artists(self, legend, orig_handle, |
| 304 | + xdescent, ydescent, width, height, fontsize, |
| 305 | + trans): |
| 306 | + |
| 307 | + xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, |
| 308 | + width, height, fontsize) |
| 309 | + |
| 310 | + markevery = None |
| 311 | + if self.get_numpoints(legend) == 1: |
| 312 | + # Special case: one wants a single marker in the center |
| 313 | + # and a line that extends on both sides. One will use a |
| 314 | + # 3 points line, but only mark the #1 (i.e. middle) point. |
| 315 | + xdata = np.linspace(xdata[0], xdata[-1], 3) |
| 316 | + markevery = [1] |
| 317 | + |
| 318 | + ydata = np.full_like(xdata, (height - ydescent) / 2) |
| 319 | + legline = Line2D(xdata, ydata, markevery=markevery) |
| 320 | + |
| 321 | + self.update_prop(legline, orig_handle, legend) |
| 322 | + |
| 323 | + if legend.markerscale != 1: |
| 324 | + newsz = legline.get_markersize() * legend.markerscale |
| 325 | + legline.set_markersize(newsz) |
| 326 | + |
| 327 | + legline.set_transform(trans) |
| 328 | + |
| 329 | + return _Line2DHandleList(legline) |
| 330 | + |
| 331 | + |
255 | 332 | class HandlerPatch(HandlerBase):
|
256 | 333 | """
|
257 | 334 | Handler for `.Patch` instances.
|
@@ -710,6 +787,8 @@ def create_artists(self, legend, orig_handle,
|
710 | 787 | _a_list = handler.create_artists(
|
711 | 788 | legend, handle1,
|
712 | 789 | next(xds_cycle), ydescent, width, height, fontsize, trans)
|
| 790 | + if isinstance(_a_list, _Line2DHandleList): |
| 791 | + _a_list = [_a_list[0]] |
713 | 792 | a_list.extend(_a_list)
|
714 | 793 |
|
715 | 794 | return a_list
|
|
0 commit comments