2

This question follow up from other solutions (like this one) that solve the problem of automatically sizing, given a total width, two side by side images (different in size and aspect ratio, which may have a single caption or one caption each) in a figure environment, so that they have the same height. I would like to do the same with the only difference that the two images should have the same area instead of the same height.

In fact, placing side by side two images of same height having very different aspect ratio gives often unsatisfactory results, whereas, if they have the same area, the appearance is aesthetically much more pleasant.

Here is a MWE of the starting code (same height images):

\documentclass{article}
\usepackage{mwe}
\usepackage{xcolor}
\usepackage{floatrow}
\usepackage{subcaption}

% 2 side by side images with a single caption
% arguments: image 1, image 2, caption, width (as ratio of textwidth)
\newcommand{\figureonepp}[4]{%based on Figure 103 at pag. 100 of floatrow manual
\begin{figure*}[htbp]%
\ffigbox[#4\textwidth]{}{\CommonHeightRow{\begin{subfloatrow}[2]% this comment needed, otherwise an unprotected space shifts slightly the figure to the right
\ffigbox[\FBwidth]{\includegraphics[height=\CommonHeight]{#1}}{}
\ffigbox[\FBwidth]{\includegraphics[height=\CommonHeight]{#2}}{}
\end{subfloatrow}}
\caption{#3}}
\end{figure*}}

% define allowable width used by floatrow package
% usage example (put at beginning of figure, before any floatrow command): \ThisWidth{0.8\textwidth}
\makeatletter
\def\ThisWidth#1{%
  \@tempdima\dimexpr(\textwidth-#1)/2\relax
  \edef\FRleftmargin{\noexpand\hspace*{\the\@tempdima}}%
  \edef\FRrightmargin{\noexpand\hspace*{\the\@tempdima}}%
  \ignorespaces}
\makeatother

% two side by side images each one with a caption
% arguments: image 1, image 2, caption 1, caption 2, width (as ratio of textwidth)
\newcommand{\figuretwopp}[5]{%
\begin{figure*}
\ThisWidth{#5\textwidth}
\CommonHeightRow{\begin{floatrow}
\ffigbox[\FBwidth]{\includegraphics[height=\CommonHeight]{#1}}{\caption{#3}}
\ffigbox[\FBwidth]{\includegraphics[height=\CommonHeight]{#2}}{\caption{#4}}
\end{floatrow}}
\end{figure*}}

\begin{document}
\pagecolor{yellow!10}
\blindtext
\figureonepp{example-image-10x16}{example-image-16x10}{This is the figure caption.}{0.8}
% uncomment the following line to show the two captions case
%\figuretwopp{example-image-10x16}{example-image-16x10}{Left caption.}{Right caption.}{0.8}
\blindtext
\end{document}

The above code produces the page on the left (same height images), while the desired result (same area images) is shown on the right:

enter image description here

I guess that the solution should implement some kind of \CommonAreaRow macro to be used in place of \CommonHeight.

Although the question is different, the code in this answer may be of some help.

Thanks in advance for any help.

0
4

This computes the scaling factors. The distance between the floats is given by \columnsep.

\documentclass{article}
\usepackage{mwe}
\usepackage{xcolor}
\usepackage{floatrow}
\usepackage{subcaption}
\usepackage{xfp}


\newcommand{\figuretwoareaeq}[5]{%
\setbox0\hbox{\includegraphics{#1}}%
\setbox1\hbox{\includegraphics{#2}}%
\edef\tmpx{\fpeval{(#4*\textwidth-\columnsep)/(\wd0*(1+sqrt(\wd1*\ht0)/sqrt(\wd0*\ht1)))}}%
\edef\tmpy{\fpeval{\tmpx*sqrt(\wd0*\ht0/(\wd1*\ht1))}}%\typeout{\tmpx,\tmpy}%
\begin{figure*}[htbp]%
\ffigbox[#4\textwidth]%
{\begin{subfloatrow}\CenterFloatBoxes% this comment needed, otherwise an unprotected space shifts slightly the figure to the right
\ffigbox[\FBwidth]{\includegraphics[scale=\tmpx]{#1}}{\caption{#3}}%
\ffigbox[\FBwidth]{\includegraphics[scale=\tmpy]{#2}}{\caption{#4}}%
\end{subfloatrow}}{\caption{#3}}
\end{figure*}}

\begin{document}
\pagecolor{yellow!10}
Call the widths and heights of the original graphics $w_i$ and $h_i$,
respectively with $i\in\{0,1\}$. We would like to scale them with scaling
factors $x$ and $y$, respectively, such that the areas are equal,
\[ (x\,w_0)\,(x\,h_0)=(y\,w_1)\,(y\,h_1)\;.\] 
This means that 
\[ y=x\,\sqrt{\frac{w_0\,h_0}{w_1\,h_1}}\;.\] 
We demand that, up to the \verb|\columnsep| $d$, the sum of rescaled widths equals
some target width $\ell$, i.e.\
\[x\,w_0+y\,w_1=\ell-d\;.\]
Thus 
\[ x=\frac{\ell-d}{w_1\,\left(1+\sqrt{\frac{h_0\,w_1}{h_1\,w_0}}\right)}\;.
\]
\figuretwoareaeq{example-image-10x16}{example-image-16x10}{This is the figure caption.}{0.8}
\blindtext
\end{document}

enter image description here

8
  • wow you've discovered that 16x10=10x16 :-) – David Carlisle Mar 17 '20 at 8:36
  • Excellent, this solves completely (apart from some easy fixing needed about parameters -- actually 6 are needed) the case of a single figure with caption and subcaptions, and I guess it can be adapted to other cases as the ones in the question (one main caption with no subcaptions, two main captions). The only additional request is to change the vertical aligning in order to center vertically the two images. I calculated the vertical shift needed as \edef\tmpvs{\fpeval{0.5*(\tmpx*\ht0+\tmpy*\ht1)}}, but I'm not able to use the result, I guess I'm missing something about units of measure. – mmj Mar 17 '20 at 10:48
  • @mmj oh sure yes ignore that comment I was just being rude to Schrödinger's cat (he can take it:-) – David Carlisle Mar 17 '20 at 11:11
  • 1
    @mmj You only need \CenterFloatBoxes, so this one does not have to be computed explicitly. (And I now David, people from this region are known for their politeness. ;-) (Just kidding. ;-) – user194703 Mar 17 '20 at 11:40
  • 1
    @mmj Good point! It is given by \columsep. You can change it with, say, \columnsep=4pt. I updated the answer accordingly. – user194703 Mar 17 '20 at 23:37

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.