这使得标记可以拾取:import numpy as np
import matplotlib.pyplot as plt
import matplotlib.legend_handler
from matplotlib.container import ErrorbarContainer
class re_order_errorbarHandler(matplotlib.legend_handler.HandlerErrorbar):
"""
Sub-class the standard error-bar handler
"""
def create_artists(self, *args, **kwargs):
# call the parent class function
a_list = matplotlib.legend_handler.HandlerErrorbar.create_artists(self, *args, **kwargs)
# re-order the artist list, only the first artist is added to the
# legend artist list, this is the one that corresponds to the markers
a_list = a_list[-1:] + a_list[:-1]
return a_list
my_handler_map = {ErrorbarContainer: re_order_errorbarHandler(numpoints=2)}
fig, ax = plt.subplots()
x = np.linspace(0,10,100)
y = np.sin(x) + np.random.rand(100)
yerr = np.random.rand(100)
erbpl1 = ax.errorbar(x, y, yerr=yerr, fmt='o', label='A')
erbpl2 = ax.errorbar(x, 0.02*y, yerr=yerr, fmt='o', label='B')
leg = ax.legend(handler_map=my_handler_map)
lines = [erbpl1, erbpl2]
lined = dict()
# not strictly sure about ordering, but
for legline, origline in zip(leg.legendHandles, lines):
legline.set_picker(5) # 5 pts tolerance
lined[legline] = origline
def onpick(event):
# on the pick event, find the orig line corresponding to the
# legend proxy line, and toggle the visibility
legline = event.artist
origline = lined[legline]
for a in origline.get_children():
vis = not a.get_visible()
a.set_visible(vis)
# Change the alpha on the line in the legend so we can see what lines
# have been toggled
if vis:
legline.set_alpha(1.0)
else:
legline.set_alpha(0.2)
fig.canvas.draw()
fig.canvas.mpl_connect('pick_event', onpick)
这里要做的是,ErrorbarContainers的标准处理程序使用4个艺术家来生成图例项(LineCollection表示条形,LineCollection表示大写,Line2D表示连接线,Line2D表示标记)。生成艺术家的代码只返回添加到图例的艺术家列表中的第一个艺术家(请参见matplotlib.legend_handler.HandlerBase.__call__)。错误条列表中的第一个艺术家恰好是行集合,它是垂直线,它最终以leg.legendHandles结束。采摘不起作用的原因似乎是他们被其他艺术家隐藏了(我想)。在
解决方案是生成一个HandlerErrorbar的局部子类,它对艺术家列表重新排序,这样保存在leg.legendHandles中的艺术家就是标记的Line2D对象。在
我可能会打开一个公关,使这成为默认行为。在