Как уже обсуждалось в предыдущем посте из серии "ЛаТеХ для продвинутых", одним из самых универсальных средств для контроля над расположением картинок, таблиц и подписей к ним в пределах плавaющего объекта является пакет floatrow.
В предыдущей части
мы рассмотрели всевозможные способы
взаимного расположения картинки и подписи (снизу, сверху, сбоку),
выравнивания их по горизонтали и т.п.
Этот же пост будет посвящён
расположению нескольких объектов (рисунков, таблиц) в ряд.
Обратите внимание, что
имеется в виду именно расположение нескольких объектов
типа figure и/или table, а не нескольких картинок/таблиц (обычно
помеченных как а, б, в, ...) в пределах
одного объекта, как это делают пакеты subcaption
или subfig.
Все примеры из данного поста могут быть найдены
здесь
и
здесь
в виде tex-файлов готовых к компиляции. Документация к пакету
floatrow доступна на
русском и
английском языках.
Краткий анонс
Сначала мы познакомимся с командами
\ffigbox{}{} и \ttabbox{}{}, которые создают
бокс для картинки/таблицы и соответствующей подписи.
Затем будут освещены средства, необходимые для контроля над горизонтальным выравниванием:
- Окружение floatrow для расположения иллюстраций и таблиц в ряд.
- Длины FBwidth (ширина картинки) и Xhsize (ширина остатка страницы).
- Параметр floatrowsep, определяющий расстояние между картинками в ряду.
И, наконец, будут разобраны способы выравнивания объектов по вертикали, как то
- Команды
\TopFloatBoxes,\BottomFloatBoxes,\CenterFloatBoxes, выравнивающие весь float. - Параметры
heightadjustиvalignдля выравнивания только картинки/таблицы. - Выравнивание подписей.
Команда \ffigbox
Основной рабочей лошадкой во всех примерах ниже является команда
\ffigbox предоставляемая пакетом floatrow.
Её синтаксис прост:
Она определяет бокс, в который помещается картинка и подпись к ней, например01:\ffigbox[ширина][высота][вертикальное положение]{подпись}{картинка}
создаст обычный плавающий объект, как произошло бы и без использования01:\usepackage{floatrow}02:\usepackage{graphicx}03:...04:\begin{figure}[!h]05:\ffigbox{\caption{My Caption}\label{fig:ffb}}%06:{\includegraphics{roman_a}}07:\end{figure}
\ffigbox, с той единственной разницей, что благодаря
\ffigbox автоматически включается горизонтальное
выравнивание по центру.
Для таблиц определена аналогичная команда \ttabbox:
далее мы сосредоточимся на картинках, но всё без исключения применимо и
к таблицам.
Расположить несколько рисунков в ряд нам поможет окружение
floatrow:
01:\begin{figure}02:\begin{floatrow}03:\ffigbox{\caption{My Caption left}\label{...}}%04:{\includegraphics{...}}05:\ffigbox{\caption{My Caption right}\label{...}}%06:{\includegraphics{...}}07:\end{floatrow}08:\end{figure}
По умолчанию, страница просто поделена на две равные по ширине части, в каждую из которых вставлен рисунок и отцентрирован по горизонтали. Просто и незатейливо,... но не всегда достаточно, чтобы добиться идеального результата. Итак, за дело: в путь к идеалу!
Горизонтальное выравнивание
Волшебная длина \FBwidth
Предыдущий рисунок выглядит очень неуравновешенно, так как ширина отводящаяся на подпись не соответствует ширине картинки. Гораздо более симпатичного результата можно добиться вот так:
01:\usepackage{floatrow,graphicx,calc}02:% Создаёем новый разделитель03:\DeclareFloatSeparators{mysep}{\hspace{3cm}}04:...05:% Настраиваем значение разделителя для объектов06:\thisfloatsetup{floatrowsep=mysep}07:% А вот и сам плавающий объект08:\begin{figure}09:\begin{floatrow}10:\ffigbox[\FBwidth+1cm]{\caption{...}}%11:{\includegraphics{...}}12:\ffigbox[\FBwidth+1cm]{\caption{...}}%13:{\includegraphics{...}}14:\end{floatrow}15:\end{figure}
По порядку
- В строках 10 и 12 использован необязательный аргумент в
\ffigbox, который задаёт ширину плавающего объекта. В этом примере мы задаём ширину на 1см больше, чем ширина соответствующего изображения: т.е. подпись будет выдаваться на 0.5см с каждой стороны. Заметьте, что ширина самого изображения доступна через\FBwidth, a для того, чтобы можно было к ней прибавить 1см, надо загрузить пакетcalcв строке 1. -
Расстояние между двумя объектами (Figure 3 и Figure 4) задано в строке 6
с помощью параметра
floatrowsep. Обратите внимание, что нельзя просто написатьfloatrowsep=3cm, вместо этого надо определить новый разделитель (назовём егоmysep) в строке 3, а затем использовать вfloatrowsep=mysep. Пакет предопределяет следующие разделители:none,quad(=1em),qquad(=2em),columnsep(равен длине\columnsep, которую ЛаТеХ использует для разделения двух колонок текста).
Волшебная длина \Xhsize
Помимо очень полезной длины \FBwidth, пакет предопределяет
длину (точнее, ширину) \Xhsize,
равную оставшейся ширине
страницы. Эта длина может быть использована точно так же, как и
\FBwidth, в первом необязательном аргументе
\ffigbox.
Например, в случае, когда одна из подписей очень длинная, под неё может быть желательно выделить побольше места:
01:\begin{figure}02:\begin{floatrow}03:\ffigbox[\FBwidth+1cm]{\caption{My Caption left}}%04:{\includegraphics{...}}05:\ffigbox[\Xhsize]{\caption{My Caption right very .... very long}}%06:{\includegraphics{...}}07:\end{floatrow}08:\end{figure}
Несколько картинок в ряд
До сих пор мы рассматривали расположение только лишь двух
рисунков в ряд. Однако, ситуацию легко обобщить для произвольного
числа рисунков. Для этого небходимо задать необязательный аргумент
к окружению floatrow равным числу рисунков, как
проиллюстрированно в третьей строке нижеследующего примера.
01:\thisfloatsetup{floatrowsep=qquad}02:\begin{figure}03:\begin{floatrow}[3]% три рисунка в ряд!04:\ffigbox[\FBwidth+0.5cm]{\caption{...}}{\includegraphics{...}}05:\ffigbox[\Xhsize/3*2]{\caption{...}}{\includegraphics{...}}06:\ffigbox[\Xhsize]{\caption{...}}{\includegraphics{...}}07:\end{floatrow}08:\end{figure}
Из этого же примера очевидна гибкость использования \FBwidth
и \Xhsize: к ним можно прибавлять длины, их можно
умножать на скаляры. Кроме того, обратите внимание, что
параметр \Xhsize в строках 5 и 6 имеет разные значения:
он каждый раз означает ширину, оставшуюся на странице
на момент вызова \ffigbox!
Вертикальное выравнивание
Весь объект
До сих пор во всех примерах использовались картинки приблизительно одинаковой высоты, т.е. особой нужды в форматировании их вертикального положения не возникало. Если же рисунки отличаются по высоте, то встаёт вопрос об их вертикальном положении относительно друг друга.
Эта проблема решается с помощью одной из команд
\BottomFloatBoxes (выравнивание по низу),
\TopFloatBoxes (выравнивание по верху),
\CenterFloatBoxes (выравнивание по центру),
которая должна следовать сразу после \begin{figure}.
приводит к такому результату:01:\begin{figure}[!h]\TopFloatBoxes% or \BottomFloatBoxes or \CenterFloatBoxes02:\begin{floatrow}03:\ffigbox{...}{...}04:\ffigbox{...}{...}05:\end{floatrow}06:\end{figure}
Только картинки
В большинстве случаев, однако, необходимо выровнять только картинки, а подписи к ним оставить на одном уровне. Без проблем:
01:\begin{figure}[!h]02:\floatsetup{heightadjust=object,valign=c}03:\begin{floatrow}04:\ffigbox{\caption{...}}%05:{\includegraphics{...}}06:\ffigbox{\caption{...}}%07:{\includegraphics{...}}08:\end{floatrow}09:\end{figure}
Здесь использованы два параметра:
heightadjust: какие части float в ряду должны быть
одинаковой высоты. Соответственно, его значения
object: место, отводящееся под саму картинку, выполнить одинаковой высоты для всех картинок;caption: то же, но для места, отводящегося под подпись;all: первое и второе вместе;noobject,nocaption,none: отрицание, соответственно, первого, второго и третьего
floatrow инструктирован выделить под
обе картинке блоки одинаковой высоты.
valign: "тип" вертикального выравнивания. Может быть
t (по верху), b (по низу), c (по центру).
Подписи
Для рисунков, когда подписи размещены под иллюстрацией, нет необходимости их дополнительно "выравнивать": подписи и так выровнены "по верху". Однако у таблиц, когда подписи размещены сверху, так как использована директива
или, что то же самое,01:\floatsetup[table]{style=plaintop}
то подписи автоматически оказываются вырoвненными "по низу", вот так:01:\floatsetup[table]{capposition=top}
Чтобы вырoвнять их "по верху" используем
или же01:\floatsetup[table]{style=Plaintop}
01:\floatsetup[table]{capposition=TOP}
Полностью код примера выше: открыть
01:% используем стиль, в котором подписи таблиц02:% сверху и выравнены "по верху"03:\floatsetup[table]{style=Plaintop,floatrowsep=qquad}04:%05:% Теперь сами таблицы в ряд06:\begin{table}[!h]07:\begin{floatrow}08:% первая таблица09:\ttabbox[\FBwidth]{\caption{My Caption left}}%10:{\begin{tabular}{c|cc}11:Column 1 & Column 2 & Column 3\\\hline12:a & b & c\\13:a & b & c\\14:a & b & c\\15:a & b & c\\16:a & b & c17:\end{tabular}18:}19:% вторая таблица20:\ttabbox[\FBwidth]{\caption{My Caption right, let us21:make it somewhat longer}}%22:{\begin{tabular}{c|cc}23:Column 1 & Column 2 & Column 3\\24:\hline25:a & b & c\\26:a & b & c\\27:a & b & c28:\end{tabular}29:}30:\end{floatrow}31:\end{table}
Картинка рядом с таблицей
Все трюки, приведённые выше, обсуждались на примере или картинок, или таблиц. Если картинка и таблица должны находиться рядом, нужно воспользоваться командой\killfloatstyle.
Например
произведёт следующий результат01:\begin{figure}[!h]\CenterFloatBoxes02:\begin{floatrow}03:\ffigbox[...]{\caption{...}}{...}04:%05:\killfloatstyle06:%07:\ttabbox[...]{\caption{...}}{...}08:\end{floatrow}09:\end{figure}
И всё-таки subfloats
Хотя во введении и было обещано не рассматривать вопросы,
связанные с расположением "подрисунков" (subfigures, subtables),
стоит отметить, что все вышеприведённые рецепты действуют и в их случае
с той лишь разницей, что надо использовать окружение
subfloatrow вместо floatrow.
Простой пример ниже демонстрирует это в деталях
Пара пунктов, на которые стоит обратить внимание:01:\usepackage{subcaption,floatrow,graphicx,calc}02:\floatsetup{floatrowsep=qquad}03:...04:\begin{figure}[!h]05:\ffigbox{06:% объявляем, что будут 3 картинки в ряд07:\begin{subfloatrow}[3]08:\ffigbox[\FBwidth+1cm]{\caption{My Caption left}}{\includegraphics{...}}09:\ffigbox[\FBwidth+1cm]{\caption{My Caption mid...}}{\includegraphics{...}}10:\ffigbox[\FBwidth+1cm]{\caption{My Caption right...}}{\includegraphics{...}}11:\end{subfloatrow}12:}13:{% подпись ко всему float14:\caption{Overall caption.}15:}16:\end{figure}
- надо загрузить дополнительно пакет
subcaption; - вместо окружения
floatrowиспользуемsubfloatrow; - причём помещаем его внутрь первого аргумента
\ffigbox(строка 5); - а во втором аргументе
\ffigboxпомещаем подпись ко всему ряду рисунков (строка 14).
Абсолютно аналогично можно это применить и к таблицам,
заменив \ffigbox на \ttabbox
Заключительный сложный пример для любознательных
Помимо рассмотренных выше трюков, floatrow позволяет
создавать собственные типы float. Кроме того, пакет иеально функционирует
в тандеме с другим пакетом caption, который позволяет
должным образом оформить подпись.
В следующем примере использованны эти возможности:
- Определен новый тип float под названием Photo (с собственным счётчиком и другими атрибутами), подпись которого набирается справа от картинки.
- Для таблиц и др. объектов, подпись отфoрмaтирована специальным образом.
01:\usepackage{caption,floatrow}02:%------------------------------------------------03:% Форматируем подписи к таблицам, благодаря пакету caption04:\DeclareCaptionLabelFormat{rightline}{\rightline{\bothIfFirst{#1}{ }#2}}05:% метка Table справа, затем новая строка, метка наклонным, сама подпись жирным малым шрифтом06:\captionsetup[table]{labelformat=rightline,labelsep=newline,%07:labelfont={md,sl},textfont={bf,small}}08:% Подпись размещаем вверху от таблицы09:\floatsetup[table]{style=Plaintop}10:%-------------------------------------------------11:% Создаём новый тип float: photo12:% Команда \DeclareNewFloatType{тип}{опции} из пакета floatrow13:\DeclareNewFloatType{photo}{name={Photo},placement=tbp}14:% Определяем аналог \ffigbox для photo15:% с помощью \newfloatcommand{команда}{тип}[преамбула][ширина]16:\newfloatcommand{photobox}{photo}%17:[{\capbeside18:\thisfloatsetup{capbesideposition={right,bottom},% подпись справа внизу19:capbesidewidth=3cm}% ширина подписи 3см20:}]%21:[\FBwidth]22:% форматируем подпись с помощью пакета caption23:\captionsetup[photo]{labelformat=rightline,labelsep=newline,%24:labelfont={md,sl},textfont={bf,small}}%25:%--------------------------------------------------26:% для обычного "Figure"27:\floatsetup[figure]{capposition=bottom}28:\captionsetup[figure]{labelfont={md,sl},textfont={bf,small}}%29:%---------------------------------------------------30:...31:\begin{table}[!h]\CenterFloatBoxes32:\begin{floatrow}33:\ttabbox[\FBwidth]{\caption{My Caption left}\label{tab:1}}%34:{\begin{tabular}{c|c}35:...36:\end{tabular}37:}38:%39:\killfloatstyle40:%41:\photobox{\caption{Here goes a photo}\label{ph:1}}{\includegraphics{...}}42:\end{floatrow}43:\end{table}44:45:See Table~\ref{tab:1} and Photo~\ref{ph:1}. Also a ``normal'' Figure~\ref{fig:1}.46:47:\begin{figure}[!h]48:\ffigbox{\caption{Graph of a function}\label{fig:1}}{\includegraphics{...}}49:\end{figure}
Подведение итогов
Пакет floatrow позволяет не только автоматизировать
процесс расположения подписи
(сверху, снизу, сбоку от картинки), но и предоставляет
мощные средства для контроля над расположением объектов в ряд.
Предоставляемый им интерфейс облегчает форматирование визуального
материала и позволяет добиться желаемого результата без
больших затрат времени и сложных комбинаций с minipages.
Все примеры из данного поста могут быть найдены
здесь
и
здесь
в виде tex-файлов готовых к компиляции.
Документация к пакету
floatrow доступна на
русском и
английском языках.












3 комментариев: |высказаться!| RSS-лента дискуссии.|
Пост выглядит круто, аж все Анонимусы разбежались и попрятались в страхе :-)
Я тут дизайню титульную страницу, и там надо разместить несколько рисунков в ряд. Поэтому у меня вопрос к тов. Amorua: есть ли у пакета floatrow какие-то конфликты с другими пакетами? У меня просто много пакетов включено.
@virens
Если на титульной странице надо разместить много странного, не проще организовать какой-либо управляемый контейнер, да хоть окружение picture, и там уже располагать необходимые объекты с точностью до ангстрема?
@virens комментирует...
Поэтому у меня вопрос к тов. Amorua: есть ли у пакета floatrow какие-то конфликты с другими пакетами?
Вроде, никаких конфликтов. floatrow замещает собой всю функциональность пакета float (включая наиболее используемую фичу [H])
Соглашусь с тов. Const, что при хитром размещении картинок на титульном листе, может оказаться проще использовать точное позиционирование, например, посредством tikz: что-то вроде
\begin{tikzpicture}
\node at (0,0){\includegraphics{картинка}};
\node at (1,0){\includegraphics{картинка}};
\end{tikzpicture}
Отправить комментарий
Подписаться на RSS-ленту комментариев к этому посту.