質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

4193閲覧

ある関数から法線を求め,その傾き値(度表記)の求め方

mdshiba2

総合スコア21

Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/12/12 07:43

編集2018/12/13 09:08

前提・実現したいこと

python 初心者です.
関数z(x)を微分して法線を求め,その法線の傾き値(度表記)を求めようとしています.
また,傾き値はその座標値(a,z(a))の値で変化すると思いますが,aが0.1間隔で0から6まで変化した分だけの情報(すばわち60個分の傾き値)が欲しいです.
下図がイメージです.

イメージ説明

発生している問題・エラーメッセージ

インターネットなどでやり方を探しているのですが,初心者ということもあり,やり方がわかりません.

該当のソースコード

Python

1 2#傾き値の取得 3 4import numpy as np 5import matplotlib.pyplot as plt 6 7# 描画範囲の指定 8# x = np.arange(x軸の最小値, x軸の最大値, 刻み) 9x = np.arange(0, 6.28, 0.1) 10 11plt.grid(True) 12plt.xlabel('$x$', fontsize=16) 13plt.ylabel('$Z$', fontsize=16) 14plt.title('upper die') 15 16#縦横比1:1 17plt.gca().set_aspect('equal', adjustable='box') 18 19R=-19.41053 20k=-59.85017 21c=1/R 22 23from sympy import Symbol, Derivative 24#xを変数xに指定 25x=Symbol('x') 26 27#関数入力 28z=-(c*x**2/(1+(1-(1+k)*c**2*x**2)**(1/2)) 29#入力関数を指定変数で微分 30Z=Derivative(z,x).doit() 31 32# 横軸の変数。縦軸の変数。 33plt.plot(x,Z) 34 35# 描画実行 36plt.show() 37 38np.savetxt("points.csv", np.vstack([x, Z]).T, delimiter=",")

微分を行うところまでは,teratailユーザーのご協力もあり出来ましたが,ここから先,行き詰っています.
知識のある方,ご協力をお願い致します.

編集後

Python

1#法線の角度を求める 2 3import matplotlib.pyplot as plt 4import numpy as np 5from sympy import * 6from sympy import Derivative, Symbol, N 7 8 9 10# xを変数xに指定 11x = Symbol('x') 12z = -(c*x**2/(1+(1-(1+k)*c**2*x**2)**(1/2)) 13 14prime_z = Derivative(z, x).doit() 15 16a = Symbol('a') 17z_a = z.subs(x, a) # f(a) 18prime_z_a = prime_z.subs(x, a) # 点 (a, f(a)) の傾き 19tangent = prime_z_a * (x - a) + z_a # 点 (a, f(a)) の接線 20normal = (-1 / prime_z_a) * (x - a) + z_a # 点 (a, f(a)) の法線 21theta = deg(atan(-1 / prime_z_a)) # 法線の角度 22print('{} degree'.format(theta.evalf(subs={a: x, prime_z_a: x}))) 23 24# x, theta の点一覧を作成する。 25xs = np.arange(0, 6.28, 0.1) 26thetas = [theta.evalf(subs={x: v}) for v in xs] 27 28# 描画する。 29fig, ax = plt.subplots(figsize=(7, 7)) 30plt.grid(True) 31plt.xlabel('$x$', fontsize=16) 32plt.ylabel('$θ$', fontsize=16) 33plt.title('upper die') 34plt.plot(xs, thetas) 35plt.show() 36 37np.savetxt("points.csv", np.vstack([xs,thetas]).T, delimiter=",")

を入力すると,

>>> # 描画する。 ... fig, ax = plt.subplots(figsize=(7, 7)) >>> plt.grid(True) >>> plt.xlabel('$x$', fontsize=16) Text(0.5,0,'$x$') >>> plt.ylabel('$θ$', fontsize=16) Text(0,0.5,'$\x83\xc6$') >>> plt.title('upper die') Text(0.5,1,'upper die') >>> plt.plot(xs, thetas) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Users\owner\Anaconda3\envs\python3.6\lib\site-packages\matplotlib\pyplot.py", line 3363, in plot ret = ax.plot(*args, **kwargs) File "C:\Users\owner\Anaconda3\envs\python3.6\lib\site-packages\matplotlib\__init__.py", line 1867, in inner return func(ax, *args, **kwargs) File "C:\Users\owner\Anaconda3\envs\python3.6\lib\site-packages\matplotlib\axes\_axes.py", line 1529, in plot self.add_line(line) File "C:\Users\owner\Anaconda3\envs\python3.6\lib\site-packages\matplotlib\axes\_base.py", line 1960, in add_line self._update_line_limits(line) File "C:\Users\owner\Anaconda3\envs\python3.6\lib\site-packages\matplotlib\axes\_base.py", line 1982, in _update_line_limits path = line.get_path() File "C:\Users\owner\Anaconda3\envs\python3.6\lib\site-packages\matplotlib\lines.py", line 956, in get_path self.recache() File "C:\Users\owner\Anaconda3\envs\python3.6\lib\site-packages\matplotlib\lines.py", line 657, in recache y = _to_unmasked_float_array(yconv).ravel() File "C:\Users\owner\Anaconda3\envs\python3.6\lib\site-packages\matplotlib\cbook\__init__.py", line 2052, in _to_unmasked_float_array return np.asarray(x, float) File "C:\Users\owner\Anaconda3\envs\python3.6\lib\site-packages\numpy\core\numeric.py", line 501, in asarray return array(a, dtype, copy=False, order=order) File "C:\Users\owner\Anaconda3\envs\python3.6\lib\site-packages\sympy\core\expr.py", line 225, in __float__ raise TypeError("can't convert expression to float") TypeError: can't convert expression to float >>> plt.show()

