2

I need to draw some arrows between two given points in my diagram. I want to turn the shorter arrow into four smaller ones and the longer one into seven, all joined together. How can I draw them automatically between the given coordinates?

Code:

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.15}
\usetikzlibrary{arrows.meta}
\tikzset{
    myarrow/.style={-{Triangle[length=1.5mm,width=1.5mm]}}
}
\begin{document}
\begin{tikzpicture}
 \begin{axis}[
   every axis plot post/.style={mark=-,thick,mark size=10mm},
   xtick style={draw=none},
   xticklabels={,,},
   xmin=-0.9,
   xmax=1.1,
   ymin=15,
   ymax=20,
   cycle list name=black white,
   only marks, 
   x=2cm, y=1cm,
   every node near coord/.append style={font=\small,yshift=-2.5mm,xshift=\myshift}
 ]
\addplot [nodes near coords={\labelz},
visualization depends on={value \thisrowno{2}\as\labelz},visualization depends on={value \thisrowno{3}\as\myshift}] 
table[header=false] {
0 15.183 a 15mm
0 18.300 b 15mm
0 19.011 c 15mm
};
\draw[draw=blue,myarrow,very thick] (0.25,18.300) -- (0.25,15.183);
\draw[draw=blue,myarrow,very thick] (-0.25,18.300) -- (-0.25,19.011);
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

Expected result for the shorter arrow:

enter image description here

  • 1
    What do you mean by "all joined together"? Could you please provide a hand-drawn sketch of what you're expecting? – Sam Oct 22 at 8:04
  • I don't know if I get the question right, but cannot you superimpose them? – Rob Tan Oct 22 at 9:01
2

TikZ has a function to invoke a command multiple times. It's called with \foreach \i in {1,...,10}{ do something }. Unfortunately, inside the axis environment, this function has some problems, thus the use of \pgfplotsinvokeforeach{1,...,10}{ do something } is encouraged.

Using this as a starting point, I calculated an increment for your arrows, e.g. (18.300-15.183)/\largeArrowParts. This will automatically calculate how long each segment should be, based on the \largeArrowParts number that you can define. In this case, it's set to 8.

I then use this increment to draw \largeArrowParts-many arrows starting at your starting point and moving forward using the index of the \pgfplotsinvokeforeach function.

This will, in fact, stack the arrows on top of each other, and each arrow will start at the starting point; thus, the first arrow is only shorter than the second one, etc. This has two advantages:

  1. It's much easier to code.
  2. It results in one solid line with arrowheads, whereas single arrows of the increment length would segment the line, which doesn't look nice.

Code

\documentclass{standalone}

\usepackage{pgfplots}

\pgfplotsset{compat=1.15}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{calc}

\tikzset{
    myarrow/.style = {-{Triangle[length = 1.5mm, width = 1.5mm]}}
}

\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
            every axis plot post/.style = {
                mark = -,
                thick,
                mark size = 10mm
            },
            xtick style = {
                draw = none
            },
            xticklabels = {,,},
            xmin = -0.9,
            xmax = 1.1,
            ymin = 15,
            ymax = 20,
            cycle list name = black white,
            only marks, 
            x = 2cm,
            y = 1cm,
            every node near coord/.append style = {
                font = \small,
                yshift = -2.5mm, xshift = \myshift
            }
        ]
        
            \addplot [
                nodes near coords = {\labelz},
                visualization depends on = {%
                    value \thisrowno{2}\as\labelz%
                },
                visualization depends on = {%
                    value \thisrowno{3}\as\myshift%
                }
            ] table[header=false] {
                0 15.183 a 15mm
                0 18.300 b 15mm
                0 19.011 c 15mm
            };
            
            \pgfmathsetmacro{\smallArrowParts}{4}
            \pgfmathsetmacro{\largeArrowParts}{8}
            
            \pgfplotsinvokeforeach{1,...,\largeArrowParts}{
                \pgfmathsetmacro{\largeInc}{(18.300-15.183)/\largeArrowParts}
                \draw [
                    draw = blue,
                    myarrow,
                    very thick
                ] (0.25, 18.300) -- (0.25, {18.300 - #1 * \largeInc});
            }
            
            \pgfplotsinvokeforeach{1,...,\smallArrowParts}{
               \pgfmathsetmacro{\smallInc}{(19.011-18.300)/\smallArrowParts}
                \draw [
                    draw = blue,
                    myarrow,
                    very thick
                ] (-0.25, 18.300) -- (-0.25, {18.300 + #1 * \smallInc});
            }

        \end{axis}
    \end{tikzpicture}
\end{document}

Result

Plot

| improve this answer | |

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.