Reading John Derbyshire's Prime Obsession and playing around with Python library matplotlib for a course project brought me to plotting Riemann zeta function. The function is defined as follows:


where s is a complex variable, thus s = a + bi. The real part of s, denoted by Re(s), is a; while the imaginary part, denoted by Im(s), is b.

Python library mpmath has implemented this function in zeta and zetazero. Here is an example of the function plot in the complex plane with Re(s) in the range [-10,10] and Im(s) in the range [-5,35]:

 >>> from mpmath import zeta, cplot  
 >>> cplot(zeta,[-10,10],[-5,35])  
The function zetazero computes the n-th nontrivial zero of the zeta function. The following figure shows 100 first non-trivial zero. As stated in the hypothesis, they have real part 1/2 (note: x-axis is the real part, y-axis is the imaginary part).
Let:
  • ζ(s) = v
  • Re(s) = 1/2
  • Im(s) in the range [0.1,50]
  • Re(v) = x
  • Im(v) = y
I plot the function value on 2D plane in this movie according to the growth of Im(s).
video

 import matplotlib.pyplot as plt  
 from numpy import arange  
 from mpmath import zeta  
   
 X = []  
 Y = []  
   
 for t in arange(0.1,50,0.1):  
      v = zeta(complex(0.5,t))  
      X.append(v.real)  
      Y.append(v.imag)  
   
 fig = plt.figure()  
 ax = fig.add_subplot(111)  
 ax.plot(X,Y)
 ax.set_xlabel("Re(v)")
 ax.set_ylabel("Im(v)")  
 plt.show()  

Ok, I hope this post can be useful for someone somewhere. I learn mostly from here and here.