π¨ Generative Art: Five Mathematical Visualizations
Mathematical functions, when rendered visually, reveal stunning hidden geometry. From 3D wave-driven bar fields to psychedelic interference grids, these five plots demonstrate how pure equations can produce compelling art.
Each subplot below is generated entirely from NumPy and Matplotlib — no external data, just mathematics.
π’ The Five Charts at a Glance
The full figure is a 1 × 5 subplot layout rendered at 20 × 8 inches. Each panel targets a different mathematical structure:
| # | Chart Name | Core Math | Colormap |
|---|---|---|---|
| 1 | 3D Bar Chart | 3 + 2sin(2.2u) + 2cos(2.8v) | cool |
| 2 | Radial Vortex | Spiral: ΞΈ + 1.5r | plasma |
| 3 | Color-Interference | sin(2x² + 2y²)·cos(2xy) | Custom psychedelic |
| 4 | Isosurface Contours | sin(1.5X)cos(1.5Y) + sin(0.5X)sin(0.8Y) | gist_earth |
| 5 | Noise Topography | Fractal Brownian motion mimic | Black contour lines |
π 1. 3D Patterned Bar Chart
A 15 × 15 grid of bars is generated using a meshgrid, then heights are computed from a wave equation: top = 3 + 2sin(2.2u) + 2cos(2.8v), where u and v are normalized coordinates centered at the grid. Bar colors map height values through the cool colormap, creating a smooth cyan-to-magenta gradient.
ax.bar3d() with shade=True and per-bar color array
derived from plt.cm.cool(top / max(top)).
π 2. Radial Vortex
Twenty concentric rings (radii 0.1 → 0.9) are subdivided into 60 angular steps.
Each step spawns a rotated Rectangle patch with spiral distortion applied as
ΞΈ' = ΞΈ + 1.5r. Width scales as 0.06(1.1 - r) and
height as 0.015r, making inner rectangles wider and outer ones taller,
reinforcing the vortex depth illusion.
angle=degrees(ΞΈ') + 45,
giving each tile an angled tilt that drives the swirling effect.
π¬ 3. Color-Interference Grid
A 40 × 40 grid of Circle patches is drawn over a black background.
Each circle's radius and color are driven by the interference value
val = sin(2x² + 2y²) · cos(2xy), normalized to
[0, 1]. A custom colormap transitions through
#00F0FF → #FF007F → #FFAA00 (cyan, magenta, amber),
producing a vivid psychedelic moirΓ©.
π️ 4. Isosurface Contours
A surface is computed over a 100 × 100 meshgrid on
[-3, 3]^2 using layered sine/cosine:
Z = sin(1.5X)cos(1.5Y) + sin(0.5X)sin(0.8Y).
The plot_surface call uses stride 3 with alpha 0.8 and the gist_earth
colormap, while ax.contour() projects level curves onto the floor at
z_{min} - 0.5.
Surface + Floor Contours
Full 5-Panel Layout
πΊ️ 5. Perlin Noise Topography
The final panel mimics fractal Brownian motion over a 150 × 150 grid on [-5, 5]^2 using three octaves:
- Octave 1 (amplitude 1.0): sin(X)cos(Y)
- Octave 2 (amplitude 0.5): sin(2X)sin(2Y)
- Octave 3 (amplitude 0.25): cos(4X)cos(4Y)
The result is plotted as 18 black contour lines (linewidths=1.2) on a white background,
evoking a topographic survey map with clean, high-contrast readability.
⚙️ Reproduction Code
The full figure is assembled with a single plt.figure(figsize=(20, 8)) call.
Run the snippet below to reproduce all five panels:
numpy, matplotlib (including
mpl_toolkits.mplot3d). No external datasets required.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, Circle
from matplotlib.colors import LinearSegmentedColormap
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(20, 8), facecolor="white")
# --- 1. 3D Bar Chart ---
ax1 = fig.add_subplot(1, 5, 1, projection='3d')
_x = np.arange(15); _y = np.arange(15)
X, Y = np.meshgrid(_x, _y)
x, y = X.ravel(), Y.ravel()
u = (x - 7.5) / 5.0; v = (y - 7.5) / 5.0
top = 3 + 2 * np.sin(2.2 * u) + 2 * np.cos(2.8 * v)
ax1.bar3d(x, y, np.zeros_like(top), 0.7, 0.7, top,
shade=True, color=plt.cm.cool(top / np.max(top)))
ax1.set_title("3D Bar Chart", fontsize=12, pad=10); ax1.axis('off')
# --- 2. Radial Vortex ---
ax2 = fig.add_subplot(1, 5, 2)
ax2.set_aspect('equal'); ax2.set_facecolor('white')
for r in np.linspace(0.1, 0.9, 20):
for theta in np.linspace(0, 2*np.pi, 60):
ct = theta + 1.5 * r
rect = Rectangle(
(r*np.cos(ct) - 0.03*(1.1-r), r*np.sin(ct) - 0.0075*r),
0.06*(1.1-r), 0.015*r,
angle=np.degrees(ct)+45,
facecolor=plt.cm.plasma(r), edgecolor='none')
ax2.add_patch(rect)
ax2.set_xlim(-1,1); ax2.set_ylim(-1,1)
ax2.set_title("Radial Vortex", fontsize=12, pad=10); ax2.axis('off')
# --- 3. Color-Interference ---
ax3 = fig.add_subplot(1, 5, 3)
ax3.set_aspect('equal'); ax3.set_facecolor('black')
cmap = LinearSegmentedColormap.from_list("psych",["#00F0FF","#FF007F","#FFAA00"])
for x in np.linspace(-2, 2, 40):
for y in np.linspace(-2, 2, 40):
val = (np.sin(2*x**2+2*y**2)*np.cos(2*x*y)+1)/2
ax3.add_patch(Circle((x,y), 0.04*val+0.01,
facecolor=cmap(val), edgecolor='none'))
ax3.set_xlim(-2.2,2.2); ax3.set_ylim(-2.2,2.2)
ax3.set_title("Color-Interference", fontsize=12, pad=10); ax3.axis('off')
# --- 4. Isosurface Contours ---
ax4 = fig.add_subplot(1, 5, 4, projection='3d')
X,Y = np.meshgrid(np.linspace(-3,3,100), np.linspace(-3,3,100))
Z = np.sin(X*1.5)*np.cos(Y*1.5) + np.sin(X*0.5)*np.sin(Y*0.8)
ax4.plot_surface(X,Y,Z,rstride=3,cstride=3,cmap='gist_earth',alpha=0.8,edgecolor='none')
ax4.contour(X,Y,Z,zdir='z',offset=Z.min()-0.5,cmap='gist_earth',linewidths=0.8)
ax4.set_zlim(Z.min()-0.5, Z.max()+0.5)
ax4.set_title("Isosurface Contours", fontsize=12, pad=10); ax4.axis('off')
# --- 5. Noise Topography ---
ax5 = fig.add_subplot(1, 5, 5)
ax5.set_aspect('equal')
X,Y = np.meshgrid(np.linspace(-5,5,150), np.linspace(-5,5,150))
Z = (np.sin(X)*np.cos(Y) + 0.5*np.sin(2*X)*np.sin(2*Y)
+ 0.25*np.cos(4*X)*np.cos(4*Y))
ax5.contour(X,Y,Z,levels=18,colors='black',linewidths=1.2)
ax5.set_title("Noise Topography", fontsize=12, pad=10); ax5.axis('off')
plt.tight_layout()
plt.savefig("generative_art.png", dpi=150, bbox_inches='tight')
plt.show()
⏭️ Next Steps
Future extensions could replace the fBm mimic with true Perlin or Simplex noise via the
noise library, animate the vortex and interference panels using
FuncAnimation, or export each subplot as an individual SVG for web embedding.
No comments:
Post a Comment