This is one solution to https://github.com/matplotlib/matplotlib/issues/2018
fig, ax = plt.subplots()
p1 = ax.scatter([0.1],[0.5],c='r',marker='s')
p2 = ax.scatter([0.3],[0.2],c='b',marker='o')
l = ax.legend([(p1,p2)],['points'],scatterpoints=2)
With above code, a TupleHandler is used to create legend handles which
simply overplot two handles (there are red squares behind the blue
circles if you look carefylly. What you want to do is make the second
marker of first handle and the first marker of the second handle
invisible. Unfortunately, the TupleHandler is a rather recent addition
and you need a special function to get all the handles. Otherwise, you
can use the Legend.legendHandles
attribute (it only show the first
handle for the TupleHandler).
def get_handle_lists(l):
"""returns a list of lists of handles.
"""
tree = l._legend_box.get_children()[1]
for column in tree.get_children():
for row in column.get_children():
yield row.get_children()[0].get_children()
handles_list = list(get_handle_lists(l))
handles = handles_list[0] # handles is a list of two PathCollection.
# The first one is for red squares, and the second
# is for blue circles.
handles[0].set_facecolors(["r", "none"]) # for the fist
# PathCollection, make the
# second marker invisible by
# setting their facecolor and
# edgecolor to "none."
handles[0].set_edgecolors(["k", "none"])
handles[1].set_facecolors(["none", "b"])
handles[1].set_edgecolors(["none", "k"])
fig