Подтвердить что ты не робот

Автоматическая легенда 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 числа для следующих сценариев?:

  • легенда ниже сюжета
  • легенда выше сюжета
  • легенда справа от сюжета

Если нет, возможно ли сделать хорошие догадки об этих числах в Python?

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

4b9b3361

Ответ 1

EDIT:

Я ВЫСОКО РЕКОМЕНДУЕТ ИСПОЛЬЗОВАТЬ ОТВЕТ ОТ ВАРИАНТА ОТОБРАЖЕНИЯ: Как вывести легенду из сюжета

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

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()

теперь играем с координатами (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

Ответ 2

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

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

Как упоминалось ранее, bbox_to_anchor находится в координатах Axes и не требует всех 4 аргументов кортежа для прямоугольника. Вы можете просто дать ему двухпараметрический кортеж, содержащий (xpos, ypos) в координатах Axes. Аргумент 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 эквивалентен установке прямых границ (0, 0, 1, 1).