Как установитьлоту_открытия для графиков matplotlib после show()
Моя настройка:
Debian Linux 8.3 amd64, XMonad WM, python2.7, matplotlib 1.5.1
Проблема:
Я делаю сюжет, например:
import matplotlib.pyplot as plt
x = xrange(10)
y1 = [i ** 2 for i in x]
y2 = [1.0 / (i + 1) for i in x]
fig = plt.figure()
ax1 = plt.subplot(1, 2, 1)
ax1.plot(x, y1)
ax2 = plt.subplot(1, 2, 2)
ax2.plot(x, y2)
plt.show()
и так как я использую оконный менеджер тайлинга, окно matplotlib растягивается до тайла. К сожалению, это делает графики маленькими и несколько рыхлыми.
Если я хочу немного "затянуть" его, щелкнув "Настроить субплоты->Tight Layout", я сделаю это. Но это означает, что мне приходится каждый раз нажимать на значок, а затем на кнопку, и, поскольку я использую этот график для отображения данных тестирования и запуска его очень часто, это довольно раздражает. Поэтому я попробовал несколько вещей, чтобы сделать это проще:
Что я пробовал:
призвание
plt.tight_layout()
доshow()
:... ax2.plot(x, y2) plt.tight_layout() plt.show()
добавление обработчика нажатия клавиш (так что я бы просто нажал "t"):
... ax2.plot(x, y2) def kbd_handler(event): if event.key == 't': plt.tight_layout() plt.gcf().canvas.mpl_connect('key_press_event', kbd_handler) plt.show()
призвание
tight_layout
на рисунке:ax2.plot(x, y2) fig.tight_layout() plt.show()
Все это ничего не изменило или, по крайней мере, выглядело одинаково для 2-х сюжетов в одном ряду, однако для более чем одного ряда это сделало макет еще более свободным, а все субплоты чрезвычайно маленькими.
Что я подозреваю:
Я полагаю, что проблема связана с изменением размера, которое, вероятно, происходит после создания окна, поэтому tighten_layout
работает с оригинальными размерами окна. Когда Window Manager изменяет размеры окна, макет сохраняет размеры подзаговоров, и у меня получается "свободный" макет с миниатюрными графиками.
Вопрос
Есть ли способ автоматически (или очень легко - как с помощью key_press_event)сжать макет, даже если размер окна изменяется сразу после вызова plt.show()
?
1 ответ
Вы можете достичь желаемого с помощью обработки событий Matplotlib. Просто напишите небольшую функцию, которая вызывает tight_layout
и обновляет фигуру каждый раз, когда фигура изменяется:
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(0,np.pi,100)
y1 = np.sin(x)
y2 = np.cos(x)
fig, (ax1,ax2) = plt.subplots(nrows=1, ncols=2)
fig.tight_layout()
ax1.plot(x,y1)
ax2.plot(x,y2)
def on_resize(event):
fig.tight_layout()
fig.canvas.draw()
cid = fig.canvas.mpl_connect('resize_event', on_resize)
plt.show()
Конечно, есть небольшая вероятность того, что это зависит от системы или версии. Я проверил приведенный выше пример на MacOS Sierra с Python 3.5.4 (Matplotlib 2.0.2) и с Python 2.7.14 (Matplotlib 2.1.0). Надеюсь это поможет.
РЕДАКТИРОВАТЬ:
На самом деле, я думаю, что ваш обработчик нажатия клавиш сработал бы, если бы вы обновили значение после tight_layout
т.е. если бы вы позвонили fig.canvas.draw()
,