SymPy Plotting Backends で塗りつぶし

以下のページの塗りつぶしパートの加筆修正用に。

ライブラリの import

必要なライブラリを import します。

In [1]:
from sympy import *
# 1文字変数の Symbol の宣言が省略できる
from sympy.abc import *
# 虚数単位,円周率,ネイピア数
from sympy import I, pi, E
# SymPy Plotting Backends (SPB)
from spb import *

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

領域の塗りつぶし

2本の陽関数で挟まれた領域を塗りつぶす

ここでは,plot_implicit() を使って,$x$ 軸($y = 0$)と $y = f(x)$ で挟まれた領域を塗りつぶしてみます。

$0.5 \leq x \leq 2$ で $0 \leq y \leq f(x)$ の領域を塗りつぶす例。

In [2]:
def f(x):
    return 0.6*x + 0.4*cos(x)
In [3]:
# 0 <= y <= f(x) の領域を 0.5 <= x <= 2 の範囲で塗りつぶす
# plot_implicit() の場合は x の範囲と y の範囲が必要
plot_implicit(
    (0 <= y) & (y <=f(x)), 
    # 塗りつぶす x の範囲
    (x, 0.5, 2), 
    # 不等式が満たされているかを探す y の範囲
    (y, -0.1, 1.2), 
    adaptive=True, # これをつけないと警告が出る
    # グラフの表示範囲
    xlim = (-0.2, 2.5), ylim = (-0.2, 1.5), 
    # 塗りつぶしの色
    color='yellow'
);

いくつかオプションを指定して描く例。

$x$ 軸 $y$ 軸を表示します。
デフォルトのグリッド線が少し目障りな場合は,以下のように細めの灰色点線にして目立たないようにすることもできます。

In [4]:
# y = f(x) を 0.25 <= x <= 2.25 の範囲で描く
p1 = plot(
    f(x), (x, 0.25, 2.25), 
    # 凡例。$ で囲まれた部分は latex 記法
    "$f(x)$", 
    xlim = (-0.2, 2.5), ylim = (-0.2, 1.5),
    show = False # 後でまとめて表示
) 

# 0 <= y <= f(x) の領域を 0.5 <= x <= 2 の範囲で塗りつぶす
# plot_implicit() の場合は x の範囲と y の範囲が必要
p2 = plot_implicit(
    (0 <= y) & (y <=f(x)), 
    (x, 0.5, 2), (y, -0.2, 1.5), 
    # 凡例。$ で囲まれた部分は latex 記法
    "$0 \leq y \leq f(x)$", 
    adaptive=True, # これをつけないと警告が出る
    xlim = (-0.2, 2.5), ylim = (-0.2, 1.5), color='yellow',
    show = False # 後でまとめて表示
) 

# 2つのグラフを重ねて
p = p1 + p2
ax = p.ax
# グリッドを細めの灰色点線で
ax.grid(which="major", color="lightgray", dashes=(3, 3), linewidth=0.5)
# x軸 y軸
ax.axhline(0, color='black', dashes=(3, 3), linewidth=0.6)
ax.axvline(0, color='black', dashes=(3, 3), linewidth=0.6);

多角形の内部を塗りつぶす

plot_geometry(Polygon()) を使って,$(0, 0)$ を中心とし,「半径」(中心から頂点までの距離)が $2$ の正四角形 $n=4$(正方形)を描く例。

In [5]:
plot_geometry(
    #       中心, 半径,頂点の数
    Polygon((0, 0), 2,   n=4), 
    # グリッドは無しに
    grid = False,
    # 塗りつぶさない
    is_filled=False
);

In [6]:
# デフォルトでは内部を塗りつぶす
plot_geometry(
    #       中心, 半径,頂点の数
    Polygon((0, 0), 2,   n=4), 
    grid = False
);

In [7]:
# 頂点の x, y 座標を指定して描く例
p1, p2, p3, p4 = [(0, 0), (1, 0), (1, 1), (0, 1)]

plot_geometry(
    Polygon(p1, p2, p3, p4), 
    # 塗りつぶしの色
    {'color':'yellow'}
);

円の内部を塗りつぶす

plot_geometry(Circle()) を使って,$(0, 0)$ を中心とし,半径が $1$ の円を描く。

In [8]:
# 原点 (0, 0) を中心とした半径 1 の円
plot_geometry(
    Circle((0, 0), 1), 
    grid = False, 
    # 塗りつぶさない
    is_filled=False 
);

In [9]:
# デフォルトでは内部を揺りつぶす
plot_geometry(
    Circle((0, 0), 1), 
    # 縁の色を赤に
    {'edgecolor':'red'}, 
    grid = False
);

coloredgecolor の同時設定

本稿執筆時点では,以下のように edgecolorcolor を両方設定しようとしてもうまくいかないようだ。

In [10]:
plot_geometry(
    Circle((0, 0), 1), {'edgecolor':'red', 'color':'yellow'}
);

どうしてもというのであれば,以下のように別々に作成して重ねて表示させるという方法があるだろう。

In [11]:
# 円のみを赤色の線で
en1 = plot_geometry(
    Circle((0, 0), 1), {'color':'red'}, 
    grid = False, legend = False, is_filled=False, 
    show=False
)

# 円の内部を黄色で塗りつぶす
en2 = plot_geometry(
    Circle((0, 0), 1), {'color':'yellow'}, 
    grid = False, legend = False, 
    show=False
)

# 重ねて表示
(en1 + en2).show();

円の内部が $ x^2 + y^2 \leq 1$ であることから,plot_implicit() を使って塗りつぶすこともできます。

In [12]:
plot_implicit(
    x**2 + y**2 <=1, (x, -1, 1), (y, -1, 1), 
    # color は塗りつぶす色,border_color は縁の線の色
    color="yellow", border_color="red",
    xlim = (-1.1, 1.1), ylim = (-1.1, 1.1),
    aspect = "equal", grid = False);

扇形の内部を塗りつぶす

まず扇形を,円周の一部と原点からの2本の直線で囲まれた領域と考えて縁のグラフを描く。

In [13]:
# 円の一部を媒介変数表示で
p1 = plot_parametric(
    cos(t), sin(t), (t, pi/6, pi/3), {"color":"black"},
    xlim = (-1.1, 1.1), ylim = (-1.1, 1.1), 
    grid = False, legend = False, 
    aspect = "equal", use_cm = False, show = False)

# 2本の直線
p2 = plot_list(
    ([0, cos(pi/6)], [0, sin(pi/6)], {"color":"black"}), 
    ([0, cos(pi/3)], [0, sin(pi/3)], {"color":"black"}), show = False)

# 重ねて表示
(p1+p2).show();

扇形の内部を,

\begin{eqnarray}
x^2 + y^2 &\leq& 1 \\
y &\geq& \tan\frac{\pi}{6} \ x \\
y &\leq& \tan\frac{\pi}{3} \ x
\end{eqnarray}

を満たす領域として,plot_implicit() で塗りつぶします。

In [14]:
p3 = plot_implicit(
    (x**2+y**2 <= 1) & (tan(pi/6)*x <= y) & (y <= tan(pi/3)*x), 
    (x, 0, 1), (y, 0, 1), legend = False, 
    color = "yellow", 
    adaptive=True, # これをつけないと警告が出る
    # グラフの表示範囲
    xlim = (-1.1, 1.1), ylim = (-1.1, 1.1), 
    aspect = "equal", grid = False
);

縁の線も重ねて表示。

In [15]:
(p1+p2+p3).show();