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

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

ただいまの
回答率

90.48%

  • Python 3.x

    6879questions

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

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 388

Fallout_18

score 65

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

import numpy as np
import matplotlib.pyplot as plt
import math
from mpl_toolkits.mplot3d import Axes3D

#環境設定
n=2  #tの範囲
m=4  #xの範囲

P = [[-1/2, 1/2, 1/2, 1/2],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
Q = [[0,0,0,0],[1/2, -1/2, 1/2, 1/2],[0,0,0,0],[0,0,0,0]]
R = [[0,0,0,0],[0,0,0,0],[1/2, 1/2, -1/2, 1/2],[0,0,0,0]]
S = [[0,0,0,0],[0,0,0,0],[0, 0, 0, 0],[1/2, 1/2, 1/2, -1/2]]

x_list=[]#xline
y_list=[]#yline
t_list=[]#time
p_list=[]#probability
s_list=[]#state
a = 1#1/math.sqrt(2)
b = 0#1j/math.sqrt(2)
c = 0
d = 0

for i in range(0,2*m+1):
    if i == m:
        phi = [a ,b, c, d]
    else:
        phi = [0, 0, 0, 0]
    p = np.dot(phi,np.conj(phi))

    x_list.append(i) #xの座標
    y_list.append(i) #yの座標

    s_list.append(phi)
    p_list.append(p)

for t in range(0, n+1):
    t_list.append(t)
    if t == 0:
        s_list
        p_list
    else:
        next_s_list = [0]*len(s_list)
        for x in range(0,2*m+1):
            if x == 0:
                for y in range(0,2*m+1):   #x=0, 0<= y =<2*m
                    if y == 0:
                        next_s_list[y] = np.inner(P, s_list[x+1]) + np.inner(R, s_list[y+1])
                    elif y == 2*m:
                        next_s_list[y] = np.inner(P, s_list[x+1]) + np.inner(S, s_list[y-1])
                    else:
                        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])
            elif x == 2*m:                  #x=2*m, 0<=y<=2*m
                for y in range(0, 2*m+1):
                    if y == 0:
                        next_s_list[y] = np.inner(Q, s_list[x-1]) + np.inner(R, s_list[y+1])
                    elif y == 2*m:
                        next_s_list[y] = np.inner(Q, s_list[x-1]) + np.inner(S, s_list[y-1])
                    else:
                        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])
            else:
                if y == 0:
                    next_s_list[y] = np.inner(Q,s_list[x-1]) + np.inner(P,s_list[x+1])
                elif y == 2*m:
                    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])
                else:
                    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])
            p_list[x] = np.dot(next_s_list[y], np.conj(next_s_list[y]))
        s_list = next_s_list

    print(t,p_list)


#3Dplot

fig = plt.figure()
ax = Axes3D(fig)

ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("probability")

ax.set_xlim(3*m,-m)
ax.set_ylim(-m,3*m)
ax.set_zlim(0,1)
ax.plot(x_list, y_list, p_list, color ="red", linewidth=1)
plt.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対応してしまい以下のような図になってしまいました。
原因はわかっているのですが、どのように修正すれば上図のようなプロットに到達できるのか、アドバイス等お願いします。
イメージ説明

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+2

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

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

m=4

x_list = range(0, 2*m+1)
y_list = range(0, 2*m+1)
p_list = np.array(
    [[0,0,0,0,0,0,0,0,0],
     [0,0,0,0,0,0,0,0,0],
     [0,0,0,0,0,0,0,0,0],
     [0,0,0,0,0.25,0,0,0,0],
     [0,0,0,0.25,0,0.25,0,0,0],
     [0,0,0,0,0.25,0,0,0,0],
     [0,0,0,0,0,0,0,0,0],
     [0,0,0,0,0,0,0,0,0],
     [0,0,0,0,0,0,0,0,0]]
)

X,Y = np.meshgrid(x_list,y_list)

fig = plt.figure()
ax = Axes3D(fig)

ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("probability")

ax.set_xlim(2*m,0)
ax.set_ylim(0,2*m)
ax.set_zlim(0,1)
ax.plot_wireframe(X, Y, p_list)
plt.savefig('out.png')
plt.show()

【結果】
イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/10 11:37

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

    キャンセル

  • 2018/05/10 12:04

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

    キャンセル

  • 2018/05/10 23:06

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

    キャンセル

  • 2018/05/10 23:25

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

    キャンセル

  • 2018/05/11 00:19

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

    キャンセル

  • 2018/05/11 00:26

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

    キャンセル

  • 2018/05/11 01:06 編集

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

    キャンセル

  • 2018/05/11 19:18

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

    キャンセル

+1

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

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

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

...
ax.plot([2, 3, 4, 5, 6], [3, 3, 3, 3, 3], [0, 0,   1/4, 0, 0])
ax.plot([2, 3, 4, 5, 6], [4, 4, 4, 4, 4], [0, 1/4, 0,   1/4, 0])
ax.plot([2, 3, 4, 5, 6], [5, 5, 5, 5, 5], [0, 0,   1/4, 0, 0])
...
plt.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)は計算上の都合でこのとおりにやりにくいなら、同じ結果となるよううに独自に計算してももちろんかまわないです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

check解決した方法

0

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python 3.x

    6879questions

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