Skip to content

Commit cf3d0f2

Browse files
1 parent 912eb07 commit cf3d0f2

File tree

2 files changed

+86
-5
lines changed

2 files changed

+86
-5
lines changed

lib/matplotlib/legend.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from matplotlib.cbook import silent_list, is_hashable, warn_deprecated
3333
from matplotlib.font_manager import FontProperties
3434
from matplotlib.lines import Line2D
35-
from matplotlib.patches import Patch, Rectangle, Shadow, FancyBboxPatch
35+
from matplotlib.patches import Patch, Rectangle, Shadow, FancyBboxPatch, FancyArrowPatch
3636
from matplotlib.collections import (LineCollection, RegularPolyCollection,
3737
CircleCollection, PathCollection,
3838
PolyCollection)
@@ -43,6 +43,7 @@
4343
from matplotlib.offsetbox import DraggableOffsetBox
4444

4545
from matplotlib.container import ErrorbarContainer, BarContainer, StemContainer
46+
from matplotlib.text import Annotation, Text
4647
from . import legend_handler
4748

4849

@@ -678,7 +679,9 @@ def _approx_text_height(self, renderer=None):
678679
update_func=legend_handler.update_from_first_child),
679680
tuple: legend_handler.HandlerTuple(),
680681
PathCollection: legend_handler.HandlerPathCollection(),
681-
PolyCollection: legend_handler.HandlerPolyCollection()
682+
PolyCollection: legend_handler.HandlerPolyCollection(),
683+
FancyArrowPatch: legend_handler.HandlerFancyArrowPatch(),
684+
Annotation: legend_handler.HandlerAnnotation()
682685
}
683686

684687
# (get|set|update)_default_handler_maps are public interfaces to
@@ -865,6 +868,7 @@ def _init_legend_box(self, handles, labels, markerfirst=True):
865868
children=[self._legend_title_box,
866869
self._legend_handle_box])
867870
self._legend_box.set_figure(self.figure)
871+
self._legend_box.set_offset(self._findoffset)
868872
self.texts = text_list
869873
self.legendHandles = handle_list
870874

@@ -1219,12 +1223,12 @@ def _get_legend_handles(axs, legend_handler_map=None):
12191223
handles_original = []
12201224
for ax in axs:
12211225
handles_original += (ax.lines + ax.patches +
1222-
ax.collections + ax.containers)
1226+
ax.collections + ax.containers+ax.texts)
12231227
# support parasite axes:
12241228
if hasattr(ax, 'parasites'):
12251229
for axx in ax.parasites:
12261230
handles_original += (axx.lines + axx.patches +
1227-
axx.collections + axx.containers)
1231+
axx.collections + axx.containers+ax.texts)
12281232

12291233
handler_map = Legend.get_default_handler_map()
12301234

lib/matplotlib/legend_handler.py

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ def legend_artist(self, legend, orig_handle, fontsize, handlebox)
2929
import numpy as np
3030

3131
from matplotlib.lines import Line2D
32-
from matplotlib.patches import Rectangle
32+
from matplotlib.patches import Rectangle, FancyArrowPatch
3333
import matplotlib.collections as mcoll
34+
from matplotlib.text import Text, Annotation
3435
import matplotlib.colors as mcolors
3536

3637

@@ -723,3 +724,79 @@ def create_artists(self, legend, orig_handle,
723724
self.update_prop(p, orig_handle, legend)
724725
p.set_transform(trans)
725726
return [p]
727+
728+
729+
730+
class HandlerFancyArrowPatch(HandlerPatch):
731+
"""
732+
Handler for FancyArrowPatch instances.
733+
"""
734+
def _create_patch(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize):
735+
arrow = FancyArrowPatch([-xdescent,
736+
-ydescent + height / 2],
737+
[-xdescent + width,
738+
-ydescent + height / 2],
739+
mutation_scale=width / 3)
740+
arrow.set_arrowstyle(orig_handle.get_arrowstyle())
741+
return arrow
742+
743+
744+
745+
746+
class HandlerAnnotation(HandlerBase):
747+
"""
748+
Handler for Annotation instances.
749+
Defers to HandlerFancyArrowPatch to draw the annotation arrow (if any).
750+
Parameters
751+
----------
752+
pad : float, optional
753+
If None, fall back to `legend.borderpad` asstr the default.
754+
In units of fraction of font size.
755+
Default is None.
756+
width_ratios : tuple, optional
757+
The relative width of the respective text/arrow legend annotation pair.
758+
Must be of length 2.
759+
Default is [1,4].
760+
"""
761+
762+
def __init__(
763+
self,
764+
pad=None,
765+
width_ratios=[1, 4],
766+
**kwargs
767+
):
768+
769+
self._pad = pad
770+
self._width_ratios = width_ratios
771+
772+
HandlerBase.__init__(self, **kwargs)
773+
774+
def create_artists(
775+
self,
776+
legend,
777+
orig_handle,
778+
xdescent,
779+
ydescent,
780+
width,
781+
height,
782+
fontsize,
783+
trans,
784+
):
785+
786+
if orig_handle.arrow_patch is not None:
787+
788+
# Arrow without text
789+
790+
handler = HandlerFancyArrowPatch()
791+
handle = orig_handle.arrow_patch
792+
793+
return handler.create_artists(
794+
legend,
795+
handle,
796+
xdescent,
797+
ydescent,
798+
width,
799+
height,
800+
fontsize,
801+
trans,
802+
)

0 commit comments

Comments
 (0)