Matplotlib автоматическая легенда вне сюжета [дубликат]

этот вопрос уже есть ответ здесь:

Я пытаюсь использовать ключевое слово bbox_to_anchor() в графике matplotlib в Python.

вот очень основной сюжет, который я произвел:

import matplotlib.pyplot as plt
x = [1,2,3]
plt.subplot(211)
plt.plot(x, label="test1")
plt.plot([3,2,1], label="test2")
plt.legend(bbox_to_anchor=(0, -0.15, 1, 0), loc=2, ncol=2, mode="expand", borderaxespad=0)
plt.show()

он основан на примере здесь: http://matplotlib.org/users/legend_guide.html#plotting-guide-legend

Я пытаюсь автоматически разместить легенду вне сюжета, используя bbox_to_anchor(). В этом примере bbox_to_anchor() перечислил 4 аргументов.

в этом конкретном примере (выше) легенда помещается ниже участка, поэтому число -0.15 необходимо вводить вручную каждый раз, когда участок изменяется (размер шрифта, заголовок оси удаляется и т. д.). можно ли автоматически рассчитать эти 4 числа для следующих сценариев?:

  1. легенда ниже участка
  2. легенда выше участка
  3. легенда справа от участка

если нет, можно ли сделать хорошие предположения об этих числах в Python?

кроме того, в приведенном выше примере кода я установил последние 2 числа в bbox_to_anchor() до 1 и 0, так как я не понимаю, что они такое или как они работают. что делают последние 2 числа в bbox_to_anchor() в смысле?

2 ответов


EDIT:

Я настоятельно рекомендую использовать ответ от ImportanceOfBeingErnest: Как убрать легенду из сюжета

Это легче понять:

import matplotlib.pyplot as plt
x = [1,2,3]
plt.subplot(211)
plt.plot(x, label="test1")
plt.plot([3,2,1], label="test2")
plt.legend(bbox_to_anchor=(0, 1), loc='upper left', ncol=1)
plt.show()

Теперь играйте с координатами to (x, y). Для loc вы можете использовать:

valid locations are:
right
center left
upper right
lower right
best
center
lower left
center right
upper left
upper center
lower center

аргумент bbox_to_anchor находится в координатах осей. matplotlib использует различные системы координат для облегчения размещения объектов на экране. При работе с легендами позиционирования критическими системами координат являются координаты осей, координаты рисунка и координаты отображения (в пикселях), как показано ниже:

системы координат matplotlib

как уже упоминалось ранее, bbox_to_anchor находится в координатах осей и не требует все 4 аргумента кортежа для прямоугольника. Вы можете просто дать ему кортеж из двух аргументов, содержащий (xpos, ypos) в координатах осей. Аргумент loc в этом случае будет определять точку привязки для легенды. Таким образом, чтобы прикрепить легенду к внешней правой части осей и выровнять с верхним краем, вы должны выдать следующее:

lgd = plt.legend(bbox_to_anchor=(1.01, 1), loc='upper left')

это, однако, не перемещает оси относительно фигуры, и это, вероятно, расположит легенду с холста фигуры. Автоматически переместите холст рисунка для выравнивания с осями и легендой, я использовал следующий алгоритм.

во-первых, нарисуйте легенду на холсте, чтобы назначить ей реальные пиксельные координаты:

plt.gcf().canvas.draw()

затем определите преобразование, чтобы перейти от координат пикселей к координатам фигуры:

invFigure = plt.gcf().transFigure.inverted()

затем получите экстенты легенды в пикселях и преобразуйте их в координаты фигуры. Вытащите самый дальний экстент в направлении x, так как это направление холста, которое нам нужно настроить:

lgd_pos = lgd.get_window_extent()
lgd_coord = invFigure.transform(lgd_pos)
lgd_xmax = lgd_coord[1, 0]

сделайте то же самое для осей:

ax_pos = plt.gca().get_window_extent()
ax_coord = invFigure.transform(ax_pos)
ax_xmax = ax_coord[1, 0]

наконец, отрегулируйте рисунок холста с помощью tight_layout для пропорции осей, которые должны перемещаться, чтобы освободить место для легенды, чтобы поместиться в холсте:

shift = 1 - (lgd_xmax - ax_xmax)
plt.gcf().tight_layout(rect=(0, 0, shift, 1))

обратите внимание, что аргумент rect для tight_layout находится в координатах рисунка и определяет нижний левый и верхний правый углы прямоугольника, содержащего границы Tight_layout осей, которые не включают легенду. Так простой вызов tight_layout эквивалентен установке прямых границ (0, 0, 1, 1).