3

The objective is to have arrows along a path for every 1-unit step we take horizontally or vertically. The arrows would be aligned midway between major grid tick marks, e.g. midway along (0,0)--(0,1). To give context, these arrows could be used to show east-west and north-west movement along a rectangular grid.

I have managed to handle the case where the x and y units are the same. Below I have tweaked the parameters to have the blue arrows aligned at the midpoint (grid minor line colored in cyan). But I failed with the red arrows. The problem is that the x-scale and y-scale are quite different. If the step is tweaked to match horizontal distances (parallel to the x-axis), then it will not match the vertical distances. How to fix this?

To clarify, if I give a path like (0,0)--(10,0), I would like an arrow midway along (0,0)--(1,0), then midway along (1,0)--(2,0), and so on. Otherwise I would just use something like [midway](0,0)--(10,0) or [pos=0.5](0,0)--(10,0). In my code I have to tweak the "starting value" as well as the "step". It would obviously be much nicer to have a solution where I could set a starting value at 0.5 (meaning at the midway point between two major grid tick lines) and a step equal to 1 (meaning moving by 1 unit of image scale --- not units of the axis --- along both x and y directions).

\documentclass[border=3pt,tikz]{standalone} \usepackage{pgfplots} \pgfplotsset{compat=newest} \usetikzlibrary{calc} % Required for coordinate calculations \usetikzlibrary{decorations.markings} % Required for decorations along path % Define a TikZ style for arrows on path: color as optional argument % \usetikzlibrary{decorations.markings, arrows.meta} \tikzset{ arrows along path/.style args={#1/#2/#3}{% >=latex, decoration={ markings, mark=between positions #1 and #2 step #3 with { \arrow{latex} } }, postaction={decorate} }, arrows along path/.default={0/1/0.5} } % x has range 5 % y has range 3000 % 3000/5 = 600 % 5/3000 = 0.00166666666 \begin{document} \begin{tikzpicture} \begin{axis}[ x = 2cm, y = 0.0033cm,% tweaked to match y/x=5/3000 ratio xmin=0, xmax=5, ymin=500, ymax=3500, xtick = {0,1,...,5}, ytick = {500,1000,...,3500}, tick align=outside, minor tick num=1, minor tick length=4pt, minor tick style={color=cyan,thick}, minor grid style={color=cyan,thick}, grid = both, clip = false, ] \coordinate (A) at (0,2000); \coordinate (B) at (5,2000); \coordinate (C) at (0,1000); \coordinate (D) at (1,1000); \coordinate (E) at (1,3000); \coordinate (F) at (4,3000); \coordinate (G) at (4,1000); \coordinate (H) at (5,1000); % Blue line \draw [blue, thick, arrows along path={0.118/1/0.20}] (A) -- (B); % Red line \draw [red, thick, arrows along path={0.051/1/0.079}] (C) -- (D) -- (E) -- (F) -- (G) -- (H); \end{axis} \end{tikzpicture} \end{document} 

enter image description here

Second implementation, also fails to get the correct output:

\documentclass[border=3pt,tikz]{standalone} \usepackage{pgfplots} \pgfplotsset{compat=newest} \usetikzlibrary{calc} % Required for coordinate calculations \usetikzlibrary{decorations.markings} % Required for decorations along path % Define a TikZ style for arrows on path: color as optional argument % \usetikzlibrary{decorations.markings, arrows.meta} \tikzset{ arrows along path/.style args={#1/#2/#3}{% >=latex, decoration={ markings, mark=between positions #1 and #2 step #3 with { \arrow{latex} } }, postaction={decorate} }, arrows along path/.default={0/1/0.5} } \begin{document} \begin{tikzpicture} \begin{axis}[ x=2cm, y=0.0033cm, xmin=0, xmax=5, ymin=500, ymax=3500, xtick = {0,1,...,5}, ytick = {500,1000,...,3500}, tick align=outside, minor tick num=1, minor tick length=4pt, minor tick style={color=cyan,thick}, minor grid style={color=cyan,thick}, grid = both, clip = false, ] \coordinate (A) at (0,2000); \coordinate (B) at (5,2000); \coordinate (C) at (0,1000); \coordinate (D) at (1,1000); \coordinate (E) at (1,3000); \coordinate (F) at (4,3000); \coordinate (G) at (4,1000); \coordinate (H) at (5,1000); % Blue line \draw [blue, thick, arrows along path={0.12/1/0.20}] (A) -- (B); % Red line \pgfplotsextra{ \foreach \P/\Q in {C/D, D/E, E/F, F/G, G/H}{ \draw [red, thick, arrows along path={0.6/1/0.40}] (\P) -- (\Q); } } \end{axis} \end{tikzpicture} \end{document} 

enter image description here

A variant with a node and a dot, that sort of look like the ideal implementation for its simplicity, but fails just the same.

\documentclass[border=3pt,tikz]{standalone} \usepackage{pgfplots} \pgfplotsset{compat=newest} \usetikzlibrary{calc} % Required for coordinate calculations \usetikzlibrary{decorations.markings} % Required for decorations along path % set up all axes \pgfplotsset{% every axis/.append style={% axis styles %ticks = none, grid = both, clip = false,% remove clip }% }% % Define a TikZ style for arrows \tikzset{ marks along path/.style args={#1/#2/#3/#4}{% decoration={ markings, mark=between positions #1 and #2 step #3 with { \node[#4] at (0,0) {}; } }, postaction={decorate} }, marks along path/.default={0/1/0.5/shape=circle,fill=black,draw=black,inner sep=0pt,minimum size=4mm,line width=2pt} } \begin{document} \begin{tikzpicture} \begin{axis}[ x = 2cm, y = 0.0033cm,% tweaked to match y/x=5/3000 ratio xmin=0, xmax=5, ymin=500, ymax=3500, xtick = {0,1,...,5}, ytick = {500,1000,...,3500}, tick align=outside, minor tick num=1, minor tick length=4pt, minor tick style={color=cyan,thick}, minor grid style={color=cyan,thick}, grid = both, clip = false, ] \coordinate (A) at (0,2000); \coordinate (B) at (5,2000); \coordinate (C) at (0,1000); \coordinate (D) at (1,1000); \coordinate (E) at (1,3000); \coordinate (F) at (4,3000); \coordinate (G) at (4,1000); \coordinate (H) at (5,1000); % Blue line \draw[blue, line width=2pt, marks along path={0/1/0.5/shape=circle,fill=blue,draw=black}] (A) -- (B); \draw[red, line width=2pt, marks along path={0/1/0.5/shape=circle,fill=red,draw=black}] (C) -- (D) -- (E) -- (F) -- (G) -- (H); \end{axis} \end{tikzpicture} \end{document} 

enter image description here

1 Answer 1

5

Set the starting point and step size in the decoration by length instead of by percentage using mark=between positions 6mm and 1 step 10mm. Now the marking will occur every 10mm, starting at the 6mm mark (which is the tip of the arrowhead, not the center) and ending at position 1 (i.e., 100%, the end of the path).

Note that for this to work the vertical segments and horizontal segments must have equal length, so the ratio is 500:1 not 600:1.

enter image description here

\documentclass{article} \usepackage{pgfplots} \pgfplotsset{compat=newest} \usetikzlibrary{calc} % Required for coordinate calculations \usetikzlibrary{decorations.markings} % Required for decorations along path % Define a TikZ style for arrows on path: color as optional argument % \usetikzlibrary{decorations.markings, arrows.meta} \tikzset{ arrows along path/.style={% >=latex, decoration={ markings, mark=between positions 6mm and 1 step 10mm with { \arrow{latex} } }, postaction={decorate} } } % x has range 5 % y has range 3000 % 2500/5 = 500 % 5/2500 = 0.002 \begin{document} \begin{tikzpicture} \begin{axis}[ x = 2cm, y = 0.004cm,% tweaked to match y/x=1/500 ratio xmin=0, xmax=5, ymin=500, ymax=3500, xtick = {0,1,...,5}, ytick = {500,1000,...,3500}, tick align=outside, minor tick num=1, minor tick length=4pt, minor tick style={color=cyan,thick}, minor grid style={color=cyan,thick}, grid = both, clip = false ] \coordinate (A) at (0,2000); \coordinate (B) at (5,2000); \coordinate (C) at (0,1000); \coordinate (D) at (1,1000); \coordinate (E) at (1,3000); \coordinate (F) at (4,3000); \coordinate (G) at (4,1000); \coordinate (H) at (5,1000); % Blue line \draw [blue, thick, arrows along path] (A) -- (B); % Red line \draw [red, thick, arrows along path] (C) -- (D) -- (E) -- (F) -- (G) -- (H); \end{axis} \end{tikzpicture} \end{document} 
3
  • maybe I misunderstood the qn, but I thought it was specifically asking how to do it when the vertical/horizontal are not equal? Commented Nov 11 at 23:44
  • Thanks Sandy! I had x range from 1 to 5 initially, then made it start at 0 and totally forgot to readjust the ratio. So that wasn't helping, for sure. Do you see an approach that would reduce the amount of tweaking of distances needed? Commented Nov 12 at 3:07
  • 1
    @cfr for my particular use case, I can set equal distances along both axes, as long as the actual units are different, so Sandy's solution covers my immediate needs. It would be interesting to learn how to do it in a more general case, of course. But more importantly, it would be convenient if I didn't have to tweak the scales each time. It would reduce the risk of making the stupid mistake of taking the length of [0,5] as 5 lol! Commented Nov 12 at 3:13

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.