I have a graph drawn using tikzpicture and even though I've increased the resolution there are still gaps in the graph itself.

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[domain=-{sqrt(2)}:{sqrt(2)}]
    \draw[very thin,color=gray] (-1.2,-1.2) grid (1.2,1.2);
    \draw[<->] (-1.7,0) -- (1.7,0) node[right] {$x$};
    \draw[<->] (0,-1.3) -- (0,1.3) node[above] {$y$};
    \draw[color=red]  plot [samples=100](\x,{abs(\x)*sqrt(2 - \x*\x)});
    \draw[color=green]  plot [samples=100] (\x,{-abs(\x)*sqrt(2 - \x*\x)});
\end{tikzpicture}
\end{document}

This produces:

Example Graph Print Out

You can see just either side of the x-axis on the right, the green part of the graph doesn't meet with the red part. I'm allowing the package to calculate the domain boundaries. If this is the problem, I can't step outside them because of the nature of the domain in the first place.

Curiously enough, when I increased the resolution from 100 to 1000, the gap got bigger.

  • 1
    I would really consider to use pgfplots for this purpose. – Claudio Fiandrino Sep 25 '13 at 6:21
  • @ Claudio Fiandrino Why? How? – Geoff Pointer Sep 25 '13 at 6:27
  • Because it is a dedicated package for plots, so start with the manual and browse pgfplots questions here. – Claudio Fiandrino Sep 25 '13 at 6:30
  • 1
    If you reduce samples and use smooth as in \draw[color=green] plot [smooth,samples=20] (\x,{-abs(\x)*sqrt(2 - \x*\x)});, they meet. But better use pgfplots. – user11232 Sep 25 '13 at 6:48
  • 3
    @GeoffPointer: well, pgfplots is built on top of TikZ specifically for plots (it automatically handles a number of things: legends, ticks, type of axis and so on). It's impossible to use pgfplots without TikZ for that reason: you can fairly consider pgfplots an extension of TikZ. For the manual, when you have doubts, browse on CTAN, in this case the pgfplots entry. – Claudio Fiandrino Sep 25 '13 at 8:12
up vote 9 down vote accepted

If you use a parametric representation of the curve (i.e. [sqrt(2)*sin(x), sin(2*x)]), you can plot it precisely to the extrema.

Here I've used PGFPlots, and also plotted your original equation in gray underneath the parametric representation:

\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
    domain=-pi/2:pi/2, % The range over which to evaluate the functions
    xtick={-1,...,1}, ytick={-1,...,1}, % Tick marks only on integers between -1 and 1
    axis lines=middle, % Axis lines go through (0,0)
    enlargelimits=true, % Make the axis lines a bit longer than required for the plots
    samples=101, % Number of samples for evaluating the functions (use an odd number to capture the (0,0) point
    xlabel=$x$, ylabel=$y$, % Axis labels
    clip=false % So the labels aren't cut off
]
\addplot [thick, red]
    ( {sqrt(2) * sin(deg(x))},
      {abs(sin(deg(x*2)))} )
    node [pos=0.8, anchor=south] {$f(x) = |x|\sqrt{2-x^2}$}; % Add a text node at 80% of the plot length
\addplot [thick, blue]
    ( {sqrt(2) * sin(deg(x))},
      {-abs(sin(deg(x*2)))} )
    node [pos=0.8, anchor=north] {$f(x) = -|x|\sqrt{2-x^2}$};

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

About the underlying problem: The problem is not solved by using PGFPlots (but I would still recommend PGFPlots for plots like this). Also, while using a parametric equation for functions like this will typically lead to better results because of the more even sampling along the plot, that's also not the root cause. The problem occurs because of numerical errors when deciding where to sample the domain, which causes the last sampling point (sqrt(2)) to be skipped. At it's core, it's the problem discussed in Why doesn't TikZ's \foreach iterate over the last element of the list?. In this context, a good solution would be to patch the function that generates the sampling expression to explicitly include the upper edge of the domain. By putting the following in your preamble (after \usepackage{tikz}), your original code will work without a gap:

\makeatletter
\def\tikz@plot@samples@recalc#1:#2\relax{%
  \pgfmathsetmacro\tikz@temp@start{#1}%
  \pgfmathsetmacro\tikz@temp@end{#2}%
  \pgfmathsetmacro\tikz@temp@step{(\tikz@temp@end-\tikz@temp@start)/(\tikz@plot@samples-1)}%
  \pgfmathsetmacro\tikz@temp@second{\tikz@temp@start+\tikz@temp@step}%
  \pgfmathsetmacro\tikz@temp@penultimate{\tikz@temp@end-\tikz@temp@step}
  \ifdim\tikz@temp@penultimate pt<\tikz@temp@second pt
    \edef\tikz@plot@samplesat{\tikz@temp@start,\tikz@temp@second,...,\tikz@temp@end}%  
  \else%
    \edef\tikz@plot@samplesat{\tikz@temp@start,\tikz@temp@second,...,\tikz@temp@penultimate,\tikz@temp@end}%
  \fi%
}
\makeatother

  • That is indeed a nice looking graph. Would you mind adding some quick tips on labelling it, that is the axis labels and a label of the equation? I promise to spend some time studying the pgf Manual as suggested. – Geoff Pointer Sep 25 '13 at 7:53
  • Also, is there a quick answer for why pgf plots are better than plotting in a tikzpicture? – Geoff Pointer Sep 25 '13 at 8:03
  • 2
    @GeoffPointer: I've edited my answer to show how to generate labels, and I've commented the code a bit. As Claudio said, PGFPlots is based entirely on TikZ/PGF (TikZ is the higher level interface to the basic PGF graphics framework), so you can mix TikZ commands with PGFPlots. Using PGFPlots for plotting is typically more comfortable than using plain TikZ, because it takes care of the scaling of the values and makes it easy to add legends and axes, and it has options for more advanced things like logarithmic and polar plots. – Jake Sep 25 '13 at 8:33
  • The elephant in the room in this discussion is that your suggestion to use a parameterisation has removed the gaps. It's not so much that using pgfplots has solved my problem. Is the problem to do with the vertical tangents at the extremes of the domain that the parameterisation is avoiding? Or what? The discussion hasn't yet actually specified what the problem is. – Geoff Pointer Sep 29 '13 at 15:28
  • 1
    @GeoffPointer: You're right, PGFPlots doesn't solve the problem. I didn't mean to imply that, sorry if that was unclear. I would still recommend to use PGFPlots instead of plain TikZ. Also, using a parametric equation doesn't solve the problem, but it's still a good idea for functions like this. I've edited my answer to include an explanation and fix of the actual, underlying problem. – Jake Sep 29 '13 at 18:38

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.