36

I want to make a figure composed of two images that have different sizes. I want to put them side by side so that they have the same height and that they overall take, say, 90% of the line width.

It is easy to make them have the same fixed height (say in cm), but how to let this common height be automatically adjusted to fulfill the desired overall width? Manual trial-and-error is time-consuming, approximate and non robust.

A solution with or without subfigure or another LaTeX package is OK.

3 Answers 3

29

You can include them to the same (more or less arbitrary) height then scale them together to the desired width

enter image description here

\documentclass{article}

\usepackage{graphicx}% images from mwe package

\begin{document}

\noindent X\dotfill X

\begin{center}
\resizebox{.9\textwidth}{!}{%
\includegraphics[height=3cm]{example-image-a}%
\quad
\includegraphics[height=3cm]{example-image-16x9}%
}
\end{center}

\end{document}
11
  • 1
    He said "It is easy to make them have the same fixed height (say in cm), but how to let this common height be automatically adjusted to fulfill the desired overall width? Manual trial-and-error is time-consuming, approximate and non robust."
    – Astrinus
    Dec 17, 2014 at 11:21
  • @Astrinus that's what he said, and that's what this does Dec 17, 2014 at 11:42
  • You are fixing an height, but what if both the images are taller than wider?
    – Astrinus
    Dec 17, 2014 at 11:56
  • 1
    @user1735003 not really, you'd have to measure and scale "by hand" so the markup would be quite a bit more complicated. Possible of course. Dec 17, 2014 at 12:57
  • 1
    I created a small package which allows you to create rows of figures: tex.stackexchange.com/questions/227935/…
    – Herbert
    Feb 14, 2015 at 11:07
22

You can use the subcaption package and do the computation as suggested by David.

\documentclass{article}

\usepackage{graphicx}% images from mwe package
\usepackage{subcaption}

\newlength{\twosubht}
\newsavebox{\twosubbox}

\begin{document}

\noindent\hrulefill The text width\hrulefill

\begin{center}
\makebox[.9\textwidth]{\hrulefill 90\% of text width\hrulefill}
\end{center}

\begin{figure}[htp]

% preliminary
\sbox\twosubbox{%
  \resizebox{\dimexpr.9\textwidth-1em}{!}{%
    \includegraphics[height=3cm]{example-image-a}%
    \includegraphics[height=3cm]{example-image-16x9}%
  }%
}
\setlength{\twosubht}{\ht\twosubbox}

% typeset

\centering

\subcaptionbox{First\label{f}}{%
  \includegraphics[height=\twosubht]{example-image-a}%
}\quad
\subcaptionbox{Second\label{s}}{%
  \includegraphics[height=\twosubht]{example-image-16x9}%
}

\caption{The caption}

\end{figure}

\end{document}

enter image description here

2
  • This works, (so +1 and thanks!) but what is going on here? Is the "preliminary" part solely for estimating the height and then never used other than that?
    – lucidbrot
    Jul 1, 2023 at 21:26
  • 2
    @lucidbrot In the preliminary part, the two images are set together, in order to compute the final height, but then we need to insert them separately.
    – egreg
    Jul 2, 2023 at 8:02
1
\documentclass[a4paper,12pt]{article}
\usepackage{graphicx}
\usepackage{adjustbox}
\usepackage{fp}
\usepackage{subcaption}

\newlength{\totalimgwidth}
\newlength{\imgspacingwidth}

\newlength{\firstimgorigwidth}
\newlength{\firstimgorigheight}
\newlength{\secondimgorigwidth}
\newlength{\secondimgorigheight}
\newlength{\firstimgwidth}
\newlength{\secondimgwidth}

\newcommand{\setsubfloatwidths}[2]{%set the total width you want the images take and the spacing between them
\setlength{\totalimgwidth}{#1}%
\setlength{\imgspacingwidth}{#2}%
\addtolength{\totalimgwidth}{-\imgspacingwidth}%
}


\begin{document}
\setsubfloatwidths{0.9\textwidth}{1ex} %set the total width of figure and spacing inbetween
\begin{figure}
\adjincludegraphics[gstore width=\firstimgorigwidth,gstore height=\firstimgorigheight,gobble]{img1}%
\adjincludegraphics[gstore width=\secondimgorigwidth,gstore height=\secondimgorigheight,gobble]{img2}%
\makeatletter%
\FPdiv\firstaspectratio{\strip@pt\firstimgorigheight}{\strip@pt\firstimgorigwidth}%
\FPdiv\secondaspectratio{\strip@pt\secondimgorigheight}{\strip@pt\secondimgorigwidth}%
\FPeval\firstfactor{\secondaspectratio / (\firstaspectratio + \secondaspectratio)}%
\FPeval\secondfactor{\firstaspectratio / (\firstaspectratio + \secondaspectratio)}%
\makeatother%
\begin{subfigure}{\firstfactor\totalimgwidth}
\includegraphics[width=\textwidth]{img1}
\end{subfigure}
\hspace*{\imgspacingwidth}
\begin{subfigure}{\secondfactor\totalimgwidth}
\includegraphics[width=\textwidth]{img2}
\end{subfigure}
\end{figure}
\end{document}

You set the total width you want the images take and the spacing between them with \setsubfloatswidths, then you call \adjincludegraphics inside the figure environment with the two image files as arguments, and finally you use subfigures as usual.

\firstfactor contains the factor which scales the first image and \secondfactor does the same for the second one.

A simpler solution could have been to set the height of the image, but \subcaption's subfigure environment take as argument the width of the subfloat.

3
  • the graphics package can already scale while preserving aspect ratio so there's no need to do those divisions explicitly. Dec 17, 2014 at 11:43
  • 1
    I know, but the problem is that if you want to use subcaption package, you have to pass it the widths of the subfloats.
    – Astrinus
    Dec 17, 2014 at 11:54
  • 2
    packages are supposed to make things easier, not harder:-) Dec 17, 2014 at 11:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .