# How to plot the function x^2+xy+2 using PGFPlots

I would like to plot z=x^2+xy+2.

Here is what I want:

However, I can not make the surface prettier.

MWE:

\documentclass{article}
\usepackage[a4paper,margin=1in,footskip=0.25in]{geometry}

\usepackage{pgfplots}
\pgfplotsset{compat=1.15}
\pgfplotsset{soldot/.style={color=black,only marks,mark=*}}

\begin{document}

\begin{center}
\begin{tikzpicture}[declare function={f(\x,\y)=\x*\x+\x*\y+2;}]
\begin{axis} [
axis on top,
axis lines=center,
xlabel=$x$,
ylabel=$y$,
zlabel=$z$,
ticklabel style={font=\tiny},
legend pos=outer north east,
legend style={cells={align=left}},
legend cell align={left},
view={135}{25}
]
\addplot3[surf,domain=0:10,domain y=0:5,restrict z to domain=0:6,samples=61,samples y=61] {x*x+x*y+2};
\addlegendentry{$$z=x^2+xy+2$$}
\addlegendentry{$$r$$}
\addlegendentry{$$\vec X$$}
\addplot3[soldot] coordinates {(1,2,5)} node[above right] {$A$};
\addplot3[soldot] coordinates {(9,4,3)} node[left] {$r\cap\vec X$};
\end{axis}
\end{tikzpicture}
\end{center}

\end{document}


EDIT. Thanks to the marmot's useful comment I could make it look better:

\documentclass{article}
\usepackage[a4paper,margin=1in,footskip=0.25in]{geometry}

\usepackage{pgfplots}
\pgfplotsset{compat=1.15}
\pgfplotsset{soldot/.style={color=black,only marks,mark=*}}
\begin{document}

\begin{center}
\begin{tikzpicture}[declare function={f(\x,\y)=\x*\x+\x*\y+2;}]
\begin{axis} [
axis on top,
axis lines=center,
xlabel=$x$,
ylabel=$y$,
zlabel=$z$,
zmax=6,
ticklabel style={font=\tiny},
legend pos=outer north east,
legend style={cells={align=left}},
legend cell align={left},
view={135}{25}
]
\addlegendentry{$$z=x^2+xy+2$$}
\addlegendentry{$$r$$}
\addlegendentry{$$\vec X$$}
\addplot3[soldot] coordinates {(1,2,5)} node[above right] {$A$};
\addplot3[soldot] coordinates {(9,4,3)} node[left] {$r\cap\vec X$};
\end{axis}
\end{tikzpicture}
\end{center}

\end{document}


However, I would like the graphic to have the color palette (all blue is not quite right).

Thanks!!

• If you drop restrict z to domain=0:6 the result looks much better. Why did you add this restriction? – user121799 Feb 27 at 0:08
• @marmot oh, I thought it was almost always necessary. It looks much better, thanks! Now we have to think about the domain of the other variables. – manooooh Feb 27 at 0:11
• @marmot the first image was the output of z=x^2+xy+2 made with Geogebra. If you want to use parametric expressions or change of variables go ahead. – manooooh Feb 27 at 0:16
• @marmot well, it is just a surface! Go to WolframAlpha: wolframalpha.com/input/?i=x%5E2%2Bxy%2B2 or see this not zoomed image: imgur.com/a/4KRVoRx. – manooooh Feb 27 at 0:21
• My previous comment was wrong. The independent linear combinations are different. Sorry! – user121799 Feb 27 at 0:44

Your plot function is a quadratic form, which can be diagonalized by a basis transformation, which in this case is a rotation by 22.5 degrees. In the rotated basis it is easier to plot the function.

\documentclass{article}
\usepackage[a4paper,margin=1in,footskip=0.25in]{geometry}

\usepackage{pgfplots}
\pgfplotsset{compat=1.15}
\pgfplotsset{soldot/.style={color=black,only marks,mark=*}}
\begin{document}

\begin{center}
\begin{tikzpicture}[declare function={f(\x,\y)=\x*\x+\x*\y+2;}]
\begin{axis} [
axis on top,
axis lines=center,
xlabel=$x$,
ylabel=$y$,
zlabel=$z$,
zmax=6,
ticklabel style={font=\tiny},
legend pos=outer north east,
legend style={cells={align=left}},
legend cell align={left},
view={135}{25}
]
%           {x*x+x*y+2};
buffer=sort,point meta=z]
({cos(22.5)*x-sin(22.5)*y},{cos(22.5)*y+sin(22.5)*x},{(4 + (1 + sqrt(2))*x*x - (-1 + sqrt(2))*y*y)/2});

\addlegendentry{$$z=x^2+xy+2$$}
\addlegendentry{$$r$$}
\addlegendentry{$$\vec X$$}
\addplot3[soldot] coordinates {(1,2,5)} node[above right] {$A$};
\addplot3[soldot] coordinates {(9,4,3)} node[left] {$r\cap\vec X$};
\end{axis}
\end{tikzpicture}
\end{center}

\end{document}


Hiding the hidden part of the red line:

\documentclass{article}
\usepackage[a4paper,margin=1in,footskip=0.25in]{geometry}

\usepackage{pgfplots}
\pgfplotsset{compat=1.15}
\pgfplotsset{soldot/.style={color=black,only marks,mark=*}}
\begin{document}

