Skip to content

Domain Coloring in Python using Matplotlib #788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions contents/domain_coloring/code/python/domain_coloring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
from matplotlib.cm import ScalarMappable


def f(z):
return z**2


def magnitude_shading(f_val):
f_val_abs = np.abs(f_val)
return 0.5 + 0.5 * (f_val_abs - np.floor(f_val_abs))


def gridlines(f_val, threshold):
return (np.abs(np.sin(np.pi * np.real(f_val))) ** threshold
* np.abs(np.sin(np.pi * np.imag(f_val))) ** threshold)


def color(f_val, threshold):
hue = (np.pi - np.angle(f_val)) / (2.0 * np.pi)
saturation = magnitude_shading(f_val)
value = gridlines(f_val, threshold)

# Currently we have a tuple of 2D-arrays (hue, saturation, value).
# This makes it a 2D-array of tuples, which the conversion function requires.
hsv = np.moveaxis((hue, saturation, value), 0, -1)
return matplotlib.colors.hsv_to_rgb(hsv)


if __name__ == "__main__":
# Create a new figure containing a single plot
fig, axes = plt.subplots(1, 1)

# Set the title for the plot
axes.set_title("$f(x)=z^2$")

# Create color bar
cbar = fig.colorbar(
ScalarMappable(matplotlib.colors.Normalize(0.0, 2.0 * np.pi), "hsv"),
ax=axes,
label="Phase Angle")

# Set x and y labels
axes.set_xlabel("$Re(z)$")
axes.set_ylabel("$Im(z)$")

# Set color bar tick locations and labels
cbar.set_ticks([0.0, np.pi, 2.0 * np.pi])
cbar.set_ticklabels(["$0.0$", "$\pi$", "$2\pi$"])

# Hide x and y ticks
for tick in axes.get_xticklines():
tick.set_visible(False)

for tick in axes.get_yticklines():
tick.set_visible(False)

# Create a 500x500 input grid
coords = np.linspace(-2.0, 2.0, 500)
z_real, z_imag = np.meshgrid(coords, coords)
z = z_real + 1j * z_imag

# Calculate function values
f_val = f(z)

# Map function values to colors
colors = color(f_val, 0.1)

# Plot the colors
# extent=(-2.0, 2.0, -2.0, 2.0) sets the x and y ranges
# origin="lower" places index (0,0) of the color array in the lower-left corner
# aspect="equal" ensures that the plot is square
axes.imshow(
colors,
extent=(-2.0, 2.0, -2.0, 2.0),
origin="lower",
aspect="equal")

# Save output
fig.savefig("domain.png")
2 changes: 2 additions & 0 deletions contents/domain_coloring/domain_coloring.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ Here is the full script to generate a domain colored output of $$f(z)=z^2$$.
{% method %}
{% sample lang="gnuplot" %}
[import, lang:"gnuplot"](code/gnuplot/domain_coloring.gp)
{% sample lang="python & matplotlib" %}
[import, lang:"python"](code/python/domain_coloring.py)
{% endmethod %}

### Bibliography
Expand Down