LoginSignup
0
1

More than 1 year has passed since last update.

Pythonistaで綺麗なハート💛をプロット

Last updated at Posted at 2021-07-25

はじめに

ふと美しい数式をプロットしたくなり、美しい数式を眺めていたら、綺麗なハート型になる数式を見つけた。
その数式をPythonでプロットしてみることにした。
なんとなくスマホですっとハートを出せるようにしたくなったため、Pythonistaで動作するように作成した。

実装方針

元となる数式について

描きたい数式:
$$(x^2 + y^2 - 1)^3 = x^2 y^3$$
これを$y$について解くと
$$y = \frac{1}{2}(x^\frac{2}{3} \pm \sqrt{x^\frac{4}{3} + 4 (1 - x^2)})$$
実数の平方根は正であるから、$x^\frac{4}{3} + 4 (1 - x^2) \ge 0$である。
これを解くと
$$-1.1390 \lessapprox x \lessapprox 1.1390$$

問題:Pythonistaで立方根を求めるnumpy.cbrtが使えない!

numpy.cbrtがimportできない場合に、cbrtの代わりとなるものを作りたい。
powで立方根自体は求められるが、引数が負数になるとエラーとなってしまう。
つまり、$x$が正($x\ge0$)のとき

pow(x, 1/3)

を返したい。また、$x$が負($x<0$)のとき

-pow(-x, 1/3)

を返したい。

numpy.ndarrayでは、x[条件式]で条件式を満たすものを抽出することができる。
すなわち、$x\ge0$のものを抽出する場合は以下のようになる。

x[x >= 0]

以上のことをまとめると、cbrtは以下のように書くことができる。

cbrt = lambda x: np.append(-pow(-x[x < 0], 1/3), pow(x[x >= 0], 1/3))

コード

"""ハート型をプロットする"""

import matplotlib.pyplot as plt
import numpy as np

# Pythonistaのnumpyではcbrtが使えないため
try:
    from numpy import cbrt
except ImportError:
    cbrt = lambda x: np.append(-pow(-x[x < 0], 1/3), pow(x[x >= 0], 1/3))


def numpy_heart():
    """ハート型をプロットする

    数式:(x^2 + y^2 - 1)^3 = x^2 * y^3
    yについて解いた数式:y = 1/2 * (x^(2/3) +- sqrt(x^(4/3) + 4 * (1 - x^2)))
    実数の平方根は正であるから、
    x^(4/3) + 4 * (1 - x^2) = 0の解が, x ~ +-1.1390であるため、
    xが+-1.1390の範囲を計算し、プロットする。
    """
    x = np.arange(-1.1390, 1.1391, 0.0001)
    y_sqrt = np.sqrt(x * cbrt(x) + 4 * (1 - np.power(x, 2)))
    y_positive = (np.power(cbrt(x), 2) + y_sqrt) / 2
    y_negative = (np.power(cbrt(x), 2) - y_sqrt) / 2
    plt.plot(x, y_positive, color="pink")
    plt.plot(x, y_negative, color="pink")
    plt.show()


def main():
    numpy_heart()

if __name__ == '__main__':
    main()

実行結果

実行結果のハート型のプロット画像

heart.png

参考文献

Heart Curve -- from Wolfram MathWorld

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1