[Tex/LaTex] Full-page landscape figure in middle of document

floatslandscapepdftex

I have a full-page figure that needs to be rotated to fit on the page. I started out with this figure in an appendix at the end of my document, and just wrapped the figure in \begin{landscape}...\end{landscape} (from the pdflscape package; I'm using pdflatex) and I was pretty happy with the results. However, I've decided the figure needs to be in the middle of the document, and I'm having trouble reproducing the results there.

The best I've come up with so far is to use the sidewaysfigure environment from the rotating package:

\documentclass{article}
\usepackage{blindtext}

\usepackage{pdflscape}
\usepackage{rotating}

\begin{document}
\blindtext[3]

\begin{sidewaysfigure}
\caption{This figure and its caption are sideways.  Ideally I would also like the pdf page containing it to be rotated so that the figure is upright for on-screen viewing.}
\end{sidewaysfigure}

\blindtext[3]

\begin{figure}
\caption{this figure should be numbered after the other one, come after it in the document, and be oriented normally.}
\end{figure}

\blindtext[2]
\end{document}

This works pretty well, except that I really liked the feature of pdflscape where the PDF page is rotated so that the figure contents and caption are oriented optimally for on-screen viewing, which seems to be missing when using the rotating package.

Things I've tried:

  • using the landscape environment anyway. This gives an immediate page break at the point in the source where the figure occurs.
  • using the landscape environment in an \afterpage{}. This sorta works, except that it's actually moving the figure around, the numbering gets switched with the subsequent figure, which is undesirable.
  • I didn't actually try it, but this solution involving fancyhdr won't work because there are going to be other figure pages (in fact, it's currently looking like this landscape figure is going to be immediately followed by a figure page)
  • I was even desperate and tried using the internal commands (\PLS@AddRotate{90}) that pdflscape uses, but they apply immediately, so the wrong page gets wrotated.

The output from sidewaysfigure is good enough to be getting on with (I think I'm falling into this trap!), but if there are any ways to fix this, I'd very much appreciate it!

This question ends up being very similar to this other one by another user which never received an answer due to not having enough details.

Best Answer

This combines sidwaysfigure and pdflscape into one environment. It uses the aux file to locate where the figure actually winds up.

\documentclass{article}
\usepackage{blindtext}% MWE only
\usepackage{graphicx}% for \rotatebox
\usepackage{everypage}
\usepackage{environ}
\usepackage{pdflscape}% not required

\newcounter{abspage}% \thepage not reliab

\makeatletter
\newcommand{\newSFPage}[1]% #1 = \theabspage
  {\global\expandafter\let\csname SFPage@#1\endcsname\null}

\NewEnviron{SidewaysFigure}{\begin{figure}[p]
\protected@write\@auxout{\let\theabspage=\relax}% delays expansion until shipout
  {\string\newSFPage{\theabspage}}%
\ifdim\textwidth=\textheight
  \rotatebox{90}{\parbox[c][\textwidth][c]{\linewidth}{\BODY}}%
\else
  \rotatebox{90}{\parbox[c][\textwidth][c]{\textheight}{\BODY}}%
\fi
\end{figure}}

\AddEverypageHook{% check if sideways figure on this page
  \ifdim\textwidth=\textheight
    \stepcounter{abspage}% already in landscape
  \else
    \@ifundefined{SFPage@\theabspage}{}{\global\pdfpageattr{/Rotate 0}}%
    \stepcounter{abspage}%
    \@ifundefined{SFPage@\theabspage}{}{\global\pdfpageattr{/Rotate 90}}%
  \fi}
\makeatother

\begin{document}
\blindtext[3]

\begin{SidewaysFigure}
\caption{This figure and its caption are sideways.  
Ideally I would also like the pdf page containing it to be rotated so that the figure is upright for on-screen viewing.}
\end{SidewaysFigure}

%\begin{landscape}

\blindtext[3]

\begin{figure}
\caption{this figure should be numbered after the other one, come after it in the document, and be oriented normally.}
\end{figure}

\blindtext[4]
%\end{landscape}
\end{document}