3

Consider the following quiver plot with a singularity:

Is there a way to omit arrows if there length is larger than a given threshold?

Not that I am not asking for a colormap or something like that.

\documentclass[a4paper,12pt]{article}

\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
  \begin{axis}[xmin=-2,xmax=2,ymin=-2,ymax=2,view={0}{90},xlabel=\empty,xlabel=\empty]
    \addplot3+ [samples=15,->,black,%restrict u to domain=0:10, 
    quiver={
      u={x/(x^2 + y^2)},
      v={y/(x^2 + y^2)},
      scale arrows=0.3,   
    },
    ] {0};
  \end{axis}
\end{tikzpicture}  
\end{document}

3 Answers 3

5
+100

You can just add a filter.

\documentclass[a4paper,12pt]{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}

\begin{tikzpicture}
  \begin{axis}[xmin=-2,xmax=2,ymin=-2,ymax=2,view={0}{90},xlabel=\empty,xlabel=\empty]
    \addplot3+ [samples=15,->,black,%restrict u to domain=0:10, 
    quiver={
      u={x/(x^2 + y^2)},
      v={y/(x^2 + y^2)},
      scale arrows=0.3,   
    },
    x filter/.expression={x*x+y*y<0.2? nan:x},
    ] {0};
  \end{axis}
\end{tikzpicture}  
\end{document}

enter image description here

2

I could not get your code running, but using this answer I may have come closer to a solution. The singularity is at x=y=0, and you can cut it of by hand by replacing x^2+y^2 by max(x^2+y^2,0.5).

\documentclass{minimal}
\usepackage{tikz}
\usepackage{pgfplots}

\begin{document}
% from https://tex.stackexchange.com/a/34010/121799
\def\length{max(x^2+y^2,0.5)}
\begin{tikzpicture}
\begin{axis}[domain=-2:2, view={0}{90}]
\addplot3[blue, quiver={u={x/(\length)}, v={y/(\length)}, scale arrows=0.3}, -stealth,samples=20] {0};
\end{axis}
\end{tikzpicture}

\end{document}

Notice also that you might get nicer results if you switch to polar coordinates, in which u=cos(phi)/r and v=sin(phi)/r.

0
2

One can hack into pgfplots' quiver handler and normalize the vector.

\documentclass{article}

\usepackage{pgfplots}

\begin{document}

\makeatletter

\def\pgfplotsplothandlersurveypoint@quiver{%
    % the arrow components are computed here
    \pgfplots@quiver@prepare@u
    \pgfplots@quiver@prepare@v
    \pgfplotsifcurplotthreedim{% 3d?
        \pgfplots@quiver@prepare@w
    }{%
        \let\pgfplots@quiver@w=\pgfutil@empty
    }%
    %%% we add our code that checks arrow length
        \pgfmathsetmacro\vecnormsq{\pgfplots@quiver@u*\pgfplots@quiver@u+\pgfplots@quiver@v*\pgfplots@quiver@v}
        \pgfmathsetmacro\vecnorm{sqrt(\vecnormsq)}
        \pgfmathsetmacro\normmax{1}
        % rescale if necessary

        \pgfmathparse{\vecnormsq > \normmax}
        \ifpgfmathfloatcomparison
            \message{too long!!}
            \pgfmathsetmacro\pgfplots@quiver@u{\pgfplots@quiver@u/\vecnorm*\normmax}
            \pgfmathsetmacro\pgfplots@quiver@v{\pgfplots@quiver@v/\vecnorm*\normmax}
        \fi
    %%% end of our addendum
    \pgfplotsaxisparsecoordinate % nonsense
    \pgfplotsaxispreparecoordinate % nonsense
    \ifpgfplotsaxisparsecoordinateok
        % update limit ≈ update the bounding box
        \pgfplotsaxisupdatelimitsforcoordinate\pgfplots@current@point@x\pgfplots@current@point@y\pgfplots@current@point@z
        % the arrow are being shifted; too late to rescale
        \pgfmathadd@{\pgfplots@quiver@u}{\pgfplots@current@point@x}%
        \let\pgfplots@quiver@u=\pgfmathresult
        \pgfmathadd@{\pgfplots@quiver@v}{\pgfplots@current@point@y}%
        \let\pgfplots@quiver@v=\pgfmathresult
        \pgfplotsifcurplotthreedim{% 3d?
            \pgfmathadd@{\pgfplots@quiver@w}{\pgfplots@current@point@z}%
            \let\pgfplots@quiver@w=\pgfmathresult
        }{}%
        % update limit ≈ update the bounding box
        \ifpgfplots@quiver@updatelimits
            \pgfplotsaxisupdatelimitsforcoordinate\pgfplots@quiver@u\pgfplots@quiver@v\pgfplots@quiver@w
        \fi
    \fi
    \pgfplotsaxisdatapointsurveyed % nonsense
}%


\begin{tikzpicture}
    \begin{axis}[,view={0}{90}]
        \addplot3+[samples=15,->,black,%restrict u to domain=0:10,
        quiver={
            u={  2*y / (x^2+y^2)},
            v={ -2*x / (x^2+y^2)},
            scale arrows=1,
        },
        ]{0};
    \end{axis}
\end{tikzpicture}
\end{document}

2
  • Is it also possible to omit the too large vectors instead normalizing them?
    – student
    Commented Mar 29, 2020 at 21:29
  • Perhaps set both u and v to zero or nan.
    – Symbol 1
    Commented Mar 29, 2020 at 22:44

You must log in to answer this question.

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