Full Code Alchemist ::: 耶郎 ::: avatar

Visualizing Pi and the Golden Ratio: Mathematical Art in Python

gamer00

Published: 05 Nov 2024 › Updated: 05 Nov 2024Visualizing Pi and the Golden Ratio: Mathematical Art in Python

Visualizing Pi and the Golden Ratio: Mathematical Art in Python

Today, I realized that while Pi has been turned into musical notes before, I’d never seen it represented as visual art.


First try: first 64 digits, 500 steps

So I decided to whip up a Python script that will do just that. When I was brainstorming this, I added Golden Ratio to the bunch, because hey, that's an endlessly repeating number too, or at least its digits are, just like with Pi!

In a nutshell, my script calculates both Pi and Golden Ratio, up to as many digits I set in num_digits with a freely adjustable start_position, then it iterates through those digits, calculates an angle, and draws a line after each angle. num_segments decides how many steps, or lines the script will draw.

To make things more interesting, I set the Golden Ratio as the colours of the lines. So in between each step, a colour hue will be chosen based on the current digit of the Golden Ratio, similarly to the angle with the Pi.

I then made a copy of the original script, with direction_digit and color_digit swapped, so I could also create images based on Golden Ratio, with colours set by Pi.


Golden Ratio visualization

I was quite surprised of how the pictures turned out. I didn't expect them to be so fractal-like (although not exactly fractals) and organic. I really like the results!


Golden Ratio — Pi colours — 150000 segments


Pi — colours decided by Golden Ratio — 150000 segments

I need to change the colour algorithm to something else, hopefully making it a bit more pleasing to the eye. Anyway. I hope you liked these, and I'll leave you with the code, here:

# pi.py

import numpy as np
from matplotlib import pyplot as plt
from mpmath import mp

# Parameters for calculating constants
num_digits = 128  # Number of digits to use
start_position = 25  # Starting position to the sequence

# Set the precision in mpmath for arbitrary-length calculations
mp.dps = (
    num_digits + start_position + 1
)  # Set precision slightly higher to ensure enough digits

# Convert Pi and Golden Ratio to strings and remove the decimal point
# I thohought this might be a better form than the previous where I removed "3." and "1.".
# This'll mean the rotation of the pictures produced by this new script slightly differ from originals.
pi_digits = str(mp.pi).replace('.', '')[start_position:start_position + num_digits]
golden_ratio_digits = str(mp.phi).replace('.', '')[start_position:start_position + num_digits]

# Drawing Parameters
num_segments = 1500  # Total number of line segments to draw
segment_length = 0.05  # Length of each line segment
angle_step = 36  # Degree step per Pi digit for direction (0-360°)
hue_step = 36  # Degree step per Golden Ratio digit for color in HSV

# Starting point and angle_step
x, y = 0.5, 0.5  # Start in the middle of a 1x1 canvas
current_angle = 0.

# Set up the plot
fig, ax = plt.subplots()
ax.set_aspect("equal")
ax.axis("off")  # Turn off the axis for a cleaner look

# Define the color map explicitly
color_map = plt.get_cmap("hsv")

# Drawing loop
for i in range(num_segments):
    # Get current direction and color digits
    direction_digit = int(pi_digits[i % len(pi_digits)])
    color_digit = int(golden_ratio_digits[i % len(golden_ratio_digits)])

    # Calculate the new angle for direction
    current_angle += direction_digit * angle_step

    # Calculate the hue for color, wrapping around 360 degrees
    hue = (color_digit * hue_step) % 360  # Changed to 360 for a full color range

    # Convert hue to RGB color for plotting
    color = color_map(hue / 360.0)  # Normalized hue for HSV colormap

    # Calculate endpoint of the line segment
    dx = segment_length * np.cos(np.radians(current_angle))
    dy = segment_length * np.sin(np.radians(current_angle))
    new_x, new_y = x + dx, y + dy  # Define new_x and new_y

    # Plot the line segment
    ax.plot(
        [x, new_x], [y, new_y], color=color, linewidth=0.75
    )  # Corrected "color" to "color"

    # Update the current position
    x, y = new_x, new_y

# Show the final plot
plt.show()

One minor gripe... Speaking of “Colours”, I hate it that I must use color instead of colour everywhere in my code, because the libraries use American spelling. Yes, I could use aliases and variable names, but for some reason it just confuses me to have both color and colour in the code, so I eventually ended doing :%s/colour/color/g, and now the code is in all-American style. But I still hate it.

Heh. It was fun. Did you like this? Comments below!

Leave Visualizing Pi and the Golden Ratio: Mathematical Art in Python to:

Written by

Gaming, FLOSS, Arts, Photography, Weiqi/Go/Baduk... All photos are my own unless otherwise specified.

Read more #programming posts


Best Posts From Full Code Alchemist ::: 耶郎 :::

We have not curated any of gamer00's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From Full Code Alchemist ::: 耶郎 :::