Чтение высоты легенды в Python

#python #matplotlib

#python #matplotlib

Вопрос:

У меня есть несколько графиков с большим количеством информации и строк, поэтому иногда я склонен помещать легенду за пределы самого графика using bbox_to_anchor . Я также предпочитаю иметь заголовок сюжета, но в этом случае он будет позиционно совпадать с легендой. Приведенный ниже пример является лишь иллюстрацией проблемы.

 import numpy as np
import matplotlib.pyplot as plt

t = np.arange(0.0, 2.0, 0.01)
s = 1   np.sin(2 * np.pi * t)
r = 1   np.sin(4 * np.pi * t)
q = 1   np.sin(6 * np.pi * t)

fig, ax = plt.subplots()
ax.plot(t, s, label='S')
ax.plot(t, r, label='R')
ax.plot(t, q, label='Q')
leg = ax.legend(loc=3, ncol=3, bbox_to_anchor=(.0, 1.02, 1., .102), borderaxespad=0., mode='expand')
ax.set_title('SIMPLE PLOT', y=1.1)
plt.show()
  

Чтобы избежать этого, я устанавливаю какое-то значение y (например, y=1.1 ). Я хотел бы автоматизировать этот процесс, потому что я продолжаю обновлять один и тот же график новыми данными, поэтому размер легенды увеличивается, и мне нужно соответствующим образом отрегулировать положение заголовка.

  • Есть ли способ автоматизировать этот процесс?
  • Есть ли в Python функция, способная считывать высоту легенды, чтобы это можно было использовать для настройки положения заголовка?

Ответ №1:

Высота легенды определяется во время рисования. Вы можете получить это после рисования фигуры через legend.get_window_extent() . Результирующая ограничивающая рамка указана в единицах пикселей. Для того, чтобы найти смещение заголовка, вам нужно будет вычесть верхний предел легенды из верхнего предела осей. Итак, вам также нужно получить положение осей в пикселях.

Заголовок может быть смещен либо в координатах рисунка ( y=1.1 ), либо в точках ( pad=20 ). Я бы предложил использовать точки здесь, чтобы сделать это независимым от размера осей. Таким образом, вы можете вычислить разницу в верхних позициях, преобразовать из пикселей в точки (т. Е. distance [pixels] * ppi / dpi ) и добавить некоторое постоянное смещение в точках (потому что обычно вы не хотели бы, чтобы заголовок располагался точно на границе легенды). Затем используйте это число как pad .

 import numpy as np
import matplotlib.pyplot as plt


fig, ax = plt.subplots(constrained_layout=True)

ax.plot([1,2,3], np.random.rand(3,5), label='Label')

leg = ax.legend(loc="lower center", ncol=3, bbox_to_anchor=(.0, 1.02, 1., 1.02),
                borderaxespad=0, mode='expand')

fig.canvas.draw()
leg_box = leg.get_window_extent()
ax_box = ax.get_position().transformed(fig.transFigure)
pad = (leg_box.y1 - ax_box.y1)*72./fig.dpi   6
ax.set_title('SIMPLE PLOT', pad=pad)

plt.show()
  

введите описание изображения здесь

Обратите внимание, что здесь я также использовал constrained_layout , чтобы заголовок не обрезался границами рисунка.

Комментарии:

1. Спасибо, @ImportanceOfBeingErnest — это было на самом деле то, что я имел в виду!