3

I have an external picture and I want to put some labels on it. The code below works fine, but I want to automate the calculation of the vertical label positions in case of resizing the imported external figure. Is there a way to obtain the height of the node probe or the image itsels and to use that in the positioning inside [above right = 2cm and 1cm of probe], e.g. something like [above right = 0.25*\imageheight and 1cm of probe] ?

\documentclass[a4paper,10pt]{scrreprt}
\usepackage[T1]{fontenc}
% \usepackage[utf8]{inputenc}
\usepackage[latin1]{inputenc}
\usepackage{geometry}
\geometry{a4paper,left=25mm,right=25mm, top=25mm, bottom=25mm}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}
  \node[inner sep=0pt] (probe) at (0,0){\includegraphics[width=.25\textwidth]{test}};
  \node[right = 1cm of probe](adhesivelabel) at (probe.east) {Adhesive};
  \node[above right = 2cm and 1cm of probe](adherent1label) at (probe.east) {Adherent 1};
  \node[below right = 2cm and 1cm of probe](adherent2label) at (probe.east) {Adherent 2};

  \draw[->] (adhesivelabel.west)  -- (probe);
  \draw[->] (adherent1label.west) -- (probe.east |- adherent1label.west);
  \draw[->] (adherent2label.west) -- (probe.east |- adherent2label.west);
\end{tikzpicture}
\end{document}

enter image description here

4

First solution with calc TiKZlibrary:

\documentclass[a4paper,10pt]{scrreprt}
\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}
\usepackage{geometry}
\geometry{a4paper,left=25mm,right=25mm, top=25mm, bottom=25mm}
\usepackage{tikz}
\usetikzlibrary{positioning,calc}

\begin{document}

\begin{tikzpicture}
  \node[inner sep=0pt] (probe) at (0,0){\includegraphics[width=.25\textwidth]{example-image}};
  \node[right = 1cm of probe](adhesivelabel) at (probe.east) {Adhesive};
  \path let \p1=($(probe.north west)$),
            \p2=($(probe.south east)$),
            \n{height} = {veclen(\y1,\y2)},
            \n{width}= {veclen(\x1,\x2)} in 
   node[above right = 1.2*\n{height} and 0.75*\n{width} of probe](adherent1label) at (probe.east) {Adherent 1};
  \node[below right = 2cm and 1cm of probe](adherent2label) at (probe.east) {Adherent 2};

  \draw[->] (adhesivelabel.west)  -- (probe);
  \draw[->] (adherent1label.west) -- (probe.east |- adherent1label.west);
  \draw[->] (adherent2label.west) -- (probe.east |- adherent2label.west);
\end{tikzpicture}
\end{document}

enter image description here

Second solution with \tcbsetmacroto{width|height} commands from tcolorbox skin library:

\documentclass[a4paper,10pt]{scrreprt}
\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}
\usepackage{geometry}
\geometry{a4paper,left=25mm,right=25mm, top=25mm, bottom=25mm}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage[skins]{tcolorbox}

\begin{document}

\begin{tikzpicture}
  \node[inner sep=0pt] (probe) at (0,0){\includegraphics[width=.25\textwidth]{example-image}};
  \tcbsetmacrotowidthofnode{\imagewidth}{probe}
  \tcbsetmacrotoheightofnode{\imageheight}{probe}
  \node[right = 1cm of probe](adhesivelabel) at (probe.east) {Adhesive};
  \node[above right = 0.5*\imageheight and 0.75*\imagewidth of probe](adherent1label) at (probe.east) {Adherent 1};
  \node[below right = 0.3*\imageheight and 0.25*\imagewidth of probe](adherent2label) at (probe.east) {Adherent 2};

  \draw[->] (adhesivelabel.west)  -- (probe);
  \draw[->] (adherent1label.west) -- (probe.east |- adherent1label.west);
  \draw[->] (adherent2label.west) -- (probe.east |- adherent2label.west);
\end{tikzpicture}
\end{document}

enter image description here

