codexriemann-sphere-reciprocal-cap.py
riemann-sphere-reciprocal-cap.py
"""An exterior, a sphere cap and a reciprocal disc; existing plotting dependencies."""
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Polygon
import numpy as np
def plane_axes(ax, limit, real, imag):
for end in [(limit, 0), (0, limit)]:
ax.annotate("", xy=end, xytext=(-end[0], -end[1]),
arrowprops={"arrowstyle": "->", "color": "#637380", "lw": 1})
ax.text(limit * .55, -limit * .12, real, fontsize=10)
ax.text(limit * .05, limit * .89, imag, fontsize=10)
ax.set(xlim=(-limit, limit), ylim=(-limit, limit), aspect="equal")
ax.axis("off")
def main():
plt.rcParams.update({"font.size": 12, "figure.facecolor": "white"})
fig, (zax, sax, wax) = plt.subplots(1, 3, figsize=(11.2, 4.7))
blue, orange = "#2367b1", "#bd581b"
zax.set_facecolor("#e6f0fc")
zax.add_patch(Polygon([(-3.1, -3.1), (3.1, -3.1), (3.1, 3.1), (-3.1, 3.1)],
facecolor="#e6f0fc", edgecolor="none", zorder=0))
zax.add_patch(Circle((0, 0), 2, facecolor="white", edgecolor=blue, linestyle="--", lw=1.8))
plane_axes(zax, 3.1, r"Re$(z)$", r"Im$(z)$")
zax.scatter([2], [1], color=orange, s=45, zorder=5)
zax.annotate("$2+i$", (2, 1), xytext=(5, 9), textcoords="offset points", color=orange)
zax.text(-.36, -.49, "$0$")
zax.text(-2.83, -2.7, "Exterior continues outward", fontsize=10, color=blue)
zax.set_title("$z$ chart: $|z|>2$", pad=18)
theta = np.linspace(0, 2 * np.pi, 500)
sax.fill(np.cos(theta), np.sin(theta), color="#f3f6fa")
cap_theta = np.linspace(np.arcsin(.6), np.pi - np.arcsin(.6), 200)
sax.fill(np.cos(cap_theta), np.sin(cap_theta), color="#e6f0fc")
sax.plot(np.cos(theta), np.sin(theta), color="#65788c", lw=1.5)
sax.plot([-.8, .8], [.6, .6], color=blue, linestyle="--", lw=1.8)
sax.axhline(0, color="#a5b0ba", lw=.8)
sax.scatter([0], [1], s=40, color=blue, zorder=5)
sax.text(-.37, 1.1, r"$N=\infty$")
sax.annotate("$Z=3/5$", (.8, .6), xytext=(.64, .21),
arrowprops={"arrowstyle": "-", "color": blue}, color=blue)
sax.text(-.61, -.15, "equatorial plane", fontsize=10)
sax.text(-.62, -.85, "$S$ ($z=0$)", fontsize=11)
sax.text(-.74, -1.31, "Meridian section of the cap", fontsize=10)
sax.set(xlim=(-1.25, 1.25), ylim=(-1.45, 1.38), aspect="equal")
sax.set_title("Sphere: $Z>3/5$", pad=18)
sax.axis("off")
wax.add_patch(Circle((0, 0), .5, facecolor="#e6f0fc", edgecolor=blue, linestyle="--", lw=1.8))
plane_axes(wax, .72, r"Re$(w)$", r"Im$(w)$")
wax.scatter([0], [0], s=40, color=blue, zorder=5)
wax.text(-.28, .08, "$w=0$\n(infinity)", fontsize=10, color=blue)
wax.scatter([.4], [-.2], color=orange, s=45, zorder=5)
wax.annotate("$(2-i)/5$", (.4, -.2), xytext=(.1, -.63),
arrowprops={"arrowstyle": "-", "color": orange}, color=orange)
wax.set_title("$w=1/z$ chart: $|w|<1/2$", pad=18)
fig.suptitle("One neighbourhood of infinity, three geometric views", fontsize=16, y=.98)
fig.text(.5, .065, "Blue shading is included. Dashed boundaries are excluded. Positive Im(z) becomes negative Im(w).",
ha="center", fontsize=11)
fig.subplots_adjust(left=.035, right=.98, top=.81, bottom=.16, wspace=.24)
fig.savefig(Path(__file__).stem + ".png", dpi=120, facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()