How do you plot the Riemann Zeta function using Tikz/Pgfplot?

I would like to plot the Riemann Zeta function for real values of x. Is this possible? I understand it's probably a long shot that it's been incorporated into it.

• Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. – darthbith Jan 3 '15 at 23:10
• Also for x<1? – percusse Jan 4 '15 at 1:55
• Yes, although if i can get it for x>1 then I can use this for x<1 – Daniel Jan 4 '15 at 10:25

There is, to my knowledge, no zeta function incorporated into LaTeX so you'll need the skill level of one of the LaTeX whizzes here (plus a chunk of time) to get it done with pure LaTeX---it's not the right tool for the job. There's an easier way: since the pgfplots package just needs a list of coordinates to plot let a computer algebra system handle the calculations and then "paste" them into where the coordinates are needed. That can be done quickly and easily using the `sagetex' package which gives you access to the computer algebra system Sage. Because it's specifically built to handle mathematics Sage has built in support for lots of functions, including the zeta function. Here's 2 ways to plot the zeta function in 35 lines:

\documentclass{article}
\usepackage{sagetex}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{pgfplots}
\begin{document}
\begin{sagesilent}
t = var('t')
LowerY = -4
UpperY = 5
LowerX = -3
UpperX = 3
step = .01
x_coords = [t for t in srange(LowerX,UpperX,step)]
y_coords = [zeta(t).n(digits=6) for t in srange(LowerX,UpperX,step)]

output = r""
output += r"\begin{tikzpicture}[scale=.7]"
output += r"\begin{axis}[xmin=%f,xmax=%f,ymin= %f,ymax=%f]"%(LowerX,UpperX,LowerY, UpperY)
output += r"\addplot[thin, blue, unbounded coords=jump] coordinates {"
for i in range(0,len(x_coords)-1):
if (y_coords[i])<LowerY or (y_coords[i])>UpperY:
output += r"(%f , inf) "%(x_coords[i])
else:
output += r"(%f , %f) "%(x_coords[i],y_coords[i])
output += r"};"
output += r"\end{axis}"
output += r"\end{tikzpicture}"
\end{sagesilent}
\begin{center}
\sagestr{output}
\end{center}
\begin{center}
\sageplot[width=6cm]{plot(zeta(x), (x, -3, 3),ymin=-4, ymax=5,detect_poles=True)}
\end{center}
\end{document}

To use the sagetex package you need Sage installed on your computer. The easiest way to get started is with a (free) Sagemath Cloud account. There can be problems with calling Sage when you're in the tikzpicture environment, like I did in my answer here, so it's best to avoid that by typesetting the entire tikzpicture text inside the sagesilent environment. The code is based on the viewing window parameters you give it: LowerY, UpperY, LowerX, UpperX. x_coords gets the values from -3 to 3 stepping .01. y_coords uses Sage and calculates zeta of each of those values. You only want to plot the values in your window so if a y value is too big or too small the code sets the y value to inf (for infinity). Otherwise the value is in the viewing window so we create coordinate without adjustment. The option "unbounded coords=jump" is going to jump over the discontinuities (so that the graph becomes disconnected). After creating the picture, we insert it into the document using \sagestr{output}.

If you don't require tikz/pgfplots then using Sage's plotting ability gives the plot in trivial fashion: \sageplot[width=6cm]{plot(zeta(x), (x, -3, 3),ymin=-4, ymax=5,detect_poles=True)}

The detect_poles=True is tells Sage to not connect the plot if it looks like there is a discontinuity. Copy/paste the code above into Sagemath Cloud to get this: Because a computer algebra system is being used it is trivial to change the function from zeta(x) to something else and the code will still work.

Another possibility is to use an external drawing program/language close to LaTeX, with adequate computational ability, such as MetaPost or Asymptote. Here is my quick try (for x>1), using MetaPost and LuaLaTeX, since MetaPost happens to be tightly integrated to LuaTeX via the mplib library (and it is the language I'm the most fluent in ;-)).

\documentclass[12pt]{scrartcl}
\usepackage{unicode-math}
\usepackage{luamplib}
\mplibsetformat{metafun}
\mplibnumbersystem{double}
\mplibtextextlabel{enable}
\everymplib{%
verbatimtex
\leavevmode
etex;
% "Riemann sum" (heavily inspired by Herbert Voss's Lua code)
vardef riemann_sum(expr x, epsilon) =
save k, y, dy;
y = 0; k = 1;
forever:
dy := 1/(k**x);
y := y + dy; k := k + 1;
exitif abs(dy) < epsilon;
endfor;
y
enddef;
%
% Riemann curve (also heavily inspired by Herbert's Lua code)
vardef riemann_curve(expr xs, xf, n, epsilon) =
save k, x, dx;
dx = (xf-xs)/n;
(xs, riemann_sum(xs, epsilon))
for x= xs+dx step dx until xf:
-- (x, riemann_sum(x, epsilon))
endfor
enddef;
%
beginfig(1);
}
\everyendmplib{endfig;}
\begin{document}
\begin{center}
\begin{mplibcode}
% For scaling
u := 0.8cm; b = 14;
% Riemann curve between 1.01 and b = 14, with n = 100 and epsilon = 1e-6
draw riemann_curve(1.01, b, 100, 1e-6) xyscaled u withcolor red;
% Axes
drawarrow (origin -- (b, 0)) xscaled u;
drawarrow (origin -- (0, b)) yscaled u;
% Marking and labels
eps := 3bp;
labeloffset := 6bp;
for x =  1 upto b-1:
draw (x*u, -eps)--(x*u, eps); label.bot(textext("$" & decimal(x) & "$"), (x*u, 0));
draw (-eps, x*u)--(eps, x*u); label.lft(textext("$" & decimal(x) & "$"), (0, x*u));
endfor;
label.llft("$O$", origin);
label.bot("$s$", (b*u, 0));
label.lft("$\zeta$", (0, b*u));
\end{mplibcode}
\end{center}
\end{document} MetaPost could also have been used externally, as well as Asymptote. Another possibility would be to make use of some Lua code in LuaLaTeX. By the way, my MetaPost program was heavily inspired by Herbert Voss' lua coding in its answer to this somewhat close subject.