この様なエラーが出てしまいます.

補足情報(FW/ツールのバージョンなど)

python3.6を使用しています.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2018/12/12 08:09 編集

数学である点の法線を求めたり、画像中の角度を求めるやり方はご存知ですか? つまり、sympy の使い方の質問なのか、それとも数学の話なのか、わからないのはどちらでしょうか?
mdshiba2

2018/12/12 08:50

数学的にはわかっております。プログラムの書き方(sympyの使い方になるのでしょうか)、がわからない状態ですm(__)m
guest

回答1

0

ベストアンサー

点 (a, f(a) における法線の傾きは - 1 / f'(a) なので、

tanθ = - 1 / f'(a) の関係から角度を求めればよいかと思います。

法線の角度を求める。

python

1import matplotlib.pyplot as plt 2import numpy as np 3from sympy import * 4 5# xを変数xに指定 6x = Symbol('x') 7y = log(x) 8prime_y = Derivative(y, x).doit() 9a_val = 0.5 # a の値 10 11a = Symbol('a') 12y_a = y.subs(x, a) # f(a) 13prime_y_a = prime_y.subs(x, a) # 点 (a, f(a)) の傾き 14tangent = prime_y_a * (x - a) + y_a # 点 (a, f(a)) の接線 15normal = (-1 / prime_y_a) * (x - a) + y_a # 点 (a, f(a)) の法線 16theta = deg(atan(-1 / prime_y_a)) # 法線の角度 17print('{} degree'.format(theta.evalf(subs={a: a_val}))) 18# -26.5650511770780 degree

結果を描画する。

python

1# x, y の点一覧を作成する。 2xs = np.linspace(0.001, 5, 100) 3ys = [y.evalf(subs={x: t}) for t in xs] 4tangent_ys = [tangent.evalf(subs={x: t, a: a_val}) for t in xs] 5normal_ys = [normal.evalf(subs={x: t, a: a_val}) for t in xs] 6# 描画する。 7fig, ax = plt.subplots(figsize=(7, 7)) 8# 表示範囲の設定 9ax.set_xlim(0, 5) 10ax.set_ylim(-5, 5) 11ax.axis('equal') 12# xy軸の設定 13ax.grid(True) 14ax.set_xticks(np.arange(6)) 15ax.set_yticks(np.arange(-5, 6)) 16ax.set_xlabel('$x$', fontsize=16) 17ax.set_ylabel('$y$', fontsize=16) 18# 折れ線グラフの作成 19ax.plot(xs, ys, label='f') 20ax.plot(xs, tangent_ys, label='tangent') 21ax.plot(xs, normal_ys, label='normal') 22ax.legend() 23plt.show()

イメージ説明

追記

python

1import matplotlib.pyplot as plt 2import numpy as np 3from sympy import * 4 5init_printing() 6 7x = Symbol('x') 8c, k = 1, 3 9z = -(c * x**2 / (1 + (1 - (1 + k) * c**2 * x**2)**0.5)) 10prime_z = Derivative(z, x).doit() 11 12a = Symbol('a') 13z_a = z.subs(x, a) # f(a) 14prime_z_a = prime_z.subs(x, a) # f'(a) 15tangent = prime_z_a * (x - a) + z_a # 点 (a, f(a)) の接線 16normal = (-1 / prime_z_a) * (x - a) + z_a # 点 (a, f(a)) の法線 17theta = deg(atan(-1 / prime_z_a)) # 法線の角度
xs = np.arange(0.1, 6.28, 0.1) thetas = np.array([complex(theta.subs(a, t)) for t in xs]) # 保存 np.savetxt("points.csv", np.c_[xs, thetas.real, thetas.imag], delimiter=",") # 読み込み xs, real, imag = np.loadtxt("points.csv", delimiter=",", unpack=True) thetas = real + 1j * imag

投稿2018/12/12 09:25

編集2018/12/13 10:00
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mdshiba2

2018/12/13 08:25

ご返信遅くなってしまい申し訳ありません.ご回答ありがとうございます. aの値が0から6まで0.1間隔で変化した時に,対応するθの値を取得したい場合はどのように書き直せばいいのでしょうか?ご教授して頂けると幸いです.
mdshiba2

2018/12/13 08:54

訂正して頂いたプログラムを基に自分でもプログラムを書いてみましたが,エラーが出てしまいました...
tiitoi

2018/12/13 10:02

追記に記載しました。 定数 c, k の値がわからないので適当に設定したら [0, 6] の範囲で複素数が出てきてしまうので、そこらへんは適当になおしてください。
mdshiba2

2018/12/13 12:23

ありがとうございます!!大変助かりました.何度も返信してくださりありがとうございました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問