Я написал сценарий Python, который должен запускать цикл, который считывает 3d-координаты со стандартного ввода и отображает последние считанные координаты как график рассеяния на mpl_toolkits.mplot3d.Axes3D
.Интерактивный сюжет не инициализируется с помощью ввода, переданного из другой программы
Он работает, когда я ввести координаты вручную с помощью запроса (это дает некоторое предупреждение устаревания, хотя):
$ 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
Рабочее поведение: открывается окно с рисунком, в котором отображается график рассеяния, показывающий одну точку. Не работает поведение, открывается окно фигуры, но отображается только серый фон, без осей или точек.
Вот код для сценария черчения:
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)
Я заметил, что влияние времени сна в генераторном сценарии может быть пропорциональное времени, требуемому для инициализации осей. При близком к нулю сдержанности почти не требуется время инициализации. С sleeptime в 0.1 это уже занимает много времени для появления диаграммы. Я еще не изучил задержку отображаемых данных, когда она наконец-то появилась.
Может ли кто-нибудь воспроизвести это поведение? Может ли кто-нибудь помочь мне понять и исправить это? Я делаю что-то неправильно?
Потенциально полезная информация:
$ lsb_release -d
Description: Ubuntu 14.04.5 LTS
$ python --version
Python 2.7.6
>>> matplotlib.__version__
'1.3.1'
Спасибо за ваш вклад! Я добавил 'sys.stdout.flush()' перед сном в 'generate3d.py', и проблема исчезла. Нет необходимости запускать процесс в качестве подпроцесса. – moooeeeep