標準入力から3次元座標を読み取り、最も最近読み込まれた座標を散布図としてmpl_toolkits.mplot3d.Axes3D
に表示するループを実行するはずのPythonスクリプトを作成しました。対話型プロットは、別のプログラムからパイプで入力して初期化できません
私は(それはしかし、いくつかの非推奨の警告を与える)プロンプトから手動で座標を入力すると、それは動作します:
$ python plot3d.py
.5 .5 .5
/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py:2407: MatplotlibDeprecationWarning: Using default event loop until function specific to this GUI is implemented
warnings.warn(str, mplDeprecation)
私はプログラムにファイルから座標を供給するときにも動作します:
$ head generated
0.56 0.40 0.55
0.61 0.49 0.60
0.48 0.39 0.48
0.39 0.33 0.39
0.32 0.28 0.32
0.35 0.31 0.35
0.50 0.47 0.50
0.40 0.38 0.40
0.37 0.35 0.37
0.51 0.50 0.51
$ python plot3d.py < generated
しかし、生成スクリプトの出力をプロッティングスクリプトに直接パイプすると生成スクリプトは各反復後にtime.sleep()
を実行します。
$ python generate3d.py | python plot3d.py
動作ビヘイビアは、Figureウィンドウが開かれ、1つのドットを示す散布図が表示されます。動作しない動作は、Figureウィンドウが開かれますが、灰色の背景、軸やドットは表示されません。ここで
は、プロットスクリプトのコードです:ここで
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
plotted_items = None
while True:
if plotted_items is not None:
plotted_items.remove()
try:
x,y,z = map(float, raw_input().split())
except:
break
else:
plotted_items = ax.scatter([x],[y],[z])
ax.set_xlim(-5, 5)
ax.set_ylim(-5, 5)
ax.set_zlim(-5, 5)
plt.pause(0.1)
は、生成スクリプトのコードです:
from random import random
import time
last = None
while True:
if last is None:
last = [random(), random(), random()]
offset = random()
for i in range(len(last)):
last[i] += 0.25 * (offset - last[i])
print "%.2f %.2f %.2f" % tuple(last)
# the value of this sleep duration influences how long it takes to initialize
# the plot in the other script!?
time.sleep(0.5)
私は生成スクリプト内のスリープ時間の影響があるかもしれないことを観察しました軸の初期化に必要な時間に比例します。休止時間がゼロに近づくと、初期化時間はほとんど必要ありません。スリープ時間が0.1になると、すでにグラフが表示されるまでに時間がかかります。 私は、表示されたデータが最終的にそこにあるときのレイテンシについてまだ調べていません。
誰でもこの現象を再現できますか?誰も私がこれを理解して解決するのを助けることができる?私は何か間違っているのですか?
潜在的に有益な情報:
$ lsb_release -d
Description: Ubuntu 14.04.5 LTS
$ python --version
Python 2.7.6
>>> matplotlib.__version__
'1.3.1'
感謝を!私は 'generate3d.py'でスリープする前に' sys.stdout.flush() 'を追加し、問題はなくなりました。プロセスをサブプロセスとして実行する必要はありません。 – moooeeeep