Here is an example using flowfram. It's more complicated than the other two solutions, BECAUSE it gives you more options for control.
It may not be perfect from a flowfram perspective, but should give you some clues and motivation. So let's go through some important steps towards the result. And as always: There Always Is More Than One Way To Do It, even with this package.
(1) There are 3 lines of code where you can switch on/off some choices to see effects:
flowframs draft-option, geometries show frame; as you can see in other images, flowfram takes some liberty here and there
\usepackage[
% draft
]{flowfram}
\usepackage[
% show frame
]{geometry}
Manipulating "caption" text to demonstrate the flow from frame to frame, with \img being a simple macro to put some images (see also below)
\img{c}{E}
% \img{c}{E, followed by some longer extra text ...
(2) The most important step is to define frames, here flowframes: there are also static frames for e.g. fixed logos, and dynamic frames, e.g. for layout manipulations of chapter headings.
- most heights are modified to avoid overlap
- the x-position for the right frames needed some gap, solved by using factor 0.54 instead of 0.5 (lazy approach)
% ~~~ all required flow-frames ~~~~~~~~~~
% they are filled in their order of creation
% W H x y, positions from bottom left
%
\newflowframe{.5\textwidth}{.3\textheight-0\flowframesep}
{0pt}{.7\textheight}
\newflowframe{.5\textwidth}{.3\textheight-0\flowframesep}
{.54\textwidth}{.7\textheight}
\newflowframe{.5\textwidth}{.4\textheight-\flowframesep}
{0pt}{.3\textheight}
\newflowframe{.5\textwidth}{.3\textheight-\flowframesep}
{.54\textwidth}{.4\textheight}
\newflowframe{.5\textwidth}{.3\textheight-\flowframesep}
{0pt}{0pt}
\newflowframe{.5\textwidth}{.4\textheight-\flowframesep}
{.54\textwidth}{0pt}
These allow to write content like this, but let it flow from flow-frame to flow-frame in the order given, just like LaTeX lets content flow from textarea to textarea:
\begin{document}
\img{a}{A}
\img{b}{B}
\img{c}{C}
\img{duck}{D}
\img{c}{E}
...
Here's the result with both draft and show frame in action (see below!). The frames are indicated, with margin-frames being overlaid. The page layout repats on the next page, which also provides some coordinates AND a pecularity which flowfram has from time to time, depending on the text you provide for display.
When you switch the \img{E}{...} line, you see the flow again, which may be very distracting when removing draft-frames, i.e. switching to option final:

(3) Preparations for grid-layout.
If you ever worked with a layout-driven program like FrameMaker, Scribus or MS Publisher, you know you have to adapt to this approach. E.g.
- you need to modify drawings (in advance)
- the duck-image MEETS the aspect ratio DEFINED somehow by this sort of layout frames chosen (too big images (
[width=\linewidth]) push the caption to the next flow-frame); while the other images have a "wrong" aspect ratio
- you need to define lenghts and overlaps as needed, e.g. if you want to stay within boundaries set by
geometry
- your control, your duty
And yes, I start liking flowframe, and it will provide some surprises on its learning curve. It's nicely done, nevertheless, with a touch of math, useful for many non-standard layouts within certain limits of complexity.
(Code)
% https://tex.stackexchange.com/questions/529766/typesetting-a-fancy-grid-of-figures
\documentclass{article}
\usepackage{graphicx}
\usepackage{calc}
\usepackage{lipsum}
\usepackage[
% draft
]{flowfram}
\usepackage[
% show frame
]{geometry}
% ~~~ default graphics and captions ~~~~~~~~~~~~~~~~
\newcommand\img[2]{\includegraphics[height=.23\textheight]{example-image-#1}\%
Caption #2\}
% ~~~ printing frame-data ~~~~~~~~~
\newcommand\FD[1]{\getflowbounds{#1}%
FF-#1: \the\ffareawidth / \the\ffareaheight / %
\the\ffareax / \the\ffareay\}
% ~~~ printing textarea-data ~~~~~~
\newcommand\TA[0]{textwidth: \the\textwidth / textheight: \the\textheight\}
% ~~~ all required flow-frames ~~~~~~~~~~
% they are filled in their order of creation
% W H x y, positions from bottom left
%
\newflowframe{.5\textwidth}{.3\textheight-0\flowframesep}
{0pt}{.7\textheight}
\newflowframe{.5\textwidth}{.3\textheight-0\flowframesep}
{.54\textwidth}{.7\textheight}
\newflowframe{.5\textwidth}{.4\textheight-\flowframesep}
{0pt}{.3\textheight}
\newflowframe{.5\textwidth}{.3\textheight-\flowframesep}
{.54\textwidth}{.4\textheight}
\newflowframe{.5\textwidth}{.3\textheight-\flowframesep}
{0pt}{0pt}
\newflowframe{.5\textwidth}{.4\textheight-\flowframesep}
{.54\textwidth}{0pt}
\setallflowframes{border=none}
%\ffvadjustfalse
\parindent0pt
\begin{document}
\img{a}{A}
\img{b}{B}
\img{c}{C}
\img{duck}{D}
\img{c}{E}
% \img{c}{E, followed by some longer extra text, which can be quite long, and needs to be long, to flow into the next flow-frame. This may or may not be a nice feature. Sometimes it is, sometimes it's not.\}
\img{c}{F}
\clearpage
% ~~~ some data ~~~~~~~~~~~~~
\TA{}
flowframesep: \the\flowframesep \\
\FD{1}
\FD{2}
\FD{3}
\FD{4}
\FD{5}
\FD{6}
\lipsum[1-3]
\end{document}