5

I am trying to draw an arrow between two imported PNG images in a beamer presentation using TikZ and the \tikzmarknode command.

Everything works, as in my example below, but I can only draw in absolute coordinates on the image. In this way, if I scale the figure by changing \includegraphics[width=...], the position of the arrow changes with respect to the image.

How can I draw the tip of the arrow in relative coordinates to the image, in such a way that the arrow location does not change when I scale the image with \includegraphics?

My question is related to tikz relative coordinates and to Tikz coordinates relative to one node, but I am not sure how to apply the idea between different images.

\documentclass{beamer}

\usepackage{tikz}
\usetikzlibrary{tikzmark}

\begin{document}

\begin{frame}{Two Figures}

    \begin{columns}
        
        \column{0.5\textwidth}            
        \tikzmarknode{fig1}{\includegraphics[width=.7\textwidth]{example-image}}

        \column{0.5\textwidth}
        \tikzmarknode{fig2}{\includegraphics[width=.7\textwidth]{example-image}}

    \end{columns}

    \begin{tikzpicture}[remember picture, overlay]
        \draw[->, red, ultra thick] (fig1) -- ([xshift=20, yshift=30]fig2.center);
    \end{tikzpicture}

\end{frame}

\end{document}

enter image description here

1

3 Answers 3

3

You could use switch to coordinates relative to the second image. The lower left corner will be (0,0), the upper right corner (1,1).

\documentclass{beamer}

\usepackage{tikz}
\usetikzlibrary{tikzmark}

\begin{document}

\begin{frame}
  \frametitle{Two Figures}
  \begin{columns}
    \begin{column}{0.5\textwidth}
      \tikzmarknode{fig1}{\includegraphics[width=.7\textwidth]{example-image}}
    \end{column}
    \begin{column}{0.5\textwidth}
      \tikzmarknode{fig2}{\includegraphics[width=.7\textwidth]{example-image}}
    \end{column}
  \end{columns}
  \begin{tikzpicture}[
    remember picture,
    overlay,
    shift={(fig2.south west)},
    x={(fig2.south east)},
    y={(fig2.north west)}
  ]
    \draw[->, green, ultra thick] (fig1) -- (0.7,0.85);        
  \end{tikzpicture}
\end{frame}

\end{document}

enter image description here

4
\documentclass{beamer}
\usepackage{tikz}
\begin{document}
\begin{frame}{Two Figures}

\begin{columns}
\column{0.5\textwidth}
\begin{tikzpicture}[remember picture]
\node[anchor=south west, inner sep=0pt] (p1) {\includegraphics[width=.9\textwidth]{example-image}};
\tikzset{x=(p1.south east), y=(p1.north west)}
\coordinate (c1) at (0.29,0.62);
\end{tikzpicture}

\column{0.5\textwidth}
\begin{tikzpicture}[remember picture]
\node[anchor=south west, inner sep=0pt] (p2) {\includegraphics[width=.6\textwidth]{example-image}};
\tikzset{x=(p2.south east), y=(p2.north west)}
\coordinate (c2) at (0.29,0.62);
\end{tikzpicture}
\end{columns}

\begin{tikzpicture}[remember picture, overlay]
\draw[->, red, ultra thick] (c1) -- (c2);
\end{tikzpicture}

\end{frame}
\end{document}

Two images with red arrow between

3

There's a useful method for drawing over images without requiring remember picture. I'd use this with the two images in a single tikzpicture. The slides below demonstrate steps in the method. You would not include the first two in your final version.

Basically, you divide the target image into a grid, which you print over the top during development and use for placing things. This grid is relative to the picture size, so (0.5,0.5) is always at the centre, (0.1,0.4) is always 10% up from the bottom and 40% across from the left. Hence, if you change the picture size, your arrow will still point to the same part of the image.

The method is based on existing answers, especially Caramdir's and Jake's, but it is convenient enough to be worth packaging for your own use. The approach is not specific to included graphics, of course. It can be used with anything you can put into a (rectangular) node.

\begin{filecontents}[overwrite]{tikz-box-helper.sty}
\ProvidesPackage{tikz-box-helper.sty}
% cfr

\RequirePackage{tikz}
\usetikzlibrary{positioning}

% ateb: https://tex.stackexchange.com/a/374029/ addaswyd o gwestiwn Skeleton Bow: https://tex.stackexchange.com/q/374012/
% copi fel tikz-boxhelper.tex yn y lle arferol
% Datrysiad addaswyd o atebion i gwesiwn http://tex.stackexchange.com/questions/9559/drawing-on-an-image-with-tikz gan Caramdir (https://tex.stackexchange.com/a/9561/) a Jake (https://tex.stackexchange.com/a/9562/)

\newif\ifhelpermarks

\newenvironment{boxhelper}[2][]{%
  \begin{scope}[shift=(#2.south west), x=(#2.south east), y=(#2.north west), #1]%
    \ifhelpermarks
      \begin{pgfinterruptboundingbox}%
        \begin{scope}[every helper line, every node/.append style={every helper mark}]
          \foreach \i [evaluate=\i as \j using {\i/10}, evaluate=\i as \k using { \i>0 ? ( \i<10 ? 0.\i : 1 ) : 0 } ] in {0,1,...,10}%
          {%
            \node [below right=2.5pt and \j of #2.south west, anchor=north] {\k};
            \node [above left=\j and 2.5pt of #2.south west, anchor=east] {\k};
            \node [above right=2.5pt and \j of #2.north west, anchor=south] {\k};
            \node [above right=\j and 2.5pt of #2.south east, anchor=west] {\k};
            \draw (\j,0) -- (\j,1) (0,\j) -- (1,\j);
          }%
        \end{scope}%
      \fi
    }{%
      \ifhelpermarks
        \end{pgfinterruptboundingbox}%
      \fi
  \end{scope}%
}

\tikzset{%
  helper marks/.is if=helpermarks,
  helper marks/.initial=false,
  helper marks/.default=true,
  every helper mark/.style={help lines, font=\sffamily\scriptsize},
  every helper line/.style={help lines},
}
\endinput
\end{filecontents}

\documentclass{beamer}
\usepackage{tikz}
\usepackage{tikz-box-helper}
\begin{document}
\begin{frame}{Set Up}
  \begin{tikzpicture}[every node/.append style={inner sep=0pt}]
    \node (img1) {\includegraphics[width=.35\textwidth]{example-image-a}};
    \node [xshift=.5\textwidth] (img2) {\includegraphics[width=.35\textwidth]{example-image-b}};
    \begin{boxhelper}[helper marks]{img2}
      
    \end{boxhelper}
  \end{tikzpicture}
\end{frame}
\begin{frame}{Configuration}
  \begin{tikzpicture}[every node/.append style={inner sep=0pt}]
    \node (img1) {\includegraphics[width=.35\textwidth]{example-image-a}};
    \node [xshift=.5\textwidth] (img2) {\includegraphics[width=.35\textwidth]{example-image-b}};
    \begin{boxhelper}[helper marks]{img2}
      \draw [->,red,ultra thick] (img1) -- (0.6,0.8);
    \end{boxhelper}
  \end{tikzpicture}
\end{frame}
\begin{frame}{Two Figures}
  \begin{tikzpicture}[every node/.append style={inner sep=0pt}]
    \node (img1) {\includegraphics[width=.35\textwidth]{example-image-a}};
    \node [xshift=.5\textwidth] (img2) {\includegraphics[width=.35\textwidth]{example-image-b}};
    \begin{boxhelper}{img2}
      \draw [->,red,ultra thick] (img1) -- (0.6,0.8);
    \end{boxhelper}
  \end{tikzpicture}
\end{frame}
\begin{frame}{Down-scaling}
  \begin{tikzpicture}[every node/.append style={inner sep=0pt}]
    \node (img1) {\includegraphics[width=.25\textwidth]{example-image-a}};
    \node [xshift=.5\textwidth] (img2) {\includegraphics[width=.25\textwidth]{example-image-b}};
    \begin{boxhelper}{img2}
      \draw [->,red,ultra thick] (img1) -- (0.6,0.8);
    \end{boxhelper}
  \end{tikzpicture}
\end{frame}
\begin{frame}{Up-scaling}
  \begin{tikzpicture}[every node/.append style={inner sep=0pt}]
    \node (img1) {\includegraphics[width=.45\textwidth]{example-image-a}};
    \node [xshift=.5\textwidth] (img2) {\includegraphics[width=.45\textwidth]{example-image-b}};
    \begin{boxhelper}{img2}
      \draw [->,red,ultra thick] (img1) -- (0.6,0.8);
    \end{boxhelper}
  \end{tikzpicture}
\end{frame}
\end{document}

The image below is crappy due to the buggyness of KDE6/current Okular. The PDF is fine.

Development:

development

Result:

result

Scaling:

scaling

You must log in to answer this question.

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