5

I'm trying to plot a simple sqrt(x) function and I get a weird looking one.

\documentclass{standalone}

\usepackage{tikz}
\usepackage{pgfplots}

\begin{document}
    \begin{tikzpicture}
        \begin{axis} [
        smooth, no markers, grid,
        domain=0:2,
        xmax=2, ymax=2,
        xmin=0, ymin=0]

        \addplot +[red] {x^2};
        \addplot +[blue]{sqrt(x)};
        \addplot {x};
        \end{axis}
    \end{tikzpicture}
\end{document}

I'm plotting it together with x^2 and what I get is clearly not the inverse function:

link

3 Answers 3

10

You can see why this happens if you remove no markers from the axis options. A quick fix is to have denser sampling near zero, with help from samples at. Personally I'd also not use smooth, the results aren't always that good.

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
    \begin{axis} [
    no markers, grid,
    domain=0:2,
    xmax=2, ymax=2,
    xmin=0, ymin=0]

    \addplot +[red,samples=50] {x^2};
    \addplot +[blue,samples at={0,0.001,0.005,0.01,...,0.2,0.3,0.4,...,2}]{sqrt(x)};
    \addplot +[samples=2] {x};
    \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

5
  • 2
    @jagjordi If the the sqrt function is too hard to plot near 0, one may also plot the disingenuous reciprocal \addplot +[blue,samples=50] ({x^2},{x});
    – marsupilam
    Jun 16, 2017 at 20:40
  • @marsupilam, as I stated in my answer this is the best way to fix the problem easily in an "automated" way. Could you transfer your comment to an answer please. Jun 16, 2017 at 21:43
  • Thanks for your answer, jut a quick question: what do the dots in {0.01,...,0.2,0.3} stand for? Thanks again
    – jagjordi
    Jun 17, 2017 at 14:19
  • 1
    @jagjordi It completes the sequence of numbers, same as in \foreach loops. E.g. 0.5,1.5,...,4 is the same as 0.5,1.5,2.5,3.5. More generally, in x, y, ..., z, x is the first number in the sequence, y is the second number, and y - x is the step. The sequence stops when it reaches z. Jun 17, 2017 at 14:40
  • @StefanPinnow Done !
    – marsupilam
    Jun 17, 2017 at 22:15
5

As Torbjørn states in his answer the key is to increase the sampling density around x=0. But to my personal view stating the x samples by hand (using samples at) is the most inelegant way.

The simplest (good) solution is given by marsupilam in the comment below Torbjørn's answer which he hopefully will transfer into a real answer.

Here I present a general way to get unequal spacing and the "inequality" can be changed by simple changing the constant a. Applying the same method on a much more complex equation can be found at https://tex.stackexchange.com/a/373820/95441.

% used PGFPlots v1.15
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
    \pgfplotsset{
        % use this `compat' level or higher to use Lua for calculations
        % (this is not required though)
        compat=1.12,
        /pgf/declare function={
            % declare the main function(s)
            f(\x) = sqrt(\x);
            % state (or calculate) the lower and upper boundaries (the domain values)
            lb = 0;
            ub = 2;
            %
            % -----------------------------------------------------------------
            %%% nonlinear spacing: <https://stackoverflow.com/a/39140096/5776000>
            % "non-linearity factor"
            a = 2;
            % function to use for the nonlinear spacing
            Y(\x) = exp(a*\x);
            % rescale to former limits
            X(\x) = (Y(\x) - Y(lb))/(Y(ub) - Y(lb)) * (ub - lb) + lb;
        },
    }
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        % just to show that also here the above constants/functions can be used
        xmin=lb,    xmax=ub,
        ymin=f(lb), ymax=ub,
        grid,
        % also use the constants for the domain, so there is only one place
        % where you need to change the values
        domain=lb:ub,
        smooth,
        no markers,     % <-- comment me to show where the x points are
    ]
        \addplot+ [mark=o]              {x^2};
        \addplot+ [samples=2]           {x};
        \addplot+ [mark=triangle,thick] {f(x)};
        \addplot+ [mark=square,green]   ({X(x)},{f(X(x))});
    \end{axis}
\end{tikzpicture}
\end{document}

image showing the result of above code

0
2

As requested by Stefan Pinnow, I expand my comment to an answer.

We just plot the original function x|->x^2 twice :

  • one normally,
  • and once after applying the x <-> y symetry of the plane. This is the graph of the reciprocal

The output is the same as other answers above.

Here, I changed the original function to showcase that it still works for non-bijective functions...

The output

enter image description here

The code

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
  [
    declare function= 
    {
      myFunction(\x) = .5*\x + sin(90 * \x);    % for demo
      %myFunction(\x) = \x^2;                   % your function
    },
  ]
  \begin{axis} 
    [
      unit vector ratio = 1 1,
      no markers,
      grid,
      domain=0:2,
      xmax=2,
      ymax=2,
      xmin=0,
      ymin=0,
      samples=50,
    ]

    \addplot +[red] {myFunction(x)}; % shortcut for ({x},{myFunction(x)});
    \addplot +[blue] ({myFunction(x)},{x});
    \addplot +[samples=2] {x};
  \end{axis}
\end{tikzpicture}
\end{document}

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.