J'ai écrit un script Python censé exécuter une boucle qui lit les coordonnées 3D de l'entrée standard et affiche les coordonnées les plus récentes sous forme de nuage de points sur un mpl_toolkits.mplot3d.Axes3D
.Le tracé interactif ne s'initialise pas avec l'entrée d'un autre programme
Il fonctionne quand j'entrer les coordonnées manuellement via l'invite (il donne un avertissement de dévalorisation bien):
$ 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)
Il fonctionne également lorsque je nourris les coordonnées d'un fichier dans le programme:
$ 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
Mais cela ne fonctionne pas lorsque je redirige la sortie du script de génération directement dans le script de traçage et que le script de génération exécute un time.sleep()
après chaque itération:
$ python generate3d.py | python plot3d.py
Le comportement de travail est, la fenêtre de figure est ouverte, ce qui affiche un nuage de points montrant un point. Le comportement ne fonctionne pas, la fenêtre de la figure est ouverte, mais elle n'affiche que l'arrière-plan gris, sans axes ni points.
Voici le code pour le script traçante:
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)
Voici le code pour le script de génération:
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)
J'ai observé que l'impact de la sleeptime dans le script de génération peut-être proportionnel au temps nécessaire à l'initialisation des axes. Avec un temps de sommeil proche de zéro, presque aucun temps d'initialisation n'est nécessaire. Avec un temps de sommeil à 0,1, il faut déjà du temps pour que le graphique apparaisse. Je n'ai pas encore exploré la latence des données affichées quand elle est enfin là.
Quelqu'un peut-il reproduire ce comportement? Quelqu'un peut-il m'aider à comprendre et à résoudre ce problème? Est-ce que je fais quelque chose de mal?
informations potentiellement utiles:
$ lsb_release -d
Description: Ubuntu 14.04.5 LTS
$ python --version
Python 2.7.6
>>> matplotlib.__version__
'1.3.1'
Merci pour vos commentaires! J'ai ajouté un 'sys.stdout.flush()' avant le sommeil dans 'generate3d.py' et le problème était parti. Pas besoin d'exécuter le processus en tant que sous-processus. – moooeeeep