Ответ 1
Короткий ответ: вы можете использовать plt.legend
аргументы loc
, bbox_to_anchor
и дополнительно bbox_transform
и mode
, чтобы разместить легенду в осях или фигуре.
Длинная версия:
Шаг 1: Убедитесь, что требуется легенда.
Во многих случаях никакая легенда не требуется вообще, и информация может быть выведена непосредственно контекстом или цветом:
Если сюжет не может жить без легенды, перейдите к шагу 2.
Шаг 2: Убедитесь, что нужна круговая диаграмма.
Во многих случаях круговые диаграммы не являются лучшим способом передачи информации.
Если потребность в круговой диаграмме однозначно определена, давайте переместим легенду.
Размещение легенды
plt.legend()
имеет два основных аргумента для определения положения легенды. Самым важным и само по себе достаточным является аргумент loc
.
Например. plt.legend(loc="upper left")
поместил легенду таким образом, чтобы она сидела в верхнем левом углу рамки. Если дальнейший аргумент не указан, это ограничивающее поле будет целыми осями.
Однако мы можем указать нашу собственную ограничительную рамку, используя аргумент bbox_to_anchor
. Если bbox_to_anchor
задан 2-кортеж, например. bbox_to_anchor=(1,1)
Это означает, что ограничивающий прямоугольник расположен в верхнем правом углу осей и не имеет степени. Затем он действует как точка, относительно которой легенда будет помещена в соответствии с аргументом loc
. Затем он будет расширяться из ограничивающего прямоугольника нулевого размера. Например. если loc
"upper left"
, верхний левый угол легенды находится в позиции (1,1), и легенда будет расширяться вправо и вниз.
Эта концепция используется для вышеупомянутого сюжета, который говорит нам потрясающую правду о предвзятости на выборах Мисс Вселенная.
import matplotlib.pyplot as plt
import matplotlib.patches
total = [100]
labels = ["Earth", "Mercury", "Venus", "Mars", "Jupiter", "Saturn",
"Uranus", "Neptune", "Pluto *"]
plt.title('Origin of Miss Universe since 1952')
plt.gca().axis("equal")
pie = plt.pie(total, startangle=90, colors=[plt.cm.Set3(0)],
wedgeprops = { 'linewidth': 2, "edgecolor" :"k" })
handles = []
for i, l in enumerate(labels):
handles.append(matplotlib.patches.Patch(color=plt.cm.Set3((i)/8.), label=l))
plt.legend(handles,labels, bbox_to_anchor=(0.85,1.025), loc="upper left")
plt.gcf().text(0.93,0.04,"* out of competition since 2006", ha="right")
plt.subplots_adjust(left=0.1, bottom=0.1, right=0.75)
Чтобы легенда не превышала цифру, мы используем plt.subplots_adjust
, чтобы получить больше пространства между краем фигуры и осью, которая затем может быть воспринята легендой.
Существует также возможность использовать 4-кортеж для bbox_to_anchor
. Как использовать или интерпретировать это подробно в этом вопросе: Что означает аргумент 4-элементного кортежа для 'bbox_to_anchor' в matplotlib?
и затем можно использовать аргумент mode="expand"
, чтобы легенда вписывалась в указанную ограничительную рамку.
Есть несколько полезных альтернатив этому подходу:
Использование координат фигуры
Вместо указания положения легенды в координатах осей можно использовать координаты фигуры. Преимущество заключается в том, что это позволит просто разместить легенду в одном углу рисунка, не изменяя большую часть остальной части. Для этого нужно использовать аргумент bbox_transform
и предоставить ему преобразование фигуры. Координаты, заданные bbox_to_anchor
, затем интерпретируются как координаты фигуры.
plt.legend(pie[0],labels, bbox_to_anchor=(1,0), loc="lower right",
bbox_transform=plt.gcf().transFigure)
Здесь (1,0)
- нижний правый угол фигуры. Из-за стандартных расстояний между осями и краем фигуры достаточно разместить легенду, чтобы она не перекрывалась с пирогом.
В других случаях, возможно, еще нужно будет адаптировать эти интервалы таким образом, чтобы не наблюдалось перекрытия, например.
title = plt.title('What slows down my computer')
title.set_ha("left")
plt.gca().axis("equal")
pie = plt.pie(total, startangle=0)
labels=["Trojans", "Viruses", "Too many open tabs", "The anti-virus software"]
plt.legend(pie[0],labels, bbox_to_anchor=(1,0.5), loc="center right", fontsize=10,
bbox_transform=plt.gcf().transFigure)
plt.subplots_adjust(left=0.0, bottom=0.1, right=0.45)
Сохранение файла с помощью bbox_inches="tight"
Теперь могут быть случаи, когда мы больше интересуемся сохраненной фигурой, чем тем, что показано на экране. Затем мы можем просто позиционировать легенду на краю фигуры, например,
но затем сохраните его с помощью bbox_inches="tight"
до savefig
,
plt.savefig("output.png", bbox_inches="tight")
Это создаст большую фигуру, которая сидит вокруг содержимого холста:
Представлен сложный подход, который позволяет разместить легенду плотно внутри фигуры, без изменения размера фигуры: Создание фигуры с точным размером и без дополнений (и легенда за пределами осей)
Использование подзаголовков
Альтернативой является использование подзаговоров для резервирования места для легенды. В этом случае одна подзапись может принимать круговую диаграмму, другой подзаговор содержит легенду. Это показано ниже.
fig = plt.figure(4, figsize=(3,3))
ax = fig.add_subplot(211)
total = [4,3,2,81]
labels = ["tough working conditions", "high risk of accident",
"harsh weather", "it not allowed to watch DVDs"]
ax.set_title('What people know about oil rigs')
ax.axis("equal")
pie = ax.pie(total, startangle=0)
ax2 = fig.add_subplot(212)
ax2.axis("off")
ax2.legend(pie[0],labels, loc="center")