Pad_inches = 0 и bbox_inches = "tight" делает график меньшим, чем объявленный figsize

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

import matplotlib.pyplot as plt
from matplotlib import rc, rcParams
from numpy import sin

rc('text', usetex=True)
rc('font', family='serif', serif='Computer Modern Roman', size=8)
rc('legend', fontsize=10)

width_in = 5
fig = plt.figure(1, figsize=(width_in, 2))
ax = fig.add_subplot(111)
ax.plot(range(0,100), sin(range(0,100)))

fig.tight_layout()
fig.savefig('test.eps', bbox_inches='tight', pad_inches=0)
plt.close()

Проблема связана с bbox_inches = 'tight' и pad_inches = 0. Добавление этих опций делает мой участок размером 4,76 дюйма вместо объявленных 5 дюймов. Но я хочу, чтобы они сэкономили место. Итак, как его решить?

Изменить: Ну, ответы предлагают удалить bbox_inches='tight' и pad_inches=0 и использовать только tight_layout(). Тогда изображения имеют нужный размер, однако у него все еще есть белые прокладки вокруг. Я могу удалить его с помощью fig.tight_layout(pad=0), но затем название фигуры переместилось внутри поля, что выглядит уродливым. С другой стороны, я могу использовать tight_layout(rect=[...]) и получить желаемый результат, но это ручная работа, чтобы получить правильные цифры - мне это не нравится. Таким образом, в настоящее время я не вижу легкого и общего решения моей проблемы.

Ответ 1

Проблема, с которой вы сталкиваетесь, заключается в том, что bbox_inches='tight' просто удаляет все лишнее свободное пространство вокруг вашей фигуры, оно фактически не перестраивает что-либо на вашей фигуре после его рендеринга.

Вам может потребоваться настроить параметры, которые вы передаете tight_layout (учебник), чтобы получить желаемый эффект.

Надеюсь, это заставит вас указывать в правильном направлении.

Ответ 2

В исходном сюжете должен быть пробел, иначе bbox_inches = tight не удалит ни одну из областей. Есть два решения для этого, о которых я знаю:

  • Простым методом является использование tight_layout, как указано tcaswell.

  • Более сложный, но более управляемый метод заключается в том, чтобы избежать использования fig.add_subplot(111) и вместо этого использовать fig.add_axes(), который позволяет вам быть более строгим с точки зрения того, насколько велики ваши оси, когда вы определяете экземпляр осей. Затем вы можете настроить размер ваших осей, чтобы занимать столько площади фигуры, сколько требуется для поддержания 5-дюймовой области фигуры. После того, как вы это сделаете, я бы рекомендовал просто не использовать bbox_inches или установить его на None ( по умолчанию), чтобы избежать непроизвольного обрезки. fig.add_axes() требует в качестве первого аргумента параметра rect, который состоит из [left_position, bottom_position, width, height], каждый из которых находится в диапазоне от 0 до 1.

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

Ответ 3

У меня та же проблема, что и matplotlib для LaTeX. Поскольку мои сюжеты не разрешали использовать tight_layout, давая этот предупреждение, я закончил использование fig.subplots_adjust(bottom=bottom_pos, top=top_pos, left=left_pos, right=right_pos). См. Этот учебник. Это требует ручного поиска наилучших значений для bottom_pos и т.д., Но в моем случае это единственная возможность получить изображения без большого пробела, не изменяя размер фигуры вывода.