2

I often find myself changing the size of figures or removing vertical space between elements (e.g., a paragraph and figure) with \vspace{} to fit certain the contents into one page. This is rather time-consuming and repetitive. Is it possible to automate this process in LaTeX? Let say that figure resizing should take priority over introducing \vspace{} (lets say between a paragraph and a figure), but the figure should have a minimum size.

Here are some applications for what I am requesting:

  • Creating posters using the multicol package, where I often have to make the above adjustments to fit contents into a specific column (and ultimately the all content into one page)

  • A report where each chapter is limited to one page.

Consider the trivial example below, the content could be fit into one page by reducing figure size to 11 cm. However, it would be preferable to set a minimum figure size and expand to fill the page.

\documentclass{article}
\usepackage{float}
\usepackage{graphicx}
\usepackage{lipsum}

\begin{document}
\lipsum[2-4]
\begin{figure}[H]
\includegraphics[width=13cm]{example-image-a}
\end{figure}
\end{document}

Let me state the algorithm I perform manually in a more formal way, and the core of my question is if this can be implemented in Latex:

  1. Does figure fit in target page?
    • no -> If size is above minimum, reduce size -> back to 1
    • yes -> Does page contain white-space?
      • yes -> fill by increasing figure size -> back to 1
      • no -> done

Is there a way in LaTex to ask the question: is the figure in the desired page? And then iteratively adjust size until conditions are met?

  • 1
    can you give more information about how you intend it to work, preferably with a test document. normally (with automatic page breaks) just enough space to take the figure is left, so no rescaling or vspace should be needed, But from your title perhaps you have a one page document like a poster, but then there should be no floating figures at all?? – David Carlisle Aug 28 at 15:48
  • I added more context to the question. Perhaps I used the term float incorrectly, but I was referring to both tables and figures which I often want to place in a specific location using \begin{figure}[H]. – jsb Aug 28 at 16:38
  • H prevents the figure floating, so it is no longer a float really. then you have the forced page break at the end of the document, arr you only interested in forced float placement and forced page breaks? and even here, it is hard to scale the figure to fill out vertical space as it is a landscape image so constrained by the page width Note the whole reason for figures floating is to avoid ugly white space. By using H you disable that and so by default get white space unless you do manual corrections, – David Carlisle Aug 28 at 21:02
  • For complete control where things go, check out the flowfram package. – John Kormylo Aug 28 at 21:49
  • I added further clarifications at the bottom of the question. My goal is to avoid ugly white space by resizing the figure, on top of that I would like to constraint the figure to appear in a given page. – jsb Aug 28 at 23:18
4

This solution uses all the remaining space on the page. It does not honor the aspect ratio. Captions are allowed, but will also be scaled.

Don't forget to run it twice.

\documentclass{article}
\usepackage{tikzpagenodes}
\usepackage{graphicx}
\usepackage{lipsum}

\newlength{\cramht}

\makeatletter% for \@captyoe
\newcommand{\crammit}[1]% #1 = image or minipage
{\bgroup
  \par\vskip\textfloatsep% normal float separation
  \def\@captype{figure}% allow captions
  \noindent\begin{tikzpicture}[overlay, remember picture]
    \pgfextracty{\cramht}{\pgfpointdiff{\pgfpointanchor{current page text area}{south}}{\pgfpointorigin}}%
    \advance\cramht by \ht\strutbox
    \node[above, inner sep=0pt] at (current page text area.south) {\resizebox{\textwidth}{\cramht}{#1}};
  \end{tikzpicture}\newpage
\egroup}
\makeatletter

\begin{document}
\lipsum[2-4]
\crammit{\includegraphics{example-image-a}}
\end{document}

This version has an optional caption which will not be scaled.

\documentclass{article}
\usepackage{tikzpagenodes}
\usepackage{graphicx}
\usepackage{lipsum}

\newlength{\cramht}
\newsavebox{\crambox}

\makeatletter
\newcommand{\crammit}[2][\empty]% #1 = caption (optional), #2 = image\
{\bgroup
  \par\vskip\textfloatsep% normal float separation
  \def\@captype{figure}% allow captions
  \ifx\empty#1\relax
    \setbox\crambox=\copy\voidb@x
  \else
    \setbox\crambox=\vbox{\caption{#1}}%
  \fi
  \noindent\strut\begin{tikzpicture}[overlay, remember picture]
    \pgfextracty{\cramht}{\pgfpointdiff{\pgfpointanchor{current page text area}{south}}{\pgfpointorigin}}%
    \advance\cramht by \ht\strutbox
    \advance\cramht by -\ht\crambox
    \node[above, inner sep=0pt, yshift=\ht\crambox] at (current page text area.south) {\resizebox{\textwidth}{\cramht}{#2}};
  \end{tikzpicture}\par
  \ifvoid\crambox\else\vfill\noindent\usebox\crambox\fi
  \newpage
\egroup}
\makeatletter

\begin{document}
\lipsum[2-4]
\crammit[test caption]{\includegraphics{example-image-a}}
\end{document}
  • Looks promising! I will test it thoroughly. Can it also be applied to tables? (worst case scenario the table can be rendered as an image separately) – jsb Aug 30 at 21:13
  • Yes, but you will have to define \@captype to be table. Or you could use \captionof{table}{...}. – John Kormylo Aug 30 at 21:16
  • Thanks. Also, it would be great if you don't mind explaining how it works or providing a reference that explains the basics needed to understand it. – jsb Aug 30 at 21:18
  • In an overlay tikzpicture, the origin in located on the baseline where the tikzpicture (equivalent to \hbox{}) is inserted. \pgfextracty etc. is used to compute the distance from the origin to the bottom of the text area. \ht\strutbox is the distance from the baseline to the top of the line. The \newpage uses up the remaining space on the page. – John Kormylo Aug 31 at 13:27
1

Placing floats at a fixed position (and not let them, well, float) requires manual intervention, no way around it.

(La)TeX usually does an excellent job handling floats, just letting it do it's job without meddling is usually enough.

If you want to create e.g. a poster or some such fixed layout document, it can be done in LaTeX (search for "latex poster", see if one of the alternatives does what you want), or consider using a package like inkscape.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.