5
  • Thanks a lot @Ignasi. Despite the obious TikZ-internal first solution, I prefer the second one, due to its simplicity. Unfortunately, despite the image I attached in the original post has no border, the labels are higher than the actual image if I use \node[above right = 0.5*\imageheight and 0.75*\imagewidth of probe](adherent1label) at (probe.east) {Adherent 1};. Does the node add additional space between node.north and node.south and the included image?
    – raedma
    Apr 13 '15 at 10:50
  • @krtek No the problem is the anchor for adherent1label which is south west when above right is used. Add anchor=west as last option in \node command and try again.
    – Ignasi
    Apr 13 '15 at 10:58
  • Thx. That helped. Could you please explain why? Is south west the standard option?
    – raedma
    Apr 13 '15 at 12:06
  • @krtek Every positioning option fixes an anchor by default, above right selects south west, right selects west, below left selects north east, ... But you can change them with anchor=... after postioning.
    – Ignasi
    Apr 13 '15 at 12:22
  • Well, thanks. Despite @sgmoye's solution is charming as well, I prefer your second one.
    – raedma
    Apr 14 '15 at 8:27
5

This solution is based on making the unit of measurement on the x-axis equal to the width of the graphic, and the unit of measurement on the y-axis equal to the height of the graphic. That being the case, a coordinate like (1,1) would indicate the upper right corner of the graphic (north east in TikZese), (0.5,0.5) would be the geometric center of the graphic and (0,0) would represent the lower left corner (south west in TikZese). This conveniently eliminates the need to calculate the size of the graphic explicitly. I've added another label as further example. I find it a more intuitive way of placing labels.

The south east corner of the graphic is used to base the placement of the labels; the calc TikZ library is used to place them at the desired location. The |- operator is used to ensure that that the arrow is drawn perpendicularly from the label to the graphic.

\documentclass[tikz]{standalone}

\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
    \node[anchor=south west,inner sep=0] (probe) at (0,0)
        {\includegraphics[width=0.4\textwidth]{example-image}};
    \begin{scope}[x={(probe.south east)},y={(probe.north west)}]
    \node[anchor=west] (p1) at ($(probe.south east) + (1cm,0.5)$) {Adhesive};
    \node[anchor=west] (p2) at ($(probe.south east) + (2cm,1.25)$) {Adherent 1};
    \node[anchor=west] (p3) at ($(probe.south east) + (1cm,0.1)$) {Adherent 2};
    \node[anchor=west] (p4) at ($(probe.south east) + (1cm,0.75)$) {Something else of interest};
    \draw[->] (p1) -- (probe.east |- p1);
    \draw[->] (p2) -- (probe.east |- p2);
    \draw[->] (p3) -- (probe.east |- p3);
    \draw[->] (p4.west) -- (0.5,0.25);
    \end{scope}
\end{tikzpicture}

\end{document}

Example of label placement on figure.

Update

I should have given the same code using TikZ's positioning library. The output is identical:

\documentclass[tikz]{standalone}

\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}
    \node[anchor=south west,inner sep=0] (probe) at (0,0)
        {\includegraphics[width=0.4\textwidth]{example-image}};
    \begin{scope}[x={(probe.south east)},y={(probe.north west)}]
    \node[above right=0.5 and 1cm of probe.south east,anchor=west] (p1)
        {Adhesive};
    \node[above right=1.25 and 2cm of probe.south east,anchor=west] (p2)
        {Adherent 1};
    \node[above right=0.1 and 1 cm of probe.south east,anchor=west] (p3)
        {Adherent 2};
    \node[above right=0.75 and 1 cm of probe.south east,anchor=west] (p4)
        {Something else of interest};
    \draw[->] (p1) -- (probe.east |- p1);
    \draw[->] (p2) -- (probe.east |- p2);
    \draw[->] (p3) -- (probe.east |- p3);
    \draw[->] (p4.west) -- (0.5,0.25);
    \end{scope}
\end{tikzpicture}

\end{document}
3
  • This sure has its benefits when you have to work with positions inside the image
    – raedma
    Apr 16 '15 at 13:41
  • This is a great example for relative \includegraphics positioning inside a tikzpicture environment!
    – Prevost
    Feb 11 at 3:30
  • @Prevost Thanks, and thanks for the reminder. I should have also given a solution using the TikZ positioning library -- all the cool kids use it. Done.
    – sgmoye
    Feb 13 at 13:06

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.