Размещение легенды ( bbox_to_anchor
)
Легенда располагается внутри ограничительной рамки осей, используя loc
аргумент to plt.legend
.
Например, loc="upper right"
легенда размещается в правом верхнем углу ограничивающего прямоугольника, который по умолчанию расширяется от (0,0)
до до (1,1)
в координатах осей (или в обозначениях ограничивающего прямоугольника (x0,y0, width, height)=(0,0,1,1)
).
Чтобы разместить легенду за пределами ограничительной рамки осей, можно указать кортеж (x0,y0)
координат осей нижнего левого угла легенды.
plt.legend(loc=(1.04,0))
Однако более универсальным подходом было бы вручную указать ограничивающий прямоугольник, в который следует поместить легенду, используя bbox_to_anchor
аргумент. Можно ограничить себя, чтобы предоставить только (x0,y0)
часть bbox. Это создает поле с нулевым интервалом, из которого легенда будет расширяться в направлении, заданном loc
аргументом. Например
plt.legend (bbox_to_anchor = (1.04,1), loc = "верхний левый")
размещает легенду вне осей, так что верхний левый угол легенды находится в положении (1.04,1)
в координатах осей.
Ниже приведены дополнительные примеры, где дополнительно показано взаимодействие между различными аргументами типа mode
и ncols
.
l1 = plt.legend(bbox_to_anchor=(1.04,1), borderaxespad=0)
l2 = plt.legend(bbox_to_anchor=(1.04,0), loc="lower left", borderaxespad=0)
l3 = plt.legend(bbox_to_anchor=(1.04,0.5), loc="center left", borderaxespad=0)
l4 = plt.legend(bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
mode="expand", borderaxespad=0, ncol=3)
l5 = plt.legend(bbox_to_anchor=(1,0), loc="lower right",
bbox_transform=fig.transFigure, ncol=3)
l6 = plt.legend(bbox_to_anchor=(0.4,0.8), loc="upper right")
Подробности о том, как интерпретировать аргумент из 4-х кортежей bbox_to_anchor
, например l4
, можно найти в этом вопросе . Расширение mode="expand"
расширяет легенду по горизонтали внутри ограничительной рамки, заданной 4-кортежем. Для вертикально развернутой легенды см. Этот вопрос .
Иногда может быть полезно указать ограничивающий прямоугольник в координатах фигуры вместо координат осей. Это показано в примере l5
сверху, где bbox_transform
аргумент используется для размещения легенды в левом нижнем углу рисунка.
Постобработка
Размещение легенды вне осей часто приводит к нежелательной ситуации, когда она полностью или частично выходит за пределы рисунка.
Решения этой проблемы:
Корректировка параметров подплота
Можно настроить параметры подплота так, чтобы оси занимали меньше места внутри фигуры (и тем самым оставляли больше места легенде) с помощью plt.subplots_adjust
. Например
plt.subplots_adjust(right=0.7)
оставляет 30% свободного пространства на правой стороне фигуры, где можно разместить легенду.
Плотная компоновка
Использование plt.tight_layout
Позволяет автоматически настраивать параметры подзаговора таким образом, чтобы элементы фигуры плотно прилегали к краям фигуры. К сожалению, легенда не принимается во внимание в этом автомате, но мы можем предоставить прямоугольник, в который будет помещаться вся область сюжетов (включая метки).
plt.tight_layout(rect=[0,0,0.75,1])
Сохранение рисунка с помощьюbbox_inches = "tight"
аргумента bbox_inches = "tight"
to plt.savefig
можно использовать для сохранения рисунка, чтобы все художники на холсте (включая легенду) помещались в сохраненную область. При необходимости размер фигуры настраивается автоматически.
plt.savefig("output.png", bbox_inches="tight")
- автоматическая настройка параметров подзаговора
В этом ответе можно найти способ автоматической настройки положения подзаголовка таким образом, чтобы легенда помещалась внутри холста без изменения размера фигуры . Создание фигуры с точным размером и без отступов (и легенда вне осей)
Сравнение между случаями, обсужденными выше:
альтернативы
Легенда фигуры
Можно использовать легенду для фигуры вместо осей matplotlib.figure.Figure.legend
. Это стало особенно полезным для версии matplotlib> = 2.1, где не требуется никаких специальных аргументов
fig.legend(loc=7)
создать легенду для всех художников по разным осям фигуры. Легенда размещается с использованием loc
аргумента, аналогично тому, как он расположен внутри осей, но со ссылкой на всю фигуру - следовательно, он будет несколько вне осей автоматически. Осталось отрегулировать вспомогательные сюжеты так, чтобы не было перекрытия между легендой и осями. Здесь будет полезен пункт «Настройка параметров подзаговора» сверху. Пример:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0,2*np.pi)
colors=["#7aa0c4","#ca82e1" ,"#8bcd50","#e18882"]
fig, axes = plt.subplots(ncols=2)
for i in range(4):
axes[i//2].plot(x,np.sin(x+i), color=colors[i],label="y=sin(x+{})".format(i))
fig.legend(loc=7)
fig.tight_layout()
fig.subplots_adjust(right=0.75)
plt.show()
Легенда внутри выделенных осей вспомогательных сюжетов
Альтернативой использованию bbox_to_anchor
будет размещение легенды в выделенных осях вспомогательных сюжетов ( lax
). Поскольку вспомогательный сюжет должен быть меньше сюжета, мы можем использовать его gridspec_kw={"width_ratios":[4,1]}
при создании осей. Мы можем скрыть оси, lax.axis("off")
но все же поместить легенду. Дескрипторы и метки легенды должны быть получены из реального сюжета через h,l = ax.get_legend_handles_labels()
, а затем могут быть переданы легенде в lax
подзаговоре lax.legend(h,l)
. Полный пример ниже.
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 6,2
fig, (ax,lax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[4,1]})
ax.plot(x,y, label="y=sin(x)")
....
h,l = ax.get_legend_handles_labels()
lax.legend(h,l, borderaxespad=0)
lax.axis("off")
plt.tight_layout()
plt.show()
Это создает сюжет, который визуально очень похож на сюжет сверху:
Мы также можем использовать первые оси для размещения легенды, но использовать bbox_transform
оси легенды,
ax.legend(bbox_to_anchor=(0,0,1,1), bbox_transform=lax.transAxes)
lax.axis("off")
При таком подходе нам не нужно получать маркеры легенды извне, но нам нужно указать bbox_to_anchor
аргумент.
Дальнейшее чтение и заметки:
- Рассмотрим Matplotlib руководство легенды с некоторыми примерами других вещей , которые вы хотите сделать с легендами.
- Пример кода для размещения легенд для круговых диаграмм можно найти непосредственно в ответе на этот вопрос: Python - легенда перекрывается с круговой диаграммой
loc
Аргумент может принимать цифры вместо строки, которые делают звонки короче, тем не менее, они не очень интуитивно сопоставляются друг с другом. Вот отображение для справки: