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

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

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

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

Q&A

解決済

3回答

4028閲覧

listによる、3次元プロットについての問題点

Fallout_18

総合スコア124

Python 3.x

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

0グッド

0クリップ

投稿2018/05/09 16:18

編集2018/05/09 16:21

結果から言うと、
ある場所に依存した確率を自分で算出することができました。
ただ、3次元プロットをしようとして、躓いています。
コード自体は、正直汚いと思われ、これから改良していく予定です。

python

1import numpy as np 2import matplotlib.pyplot as plt 3import math 4from mpl_toolkits.mplot3d import Axes3D 5 6#環境設定 7n=2 #tの範囲 8m=4 #xの範囲 9 10P = [[-1/2, 1/2, 1/2, 1/2],[0,0,0,0],[0,0,0,0],[0,0,0,0]] 11Q = [[0,0,0,0],[1/2, -1/2, 1/2, 1/2],[0,0,0,0],[0,0,0,0]] 12R = [[0,0,0,0],[0,0,0,0],[1/2, 1/2, -1/2, 1/2],[0,0,0,0]] 13S = [[0,0,0,0],[0,0,0,0],[0, 0, 0, 0],[1/2, 1/2, 1/2, -1/2]] 14 15x_list=[]#xline 16y_list=[]#yline 17t_list=[]#time 18p_list=[]#probability 19s_list=[]#state 20a = 1#1/math.sqrt(2) 21b = 0#1j/math.sqrt(2) 22c = 0 23d = 0 24 25for i in range(0,2*m+1): 26 if i == m: 27 phi = [a ,b, c, d] 28 else: 29 phi = [0, 0, 0, 0] 30 p = np.dot(phi,np.conj(phi)) 31 32 x_list.append(i) #xの座標 33 y_list.append(i) #yの座標 34 35 s_list.append(phi) 36 p_list.append(p) 37 38for t in range(0, n+1): 39 t_list.append(t) 40 if t == 0: 41 s_list 42 p_list 43 else: 44 next_s_list = [0]*len(s_list) 45 for x in range(0,2*m+1): 46 if x == 0: 47 for y in range(0,2*m+1): #x=0, 0<= y =<2*m 48 if y == 0: 49 next_s_list[y] = np.inner(P, s_list[x+1]) + np.inner(R, s_list[y+1]) 50 elif y == 2*m: 51 next_s_list[y] = np.inner(P, s_list[x+1]) + np.inner(S, s_list[y-1]) 52 else: 53 next_s_list[y] = np.inner(P, s_list[x+1]) + np.inner(R,s_list[y+1]) +np.inner(S, s_list[y-1]) 54 elif x == 2*m: #x=2*m, 0<=y<=2*m 55 for y in range(0, 2*m+1): 56 if y == 0: 57 next_s_list[y] = np.inner(Q, s_list[x-1]) + np.inner(R, s_list[y+1]) 58 elif y == 2*m: 59 next_s_list[y] = np.inner(Q, s_list[x-1]) + np.inner(S, s_list[y-1]) 60 else: 61 next_s_list[y] = np.inner(Q, s_list[x-1]) + np.inner(R,s_list[y+1]) +np.inner(S, s_list[y-1]) 62 else: 63 if y == 0: 64 next_s_list[y] = np.inner(Q,s_list[x-1]) + np.inner(P,s_list[x+1]) 65 elif y == 2*m: 66 next_s_list[y] = np.inner(Q,s_list[x-1]) + np.inner(P,s_list[x+1]) + np.inner(S,s_list[y-1]) 67 else: 68 next_s_list[y] = np.inner(P, s_list[x+1]) + np.inner(Q, s_list[x-1]) + np.inner(R, s_list[y+1]) + np.inner(S,s_list[y-1]) 69 p_list[x] = np.dot(next_s_list[y], np.conj(next_s_list[y])) 70 s_list = next_s_list 71 72 print(t,p_list) 73 74 75#3Dplot 76 77fig = plt.figure() 78ax = Axes3D(fig) 79 80ax.set_xlabel("x") 81ax.set_ylabel("y") 82ax.set_zlabel("probability") 83 84ax.set_xlim(3*m,-m) 85ax.set_ylim(-m,3*m) 86ax.set_zlim(0,1) 87ax.plot(x_list, y_list, p_list, color ="red", linewidth=1) 88plt.show()

今回はコード自体はあまり関係ないと思われますが、一応掲載しときます。確率は

t=0 x_list=y_list=[0,1,2,3,4,5,6,7,8] p_list=[0, 0, 0, 0, 1, 0, 0, 0, 0] t=1 x_list=y_list=[0,1,2,3,4,5,6,7,8] p_list=[0.0, 0.0, 0.0, 0.25, 0.0, 0.25, 0.0, 0.0, 0.0] t=2 x_list=y_list=[0,1,2,3,4,5,6,7,8] p_list=[0.0, 0.0, 0.0625, 0.0, 0.125, 0.0, 0.0625, 0.0, 0.0]

となり、計算結果は間違えていません。
このとき、x_list=y_list=[0, 1, 2, 3, 4, 5, 6, 7, 8]に対応しており、
t=1(空白は確率0)のとき
|y/x|0|1|2|3|4|5|6|7|8|
|--|--:|
|0
|1
|2
|3|||||1/4|
|4||||1/4||1/4
|5|||||1/4|
|6
|7
|8

のように、x_list,y_listの中の座標を確率と対応させると、確かに上図のようなプロットが出来るはずなのですが、
x_list,y_listの中の順番とp_listの順番が1:1対応してしまい以下のような図になってしまいました。
原因はわかっているのですが、どのように修正すれば上図のようなプロットに到達できるのか、アドバイス等お願いします。
イメージ説明

すこしわかりにくい説明になってしまいました。
状況が理解できない場合、説明します。
よろしくお願い致します。

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

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

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

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

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

guest

回答3

0

計算部に関してはあまり理解はしていないのですが・・。
質問の表のようなデータをプロットしたいのであれば、1次元として保持している確立データ(p_list)を2次元データとして保つ必用があるのではないでしょうか。

Pytho

1import numpy as np 2import matplotlib.pyplot as plt 3from mpl_toolkits.mplot3d import Axes3D 4 5m=4 6 7x_list = range(0, 2*m+1) 8y_list = range(0, 2*m+1) 9p_list = np.array( 10 [[0,0,0,0,0,0,0,0,0], 11 [0,0,0,0,0,0,0,0,0], 12 [0,0,0,0,0,0,0,0,0], 13 [0,0,0,0,0.25,0,0,0,0], 14 [0,0,0,0.25,0,0.25,0,0,0], 15 [0,0,0,0,0.25,0,0,0,0], 16 [0,0,0,0,0,0,0,0,0], 17 [0,0,0,0,0,0,0,0,0], 18 [0,0,0,0,0,0,0,0,0]] 19) 20 21X,Y = np.meshgrid(x_list,y_list) 22 23fig = plt.figure() 24ax = Axes3D(fig) 25 26ax.set_xlabel("x") 27ax.set_ylabel("y") 28ax.set_zlabel("probability") 29 30ax.set_xlim(2*m,0) 31ax.set_ylim(0,2*m) 32ax.set_zlim(0,1) 33ax.plot_wireframe(X, Y, p_list) 34plt.savefig('out.png') 35plt.show()

【結果】
イメージ説明

投稿2018/05/10 00:05

magichan

総合スコア15898

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

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

KSwordOfHaste

2018/05/10 02:37

plot_surfaceって回答してしまったですが、ワイヤーフレームならplot_wireframeですね!
magichan

2018/05/10 03:04

確かにそうですね。 ただ個人的には、surface と wireframe は好みの問題かと思いますので、surfaceでも全く問題ないかと思います。
Fallout_18

2018/05/10 14:06

んーと、上記のようにp_listにひとつひとつプロットしていくということですか?
Fallout_18

2018/05/10 14:25

新たな2次元配列をもってきて、時間ごとに更新しながら代入していくやり方の方がよさそうですね。
Fallout_18

2018/05/10 15:19

magichanさん、上のp_listは1次元から2次元配列を自分で手作業で代入して変えるしか、やり方がありませんでしょうか?
Fallout_18

2018/05/10 15:26

調べたら、できるみたいなのでちょっとやってみます
magichan

2018/05/10 16:08 編集

返信おそくなりました。すみません ワイヤーフレームのような3次元のグラフを書くためには、各x,yに対するP値のマトリックスを全て埋める必要があります。 で、その方法ですが、一次元であたえられたP値のリストが各x,y にどのように対応しているのかを私が理解しておりませんので、申し訳ありませんが具体的にに回答することができません。とりあえずxとyを引数にとりP値を返す関数 f(x,y) 等を定義することで、簡単に記述できるかと思います。
Fallout_18

2018/05/11 10:18

お返事ありがとうございます。 おっしゃる通り、pをx,yの関数で定義して行うことが、解決策になりますね。やってみます。
guest

0

自分もmatplotlibはサンプル真似るレベルですので間違ってるかも知れませんが...

そもそもplotの1回の呼び出しでは1本の折れ線グラフしか描けないのではないでしょうか。これを用いて確率をX-Y平面上に充填したようなグラフを描画するにはX or Y軸にそって複数本の走査線のようなグラフを別個に描画する必要があるような気がします。

つまり以下のようなイメージです。

Python

1... 2ax.plot([2, 3, 4, 5, 6], [3, 3, 3, 3, 3], [0, 0, 1/4, 0, 0]) 3ax.plot([2, 3, 4, 5, 6], [4, 4, 4, 4, 4], [0, 1/4, 0, 1/4, 0]) 4ax.plot([2, 3, 4, 5, 6], [5, 5, 5, 5, 5], [0, 0, 1/4, 0, 0]) 5... 6plt.show()

もし2次元の格子のグラフをお望みならplot_surfaceを用いるのだと思います。

自分がイメージしたのは
https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html
にあるサンプルのうち以下のグラフです。
https://matplotlib.org/_images/wire3d_demo1.png

サンプルコードを見ますとplot_surfaceの引数のx, y, zはそれぞれXY平面の各格子上の頂点の座標を2次元に並べた形で与えることがわかります。

もし確率がx, yについての関数f(x, y)として定義できるなら簡単で、

(A) x, yについてはnumpy.meshgridを用いて展開
(B) ff = np.vectorize(f)でスカラー引数前提の関数fを配列前提のものに置き換える
(C) ffに(A)で生成したx, yを与えてz = ff(x, y)とする
(D) ax.plot_surface(x, y, z, ...)

とすれば描画できます。(A)~(C)は計算上の都合でこのとおりにやりにくいなら、同じ結果となるよううに独自に計算してももちろんかまわないです。

投稿2018/05/09 18:30

KSwordOfHaste

総合スコア18394

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

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

0

自己解決

出力する配列の次元が違っていたので、そこを修正して解決できました。

投稿2018/05/22 03:23

Fallout_18

総合スコア124

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問