Today is March 14th, which coincidentally represents the first three digits of the mathematical constant $\pi$. Therefore, the mathematics community has designated this day as $\pi$ Day.
$\pi$ is perhaps the most famous irrational number, and exploration of $\pi$ has never ceased. To date, with the help of computers, we have calculated $\pi$ to $31.4$ trillion decimal places! This record was set by a Japanese programmer from Google named Haruka Iwao. It is said that the calculation program ran on $25$ virtual machines for $121$ days, involving $170$ TB of data, ultimately achieving an accuracy of $31.4$ trillion decimal places for $\pi$.
Calculating the precision of $\pi$ has also been a method to measure computational power, a practice that began with John von Neumann. To this day, many mathematicians are tirelessly studying various properties of $\pi$, with some even believing that the digits of $\pi$ contain the ultimate secrets of the universe. Today, I will use Python to visualize $\pi$ and see what astonishing patterns might emerge.
Ideas
First of all, I downloaded the first 1 million decimal places of $\pi$ from the internet and saved them in a text file. The data is arranged with 50 digits per line, and it looks like this:
14159265358979323846264338327950288419716939937510
58209749445923078164062862089986280348253421170679
82148086513282306647093844609550582231725359408128
48111745028410270193852110555964462294895493038196
44288109756659334461284756482337867831652712019091
45648566923460348610454326648213393607260249141273
72458700660631558817488152092096282925409171536436
Then I will visualize these $10$ digits $[0-9]$ using certain rules. Currently, I have $2$ ideas:
- Dot Diagram: Assign a color to each of the $10$ digits $[0-9]$, and then draw dots sequentially.
- Line Diagram: Assign a color and an angle to each of the $10$ digits $[0-9]$, and draw connected line segments.
Dot Diagram
It is not complicated to draw dot diagram. First, define dot colors:
# Dot outline colors
color = ['gold', 'goldenrod', 'red', 'firebrick', 'mediumvioletred', 'darkorchid', 'royalblue', 'lightseagreen', 'mediumseagreen', 'olivedrab']
# Dot fill colors
color_fill = ['khaki', 'moccasin', 'lightcoral', 'lightsalmon', 'orchid', 'mediumpurple', 'skyblue', 'aquamarine', 'lightgreen', 'palegreen']
Then use the numbers $[0-9]$ as the color index to get dot color. The code to draw a single dot is as follows:
def draw_dot(n: int, c: int):
""" Draw dots
:param n: number in the place
:param c: place in the decimal part
:return: None
"""
t.color(color_fill[n])
t.begin_fill()
t.circle(10)
t.end_fill()
t.color(color[n])
t.circle(10)
pos = t.pos()
After drawing a dot, the turtle moves to the next position, and here I set it to break line each 40 dots:
def move(c: int):
""" Mode to next position
:param c: place in the decimal part
:return: None
"""
pos = t.pos()
t.penup()
if c % 40 == 0: #break line each 40 dots
t.goto(-600, pos[1] - 30)
else:
t.goto(pos[0] + 30, pos[1])
t.pendown()
Finally, we just read the decimal part of $\pi$ and draw the dots in a loop.
import turtle
turtle.setup(1.0, 1.0)
t = turtle.Turtle()
t.hideturtle()
t.pensize(2)
t.penup()
t.goto(-600, 400)
t.pendown()
t.speed(0)
# Draw dot 3 to represent the integer part
count = 1
num = 3
draw_dot(num, count)
move(count)
# Loop drawing decimal parts
with open('top-1-million-digits-of-pi.txt') as f:
for i in range(28): # draw 28*50=1400 dots
word = f.readline().strip()
for a in word:
num = int(a)
count += 1
draw_dot(num, count)
move(count)
f.close()
turtle.done()
Let's take a look at the final result.
Line Diagram
With a basic understanding of dot diagram, drawing line diagram is relatively simple. Here's the code directly:
import turtle
turtle.setup(1.0, 1.0)
t = turtle.Turtle()
t.hideturtle()
t.pensize(2)
t.pendown()
t.left(90)
t.speed(0)
color = ['gold', 'goldenrod', 'red', 'firebrick', 'mediumvioletred', 'darkorchid', 'royalblue', 'lightseagreen', 'mediumseagreen', 'greenyellow']
# Draw dot 3 to represent the integer part
last_num = 3
t.color(color[last_num])
t.right(last_num * 36)
t.forward(40)
# Loop drawing decimal parts
with open('top-1-million-digits-of-pi.txt') as f:
for i in range(100):
word = f.readline().strip()
for a in word:
current_num = int(a)
t.color(color[current_num])
angle = (current_num - last_num) * 36
t.right(angle)
t.forward(20)
last_num = current_num
f.close()
turtle.done()
Let's take a look at the final result.
Conclusion
How is it? Amazing, right? If you have any better ideas for visualization, feel free to leave a comment and share.
Finally, Happy $\pi$ Day to everyone!