1

I am fairly new in python, and I am trying to have a plot, based on data stored in a file. This file may be updated at any time, so I am trying to make the drawing updated every 3 seconds (so I don't use all the CPU). My problem is that the GUI freezes after the lunch.

#!/usr/bin/python
# _*_ coding: utf8 _*_

import matplotlib.pyplot as plt
import numpy as np
import time 

plt.ion()
plt.figure()
i=0
while 1:
    taille=0
    fichier=np.loadtxt('data/US.SAVE')
    fichier1=np.loadtxt('data/cond.SAVE')
    taille1=np.size(fichier1[:,1])
    taille=np.size(fichier[:,1])

    min=min(fichier[0,0],fichier1[0,0]);

    fichier[:,0]=fichier[:,0]-min
    fichier1[:,0]=fichier1[:,0]-min


    if (taille != taille1) :
        printErrors("TAILLE DE FICHIERS DIFFERENTES")


    nb_chunks=np.size(fichier1[1,:])
    nb_inputs=np.size(fichier[1,:])


    plt.subplot(3,1,1)

    plt.bar(fichier[:,0],fichier[:,1],align='center',width=0.0001, facecolor='b', label="US")
    x1,x2,y1,y2 = plt.axis()
    x1=x1-0.0001
    plt.axis([x1, x2, y1, 1.2])
    plt.legend(ncol=3,prop={'size':9})
    plt.title("US ") 
    plt.ylabel('Activation')
    plt.xlabel('Time')

    plt.subplot(3,1,2)

    plt.bar(fichier1[:,0],fichier1[:,1],align='center',width=0.0001, facecolor='b', label="response")



    plt.axis([x1, x2, y1, 1.2])
    plt.legend(ncol=3,prop={'size':9})
    plt.title("Response ") 
    plt.ylabel('Activation')
    plt.xlabel('Time')


    plt.subplot(3,1,3)

    plt.bar(fichier[:,0]-fichier1[:,0],fichier1[:,1],align='center',width=0.0001, facecolor='b', label="Error")
    plt.axis([x1, x2, y1, 1.2])
    plt.legend(ncol=3,prop={'size':9})
    plt.title("Error") 
    plt.ylabel('Activation')
    plt.xlabel('Time')
    plt.draw()
    name1='data/Conditionnement.eps'
    plt.savefig(name1,dpi=256)
    plt.draw()
    del fichier,fichier1,min
    i=i+1

    time.sleep(3)   

plt.show()

I did not find any other topic on a file based drawing.

Jdog
  • 10,071
  • 4
  • 25
  • 42
  • Did you get this sorted out? If so you should accept one of the answers. – tacaswell Jun 01 '13 at 04:07
  • possible duplicate of [pylab.ion() in python 2, matplotlib 1.1.1 and updating of the plot while the program runs](http://stackoverflow.com/questions/12822762/pylab-ion-in-python-2-matplotlib-1-1-1-and-updating-of-the-plot-while-the-pro) – Mechanical snail Jun 05 '13 at 23:33

2 Answers2

2

You want to use the plt.pause(3) function instead of time.sleep(). pause includes the necessary calls to the gui main loop to cause the figure to re-draw.

also see: Python- 1 second plots continous presentation, matplotlib real-time linear line, pylab.ion() in python 2, matplotlib 1.1.1 and updating of the plot while the program runs,

Community
  • 1
  • 1
tacaswell
  • 84,579
  • 22
  • 210
  • 199
2

On top of the answer of @tcaswell (that solve the problem), I suggest to rethink the script in a more OO way.

I have tried this:

plt.ion()
plt.figure()
plt.show()

while True:
    x=np.arange(10)
    y=np.random.rand(10)

    plt.subplot(121)
    plt.plot(x,y)
    plt.subplot(122)        
    plt.plot(x,2*y)

    plt.draw()

    plt.pause(3)

but it does not work (it looks like it opens a gui at plt.figure and then at each loop.

A solution like this:

plt.ion()
fig, ax = plt.subplots(nrows=2, ncols=1)
plt.show()

while True:
    x=np.arange(10)
    y=np.random.rand(10)

    ax[0].plot(x,y)
    ax[1].plot(x,2*y)

    plt.draw()

    plt.pause(3)

is much more efficient (axes are created only once), neater (at the end matplotlib is OO) and potentially less prone to memory leaks.

Besides, from your most I gather that at each loop you read in the files again and then plot the new lines. If this is the case, you want to clear first the content of the axes before redrawing. In my simple case you can clear the axes with

for a in ax:
    a.clear()
Francesco Montesano
  • 8,485
  • 2
  • 40
  • 64
  • 1
    +1 If you are going to do it this way, you can do one better, save the `Line2d` objects and re-use them as well. – tacaswell Feb 02 '13 at 00:52
  • @tcaswell: do you mean something like this? `l = ax.plot(x,y)` the first time and `l.set_data(x, y)` in all the following loops? To get automatic resetting of the axis limits can do `ax.relim()`; `ax.autoscale()` – Francesco Montesano Feb 02 '13 at 11:45
  • yes, something like that. See the links in my answer or any of the animation examples. – tacaswell Feb 02 '13 at 16:46