2

I want to plot the function 1/(x²+y²), but since it tends to infinity in (0,0), I get a horrible plot:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[grid=both]
    \addplot3 [surf] {1 / (x^2 + y^2)};
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

By restricting the domain of z, I get anyway a not so nice plot:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[grid=both,restrict z to domain=0:1]
    \addplot3 [surf] {1 / (x^2 + y^2)};
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

I would like to get something smooth, which finish in a circle (the circle of the intersection of this function with the plane z=1 for example).

Something like this would be great:

enter image description here

  • For that I think you need a different parametrization of the surface. Otherwise you will get that sampling behavior. – percusse Oct 10 '16 at 20:41
  • 1
    But there may be a way to intersect this surface with the plane z=1, and "hide" what is above it, or something like that... – Alejandro DC Oct 10 '16 at 20:52
  • That's not how meshing is performed. – percusse Oct 10 '16 at 21:42
  • 1
    You also need to set zmax to a value less than that used by [restrict z to domain]. The way it works, the plot is clipped at zmax, but you need additional points outside the plot to interpolate the edges. – John Kormylo Oct 11 '16 at 14:35
  • That is a really good tip. I am trying, but I am not sure how to add the additional points outside the plot, because the zmax goes in the option of the axis, not of the addplot3, and hence, anything I add outside that limit, will be clipped out. – Alejandro DC Oct 11 '16 at 14:55
8

After hours (at least one) of trying to make what is written in the first plot, I thought of polar coordinates. It works.

\documentclass{scrartcl}
    \usepackage{tikz}
    \usepackage{pgfplots}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}[width=\textwidth,
    axis equal,
    xmin=-0.1,xmax=5,ymin=-0.5,ymax=3,zmin=-0.4,zmax=7,
    xtick=\empty,ytick=\empty,ztick=\empty,
    axis lines=center]

    \addplot3[surf,opacity=0.5,domain=0.4:2.2,y domain=0:360,samples=40]
    ({x*cos(y)+3}, {x*sin(y)+2}, {1/(x^2)});
    \end{axis}
    \end{tikzpicture}
\end{document}

enter image description here

  • 1
    Fantastic, that's a great approach. Thanks for posting, and welcome to the site! – Jake Nov 30 '16 at 16:53
7

pgfplots supports the "starred" version restrict z to domain* which clips all bigger values into the prescribed domain. The result is a closed cap on top:

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.14}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[grid=both,restrict z to domain*=0:10]
    \addplot3 [surf,samples=51,
        domain=-2:2,miter limit=1] {1 / (x^2 + y^2)};
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

Here is the same with 71 samples:

enter image description here

4

Here's a possibility using the sagetex package and a (free) SagemathCloud account giving you access to a computer algebra system Sage for your LaTeX document. The idea is to generate the data points and for "large" z-values redefine the point to be the maximum z-value on the graph.

\documentclass[11pt,border={10pt 10pt 10pt 10pt}]{standalone}
\usepackage{pgfplots}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
x = var('x')
y = var('y')
step = .10
x1 = -2
x2 = 2
y1 = -2
y2 = 2
output = ""
output += r"\begin{tikzpicture}[scale=1.0]"
output += r"\begin{axis}[xmin=%d, xmax=%d, ymin=%d, ymax=%d]"%(x1,x2,y1,y2-step)
output += r"\addplot3[surf,mesh/rows=%d] coordinates {"%((y2-step-y1)/step+1)
# rows is the number of y values
for y in srange(y1,y2,step):
    for x in srange(x1,x2,step):
        if (1/(x^2+y^2))<10:
            output += r"(%f, %f, %f) "%(x,y,1/(x^2+y^2))
        else:
            output += r"(%f, %f, %f) "%(x,y,10)
output += r"};"
output += r"\end{axis}"
output += r"\end{tikzpicture}"
\end{sagesilent}
\sagestr{output}
\end{document}

Running in SagemathCloud you get this output: enter image description here

If you don't mind MetaPost output, the Function Grapher can easily do something similar :

enter image description here

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.