Matplotlib で円弧や双曲線が張る面積の図を描く

円弧や双曲線が張る面積の図を Matplotlib だけで描く。以下の記事で使っているので。

In [1]:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np

# グラフを SVG で Notebook にインライン表示
%config InlineBackend.figure_formats = ['svg']

plt.rcParams['mathtext.fontset'] = 'cm'
# 本格的に full latex したいときには True に。ただし時間がかかる...
plt.rcParams["text.usetex"] = False
In [2]:
fig = plt.figure(figsize=[6.4, 6.4])
ax = fig.add_subplot(aspect='equal')
fig.tight_layout()

# 原点を中心とした半径 1 の円
en1 = patches.Circle(
        xy=(0, 0), 
        radius = 1, 
        fill=False, edgecolor="purple", linewidth=1)
ax.add_patch(en1)

# 円上の点 A の座標
xA = 1
yA = 0
# 点 A
plt.scatter([xA], [yA], zorder=10, c="k")
ax.text(xA+0.02, yA+0.04, r"$A\,(1, 0)$", 
        fontsize="xx-large", c='k')

# 円上の点 P の座標
xP = np.cos(np.radians(60))
yP = np.sin(np.radians(60))
# 点 P
plt.scatter([xP], [yP], zorder=10, c="k")
ax.text(xP+0.02, yP+0.02, r"$P\,(x, y)$", 
        fontsize="xx-large", c='k')

# 円の中心 O の座標
xO = 0
yO = 0
# 点 O
plt.scatter([xO], [yO], zorder=10, c="k")
ax.text(-0.08, -0.08, r"$O$", fontsize="xx-large", c='k')

# 直線 OA
plt.plot([0, xA], 
         [0, yA], c="k", linewidth=2)
# 直線 OP
plt.plot([0, xP], 
         [0, yP], c="k", linewidth=2)

# 点 P から y 軸への線
plt.plot([xP, 0 ],
         [yP, yP], ls = ':',lw=0.8, c="gray")
ax.text(-0.08, yP-0.02, r"$y$", fontsize="xx-large", c='k')

# 点 P から x 軸への線
plt.plot([xP, xP],
         [yP, 0 ], ls = ':',lw=0.8, c="gray")
ax.text(xP-0.02, -0.08, r"$x$", fontsize="xx-large", c='k')

# 角度 θ 部分
arc1 = patches.Arc(
        xy=(0, 0), width=0.18, height=0.18, 
        theta1=0, theta2=60, edgecolor="green", linewidth=1)
arc2 = patches.Arc(
        xy=(0, 0), width=0.2, height=0.2, 
        theta1=0, theta2=60, edgecolor="green", linewidth=1)
ax.add_patch(arc1)
ax.add_patch(arc2)
ax.text(0.1, 0.05, r"$\theta$", fontsize="xx-large", c='green')

# 円弧 AP
arcAP = patches.Arc(
        xy=(0, 0), width=2, height=2, 
        theta1=0, theta2=60, edgecolor="red", linewidth=3)
ax.add_patch(arcAP)

# ell
xl = np.cos(np.radians(30))
yl = np.sin(np.radians(30))
ax.text(xl+0.01, yl+0.01, r"$\ell = \theta$", fontsize="28", c='red')

# 表示範囲
ax.set_xlim(-1.4, 1.4)
ax.set_ylim(-1.1, 1.1)

# 目盛設定
ax.axis(False);

# x軸 y軸は dashed に
ax.axhline(0, c='k', ls = ':', lw=1)
ax.axvline(0, c='k', ls = ':', lw=1);
In [3]:
plt.rcParams["text.usetex"] = True
In [4]:
fig = plt.figure(figsize=[6.4, 6.4])
ax = fig.add_subplot(aspect='equal')
fig.tight_layout()

# 原点を中心とした半径 1 の円
en1 = patches.Circle(
        xy=(0, 0), 
        radius = 1, 
        fill=False, edgecolor="purple", linewidth=1)
ax.add_patch(en1)

# 円上の点 A の座標
xA = 1
yA = 0
# 点 A
plt.scatter([xA], [yA], zorder=10, c="k")
ax.text(xA+0.02, yA+0.04, r"$A\,(1, 0)$", 
        fontsize="xx-large", c='k')

# 円上の点 P の座標
xP = np.cos(np.radians(60))
yP = np.sin(np.radians(60))
# 点 P
plt.scatter([xP], [yP], zorder=10, c="k")
ax.text(xP+0.02, yP+0.02, r"$P\,(x, y)$", 
        fontsize="xx-large", c='k')

# 円の中心 O の座標
xO = 0
yO = 0
# 点 O
plt.scatter([xO], [yO], zorder=10, c="k")
ax.text(-0.08, -0.08, r"$O$", fontsize="xx-large", c='k')

# 直線 OA
plt.plot([0, xA], 
         [0, yA], c="k", linewidth=2)
