Как я могу сделать так, чтобы легенда matplotlib охватывала области графика подграфиков?Python

Программы на Python
Ответить
Anonymous
 Как я могу сделать так, чтобы легенда matplotlib охватывала области графика подграфиков?

Сообщение Anonymous »

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

Вот что я пробовал / минимальный воспроизводимый пример то, что, как я ожидаю, должно работать, основано на документации:

Код: Выделить всё

import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(7, 4), layout="constrained")

# Plot some dummy data
x = [1, 2, 3, 4, 5]
y1 = [1, 2, 3, 4, 5]
y2 = [5, 4, 3, 2, 1]
axes[0].plot(x, y1, label="Line 1")
axes[1].plot(x, y1, label="Line 1")
axes[1].plot(x, y2, label="Line 2")

def find_ideal_bbox(axes):
# Use the box that spans the combined plot width (excluding figure side margins)
# Collect axes positions in figure coordinates
positions = [ax.get_position() for ax in axes]
if positions:
x0 = min(p.xmin for p in positions)
x1 = max(p.xmax for p in positions)
# Full vertical extent (0->1) so outside locations can align horizontally;
# width restricted to the subplot grid width.
return (x0, 0.0, x1 - x0, 1.0)
return None

# Collect all handles and labels from all axes
handles, labels = [], []
for ax in axes:
h, label_list = ax.get_legend_handles_labels()
for handle, label in zip(h, label_list):
if label not in labels:  # Avoid duplicates
handles.append(handle)
labels.append(label)

# Add one legend for both axes
fig.legend(
handles,
labels,
loc="outside upper center",
ncol=2,
bbox_to_anchor=find_ideal_bbox(axes),
mode="expand",
borderaxespad=-1,  # Move it outside the figure
columnspacing=1.0,  # Reduce space between columns (default is 2.0)
handletextpad=0.4,
# Reduce space between symbol and text (default is 0.8)
)

# Finally, save the figure in three different sizes
widths = [None, 3.16, 4.21]

# Make sure they have the same aspect ratio
original_size = fig.get_size_inches()
aspect_ratio = original_size[1] / original_size[0]
for w in widths:
if w is not None:
fig.set_size_inches(w, w * aspect_ratio)

# Reset the legend size
fig.legends[0].set_bbox_to_anchor(find_ideal_bbox(axes))

fig.savefig(
f"mvr_figure_{w}.png" if w is not None else "mvr_figure.png",
bbox_inches="tight",
)
Вот что это дает:
Изображение

Изображение

Изображение

Как видно из этих примеров, легенда во всех случаях слишком широкая и всегда немного смещена влево. Обратите внимание на макет="constrained". Без этого можно наблюдать обратное; легенда всегда слишком длинная справа.
Самое странное для меня то, что я могу отлаживать метод find_ideal_bbox, просто используя fig.text() для найденных координат, и текст размещается там, где я ожидаю.
Что мне не хватает? Почему легенды не используют bbox, о котором я им говорю?

Подробнее здесь: https://stackoverflow.com/questions/797 ... e-subplots
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»