Я рисую легенду о объекте axes в matplotlib, но позиционирование по умолчанию, которое утверждает, что помещает его в умное место, похоже, не работает. В идеале, я бы хотел, чтобы легенда была перетаскиваемой пользователем. Как это можно сделать?
Как создать перетаскиваемую легенду в matplotlib?
Ответ 1
Примечание: теперь это встроено в matplotlib
leg = plt.legend()
if leg:
leg.draggable()
будет работать как ожидалось
Ну, я нашел бит и кусочки решения, разбросанные среди списков рассылки. Я придумал хороший модульный кусок кода, который вы можете зайти и использовать... вот он:
class DraggableLegend:
def __init__(self, legend):
self.legend = legend
self.gotLegend = False
legend.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)
legend.figure.canvas.mpl_connect('pick_event', self.on_pick)
legend.figure.canvas.mpl_connect('button_release_event', self.on_release)
legend.set_picker(self.my_legend_picker)
def on_motion(self, evt):
if self.gotLegend:
dx = evt.x - self.mouse_x
dy = evt.y - self.mouse_y
loc_in_canvas = self.legend_x + dx, self.legend_y + dy
loc_in_norm_axes = self.legend.parent.transAxes.inverted().transform_point(loc_in_canvas)
self.legend._loc = tuple(loc_in_norm_axes)
self.legend.figure.canvas.draw()
def my_legend_picker(self, legend, evt):
return self.legend.legendPatch.contains(evt)
def on_pick(self, evt):
if evt.artist == self.legend:
bbox = self.legend.get_window_extent()
self.mouse_x = evt.mouseevent.x
self.mouse_y = evt.mouseevent.y
self.legend_x = bbox.xmin
self.legend_y = bbox.ymin
self.gotLegend = 1
def on_release(self, event):
if self.gotLegend:
self.gotLegend = False
... и в вашем коде...
def draw(self):
ax = self.figure.add_subplot(111)
scatter = ax.scatter(np.random.randn(100), np.random.randn(100))
legend = DraggableLegend(ax.legend())
Я отправил по электронной почте группу пользователей Matplotlib, а John Hunter был достаточно любезен, чтобы добавить мое решение в SVN HEAD.
В Чт, 28 января 2010 в 15:02, Адам Фрейзер писал:
Я думал, что поделился бы решением проблемы с перетаскиваемой легендой, поскольку мне потребовалось навсегда ассимилировать все разбросанные знания на списки рассылки...
Прохладный - хороший пример. Я добавил код в legend.py. Теперь вы можете сделать
leg = ax.legend()
leg.draggable()чтобы включить режим перетаскивания. Ты можешь неоднократно вызывать эту функцию для переключения состояние перетаскивания.
Я надеюсь, что это полезно для людей, работающих с matplotlib.
Ответ 2
В новых версиях Matplotlib (v1.0.1) это встроено.
def draw(self):
ax = self.figure.add_subplot(111)
scatter = ax.scatter(np.random.randn(100), np.random.randn(100))
legend = ax.legend()
legend.draggable(state=True)
Если вы используете matplotlib интерактивно (например, в режиме pythab в IPython).
plot(range(10), range(10), label="test label")
plot(range(10), [5 for x in range(10)], label="another test")
l = legend()
l.draggable(True)
Ответ 3
В еще более новых версиях (3.0.2) он устарел и потенциально может представлять свойство.
plot(range(10), range(10), label="test label")
plot(range(10), [5 for x in range(10)], label="another test")
plt.legend().set_draggable(True)