31

I want to plot $y = 2^x$ over a small domain. Unfortunately, even though tikz (v 2.1) seems to be able to calculate 2^{negative numbers} it is not plotting them correctly.

My minimal example is:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
The value of $2^{-1}$ is \pgfmathparse{pow(2,-1)}\pgfmathresult.
\begin{tikzpicture}
\draw[thick,->] (-2,0) -- (2,0) node[right]{$x$};
\draw[thick,->] (0,0) -- (0,5) node[above]{$y$};
\draw[blue,domain=-2:2] plot (\x,{exp(ln(2)*\x)});
\draw[red,domain=-2:2] plot (\x,{pow(2,\x)});
\end{tikzpicture}
\end{document}

The red and blue graphs should be identical, and they are for the very first point (x = -2) and all the non-negative values, but there seems to be some problem with the plotting algorithm that means there is a bizarre kink to make the red graph almost symmetrical.

Output of above code with tikz 2.1, texlive 2010

Is this a known problem, and if so, has it been fixed in later versions of tikz?

5
  • 2
    I had done a similar diagram and it ran perfectly with TexLive2009 but when I changed to TeXLive2011 it gave output like yours. Your code works with TeXLive 2009 also. Sounds like a bug; I ended doing the diagram with PS Tricks (pst-plot).
    – DJP
    Oct 17, 2011 at 2:59
  • Plotting this with pgfplots works fine, which is probably a more convenient way of plotting functions than using "raw" TikZ.
    – Jake
    Oct 17, 2011 at 5:40
  • 1
    It's good to know that it works on pgfplots, but I'd prefer not to go with that workaround for the moment because the graph in question is part of something bigger that I've built on top of TikZ, so I'd like to make sure the underlying package is rock solid.
    – bryn
    Oct 17, 2011 at 9:10
  • 1
    Please don't use JPG for non-photographic images. Jan 21, 2018 at 13:44
  • @AndreasRejbrand it makes perfect sense to use JPEG also for 2D colour plots of noisy data. Just not for anything with exact lines. May 11, 2018 at 17:31

2 Answers 2

25

Yes, as Leo Liu said, this is fixed in the CVS version. The change was made in revision 1.5 of pgfmathfunctions.basic.code.tex.

If you don't want to install the CVS version, you could also just include the new version of the offending exp function by including the following code in your preamble:

% fixed exp function.
%
\makeatletter
\let\pgfmath@function@exp\relax % undefine old exp function
\pgfmathdeclarefunction{exp}{1}{%   
  \begingroup
    \pgfmath@xc=#1pt\relax
    \pgfmath@yc=#1pt\relax
    \ifdim\pgfmath@xc<-9pt
      \pgfmath@x=1sp\relax
    \else
      \ifdim\pgfmath@xc<0pt
        \pgfmath@xc=-\pgfmath@xc
      \fi
      \pgfmath@x=1pt\relax
      \pgfmath@xa=1pt\relax
      \pgfmath@xb=\pgfmath@x
      \pgfmathloop%
        \divide\pgfmath@xa by\pgfmathcounter
        \pgfmath@xa=\pgfmath@tonumber\pgfmath@xc\pgfmath@xa%
        \advance\pgfmath@x by\pgfmath@xa
      \ifdim\pgfmath@x=\pgfmath@xb
      \else
        \pgfmath@xb=\pgfmath@x
      \repeatpgfmathloop%
      \ifdim\pgfmath@yc<0pt
        \pgfmathreciprocal@{\pgfmath@tonumber\pgfmath@x}%
        \pgfmath@x=\pgfmathresult pt\relax
      \fi
    \fi
    \pgfmath@returnone\pgfmath@x%
  \endgroup
}
\makeatother

Alternatively, using pgfplots for plotting the function works flawlessly out of the box.

3
  • I'm a bit surprised about this because the exp function is actually the one that is exhibiting the correct behaviour, whereas the pow function is doing the wrong thing within a plot command. I'm not sure why pow(a,b) isn't just defined in terms of exp anyway, and I find it even more bizarre that the pow(...,...) would work within a pgfmathparse but not within a plot.
    – bryn
    Oct 17, 2011 at 9:12
  • 1
    @bryn: The pow function does use the exp function internally, but only for non-integer values. If you try \pgfmathparse{pow(2,-0.5)}\pgfmathresult you'll get the same (wrong) result, 1.41, which is the same as 2^0.5. You can also see what happens when you plot \draw[red,domain=-2:2,samples=9] plot (\x,{pow(2,\x)});: Some of the samples are integers, and the function evaluates fine there. The problem arises because the minus sign is lost when pow calls exp (an expansion problem). You could also fix the problem by changing some code in the pow function, but this way is cleaner.
    – Jake
    Oct 17, 2011 at 11:50
  • The CVS diff link is broken.
    – tambre
    Mar 3, 2018 at 10:32
7

I use TeX Live 2011 with CVS version of pgf package. The result is OK. Thus I think the bug has been fixed.

See tlcontrib to get the CVS version of pgf in TeX Live.

And for MiKTeX, you may go to sourceforge to check out latest pgf.

0

You must log in to answer this question.

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