# 直線 OP
plt.plot([0, xP], 
         [0, yP], c="k", linewidth=2)

# 点 P から y 軸への線
plt.plot([xP, 0 ],
         [yP, yP], ls = ':',lw=0.8, c="gray")
ax.text(-0.08, yP-0.02, r"$y$", fontsize="xx-large", c='k')

# 点 P から x 軸への線
plt.plot([xP, xP],
         [yP, 0.5 ], ls = ':',lw=0.8, c="gray")
plt.plot([xP, xP],
         [0.2, 0 ], ls = ':',lw=0.8, c="gray")
ax.text(xP-0.02, -0.08, r"$x$", fontsize="xx-large", c='k')

# 角度 θ 部分
arc1 = patches.Arc(
        xy=(0, 0), width=0.18, height=0.18, 
        theta1=0, theta2=60, edgecolor="green", linewidth=1)
arc2 = patches.Arc(
        xy=(0, 0), width=0.2, height=0.2, 
        theta1=0, theta2=60, edgecolor="green", linewidth=1)
ax.add_patch(arc1)
ax.add_patch(arc2)
ax.text(0.1, 0.05, r"$\theta$", fontsize="xx-large", c='green')

# 円弧 AP
arcAP = patches.Arc(
        xy=(0, 0), width=2, height=2, 
        theta1=0, theta2=60, edgecolor="red", linewidth=3)
ax.add_patch(arcAP)

# 扇形 OAP の塗りつぶし
wedge1 = patches.Wedge(center=(0, 0), r=1,
             theta1=0, theta2=60, 
             facecolor="yellow", zorder = 0)
ax.add_patch(wedge1)

# S, plt.rcParams["text.usetex"] = True が必要
ax.text(0.27, 0.3, r"$\displaystyle S=\frac{1}{2}\, \theta$", 
        fontsize="26", c='k')


# 表示範囲
ax.set_xlim(-1.4, 1.4)
ax.set_ylim(-1.1, 1.1)

# 目盛設定
ax.axis(False);

# x軸 y軸は dashed に
ax.axhline(0, c='k', ls = ':', lw=1)
ax.axvline(0, c='k', ls = ':', lw=1);
In [5]:
plt.rcParams["text.usetex"] = False
In [6]:
fig = plt.figure(figsize=[6.4, 6.4])
ax = fig.add_subplot(aspect='equal')
fig.tight_layout()

# 双曲線
t = np.linspace(-2,2)
plt.plot(np.cosh(t), np.sinh(t), c="purple", linewidth=1)
plt.plot(-np.cosh(t), np.sinh(t), c="purple", linewidth=1)

# 双曲線上の点 A の座標
xA = 1
yA = 0
# 点 A
plt.scatter([xA], [yA], zorder=10, c="k")
ax.text(xA+0.05, yA+0.07, r"$A\,(1, 0)$", 
        fontsize="xx-large", c='k')

# 双曲線上の点 P の座標
xP = np.cosh(1.3)
yP = np.sinh(1.3)
# 点 P
plt.scatter([xP], [yP], zorder=10, c="k")
ax.text(xP+0.07, yP-0.1, r"$P\,(x, y)$", 
        fontsize="xx-large", c='k')

# 原点 O
xO = 0
yO = 0
# 点 O
plt.scatter([xO], [yO], zorder=10, c="k")
ax.text(-0.25, -0.25, r"$O$", fontsize="xx-large", c='k')

# 直線 OA
plt.plot([0, xA], 
         [0, yA], c="k", linewidth=2)
# 直線 OP
plt.plot([0, xP], 
         [0, yP], c="k", linewidth=2)

# 点 P から y 軸への線
plt.plot([xP, 0 ],
         [yP, yP], ls = ':',lw=0.8, c="gray")
ax.text(-0.2, yP-0.02, r"$y$", fontsize="xx-large", c='k')

# 点 P から x 軸への線
plt.plot([xP, xP],
         [yP, 0 ], ls = ':',lw=0.8, c="gray")
ax.text(xP-0.07, -0.2, r"$x$", fontsize="xx-large", c='k')

# 曲線 AP
t = np.linspace(0, 1.3)
plt.plot(np.cosh(t), np.sinh(t), c="red", lw=3)

# S
x = np.linspace(0, 1)
ax.fill_between(x, np.tanh(1.3)*x, 0, facecolor="yellow")
x = np.linspace(1, xP)
ax.fill_between(x, np.tanh(1.3)*x, np.sqrt(x**2-1), facecolor="yellow")
ax.text(0.5, 0.15, r"$S$", fontsize="24", c='k')

# 表示範囲
ax.set_xlim(-2.8, 2.8)
ax.set_ylim(-2.5, 2.5)

# 目盛設定
ax.axis(False);

# x軸 y軸は dashed に
ax.axhline(0, c='k', ls = ':', lw=1)
ax.axvline(0, c='k', ls = ':', lw=1);