Matplotlib Legend Высота в пикселях - PullRequest
4 голосов
/ 16 февраля 2011

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

это возвращает 1.

height = legend.get_frame().get_bbox_to_anchor().height

это возвращает [0,0], [1., 1.]

box = legend.get_window_extent().get_points()

это также возвращает [0,0], [1., 1.]

box = legend.get_frame().get_bbox().get_points()

все они возвращают 1, даже если размер легенды изменяется! что происходит?

1 Ответ

4 голосов
/ 16 февраля 2011

Это потому, что вы еще не нарисовали холст.

Значения пикселей просто не существуют в matplotlib (точнее, они существуют, не имеют отношения к экрану или другому выводу) до холстаРисуется.

Для этого есть несколько причин, но сейчас я их пропущу.Достаточно сказать, что matplotlib старается оставаться как можно более общим и, как правило, избегает работы со значениями пикселей до тех пор, пока все не будет нарисовано.

В качестве простого примера:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10), label='Test')
legend = ax.legend(loc='upper left')

print 'Height of legend before canvas is drawn:'
print legend.get_window_extent().height

fig.canvas.draw()

print 'Height of legend after canvas is drawn:'
print legend.get_window_extent().height

Однакобудет отображать высоту легенды в пикселях только так, как она нарисована на экране !Если вы сохраните рисунок, он будет сохранен с другим разрешением (100, по умолчанию), чем на экране, поэтому размер элементов в пикселях будет другим.

Существует два способаэто:

  1. Быстро и грязно: нарисуйте холст фигуры перед выводом значений пикселей и обязательно укажите dpi фигуры при сохранении (например, fig.savefig('temp.png', dpi=fig.dpi).

  2. Рекомендуется, но немного сложнее: подключите обратный вызов к событию рисования и работайте со значениями пикселей только при рисовании фигуры. Это позволяет работать со значениями пикселей при рисовании фигуры только один раз.

В качестве быстрого примера последнего метода:

import matplotlib.pyplot as plt

def on_draw(event):
    fig = event.canvas.figure
    ax = fig.axes[0] # I'm assuming only one subplot here!!
    legend = ax.legend_ 
    print legend.get_window_extent().height

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10), label='Test')
legend = ax.legend(loc='upper left')

fig.canvas.mpl_connect('draw_event', on_draw)

fig.savefig('temp.png')

Обратите внимание на различия в том, что напечатано как высота легенды для первого и второго примеров. (31.0для второго по сравнению с 24,8 для первого в моей системе, но это будет зависеть от значений по умолчанию в в вашем файле .matplotlibrc )

Разница обусловлена ​​различиемt dpi между значением по умолчанию fig.dpi (80 точек на дюйм, по умолчанию) и разрешением по умолчанию при сохранении рисунка (100 точек на дюйм, по умолчанию).

Надеюсь, в любом случае это имеет смысл.

...