\begin{center}
\begin{tikzpicture}[declare function={f(\x,\y)=\x*\x+\x*\y+2;}]
\begin{axis} [
axis on top,
axis lines=center,
xlabel=$x$,
ylabel=$y$,
zlabel=$z$,
zmax=6,
ticklabel style={font=\tiny},
legend pos=outer north east,
legend style={cells={align=left}},
legend cell align={left},
view={135}{25}
]
%           {x*x+x*y+2};
buffer=sort,point meta=z]
({cos(22.5)*x-sin(22.5)*y},{cos(22.5)*y+sin(22.5)*x},{(4 + (1 + sqrt(2))*x*x - (-1 + sqrt(2))*y*y)/2});

\addlegendentry{$$z=x^2+xy+2$$}
\addlegendentry{$$r$$}
\addlegendentry{$$\vec X$$}
\addplot3[soldot] coordinates {(1,2,5)} node[above right] {$A$};
\addplot3[soldot] coordinates {(9,4,3)} node[left] {$r\cap\vec X$};
\end{axis}
\end{tikzpicture}
\end{center}

\end{document}


Here is how you could restrict the plot. Compute the a function xcrit(y) that determines what x must be for a given y such that the function has a certain constant value. Use this to clip the plot.

\documentclass{article}
\usepackage[a4paper,margin=1in,footskip=0.25in]{geometry}

\usepackage{pgfplots}
\pgfplotsset{compat=1.16,width=15cm}
\pgfplotsset{soldot/.style={color=black,only marks,mark=*}}
\begin{document}

\begin{center}
\begin{tikzpicture}[declare function={f(\x,\y)=\x*\x+\x*\y+2;
ftransformed(\x,\y)=(4 + (1 + sqrt(2))*\x*\x - (-1 + sqrt(2))*\y*\y)/2;
xcrit(\y,\c)=sqrt(-1 + sqrt(2))*sqrt(-4 + 2*\c +
(-1 + sqrt(2))*\y*\y);}]
\begin{axis} [
axis on top,
axis lines=center,
xlabel=$x$,
ylabel=$y$,
zlabel=$z$,
zmax=6,
ticklabel style={font=\tiny},
legend pos=outer north east,
legend style={cells={align=left}},
legend cell align={left},
view={135}{25}
]
%           {x*x+x*y+2};
\begin{scope}
\clip plot[variable=\y,domain=-6:6]
({-cos(22.5)*xcrit(\y,6)-sin(22.5)*\y},{cos(22.5)*\y-sin(22.5)*xcrit(\y,6)},{6})
-- ({-cos(22.5)*xcrit(6,6)-sin(22.5)*6},{cos(22.5)*6-sin(22.5)*xcrit(6,6)},{-10})
--({-cos(22.5)*xcrit(-6,6)+sin(22.5)*6},{-cos(22.5)*6-sin(22.5)*xcrit(-6,6)},{-10})
;
buffer=sort,point meta=z,forget plot]
({cos(22.5)*x-sin(22.5)*y},{cos(22.5)*y+sin(22.5)*x},{ftransformed(x,y)});
\end{scope}
\begin{scope}
\clip plot[variable=\y,domain=-7:7]
({cos(22.5)*xcrit(\y,6)-sin(22.5)*\y},{cos(22.5)*\y+sin(22.5)*xcrit(\y,6)},{6})
-- ({cos(22.5)*xcrit(7,6)-sin(22.5)*6},{cos(22.5)*6+sin(22.5)*xcrit(7,6)},{-10})
--({cos(22.5)*xcrit(-7,6)+sin(22.5)*6},{-cos(22.5)*6+sin(22.5)*xcrit(-7,6)},{-10})
;
buffer=sort,point meta=z]
({cos(22.5)*x-sin(22.5)*y},{cos(22.5)*y+sin(22.5)*x},{ftransformed(x,y)});
\end{scope}
%           \draw[thick,red] plot[variable=\y,domain=-5:5]
%            ({cos(22.5)*xcrit(\y,6)-sin(22.5)*\y},{cos(22.5)*\y+sin(22.5)*xcrit(\y,6)},{6});
\addlegendentry{$$z=x^2+xy+2$$}
\addlegendentry{$$r$$}
\addlegendentry{$$\vec X$$}
\addplot3[soldot] coordinates {(1,2,5)} node[above right] {$A$};
\addplot3[soldot] coordinates {(9,4,3)} node[left] {$r\cap\vec X$};
\end{axis}
\end{tikzpicture}
\end{center}
\end{document}


• WOW! You know more math than I thought :). This is an excellent answer, thanks! P.S. Do you know how to hide part of the two lines drawn behind the surface, so that it is more realistic? – manooooh Feb 27 at 1:07
• @manooooh You have to draw them in different steps... meaning one has to compute the intersections, draw the hidden stretches to the intersections, then the surface, and then the visible stretches. asymptote does that automatically. – user121799 Feb 27 at 1:16
• @manooooh Just looking and guessing: you need to just make the red line a bit shorter. \addplot3[red,thick,variable=\t,domain=0:3,samples y=0] ({1+4*t},{2+t},{5-t}); A is the intersection of the surface with the red line. – user121799 Feb 27 at 1:21
• @manooooh You could add your own clip like e.g. in tex.stackexchange.com/a/476772/121799. – user121799 Feb 27 at 4:31
• @manooooh Almost, please see my update. ;-) – user121799 Feb 27 at 5:06