title: matplotlib: (re-)plot ping standard-input data. Doable?
body: <p>I recently started tinkering with python and the matplotlib module(1.1.0) shipped with Enthought Python Distribution(the free version one).
  I thought of an interesting project I could do and came up with something like this:</p>
  <ul>
  <li>get ping of an internet address</li>
  <li>pipe that via <code>sys.stdin</code> into python script</li>
  </ul>
  <p>now in the python script:</p>
  <ul>
  <li>regex the answer time, if there is no answer time: use <code>NaN</code> or just 0 as number</li>
  <li>plot data via matplotlib</li>
  <li>add continuously data</li>
  </ul>
  <p>I managed to get the ping via this: ping stackoverflow.com | python script.py
  get the answertime wasn't particulary hard. But when it comes to plotting the data. I am stuck. I know there is an animation module inside matplotlib, but I think a timer-based plot would be harder to program than this, and I don't know how events are used anyway. What I want:</p>
  <ul>
  <li>Wait for sys.stdin to get a new string and thus the ping time</li>
  <li>Add it to the data array</li>
  <li>Plot the data array
  But it doesn't seem to be that easy. Besides this, Error handling is not yet done..
  Unfortunately I couldn't find any comparable code, although I did a lot of googling about it :/ Maybe this design is not meant to be like this..</li>
  </ul>
  <p>Does anybody have an idea how to accomplish this replotting? It doesn't need to be efficient, as the ping only comes in every second or so..
  I thought about buffering the incoming stdin and do a regular timer-based plot, but I have now idea to do that.</p>
  <p>Thank you in advance,</p>
  <p>Jonas</p>
  <h1>Update1:</h1>
  <p>I can get rid of this error by using:</p>
  <pre><code>l1.set_xdata(range(len(data)))
  </code></pre>
  <p>before the <code>l1.set_ydata(..)</code>, but still it doesn't plot anything and the window doesn't respond either. At least it shows the plot axis.</p>
  <h1>Code</h1>
  <pre><code>import sys
  import re
  import numpy as np
  import matplotlib.pyplot as plt
  
  
  def main():
      if sys.stdin.isatty():
          print &quot;Please use a pipe as stdin\nExample: ping stackoverflow.com | python script.py&quot;
          return 0
      regex = re.compile('time=(\d+.\d+)')
      data = []
      fig = plt.figure()
  
      ax = fig.add_subplot(111)
      ax.set_yscale('linear') # or log
      ax.grid(True)
  
      l1, = ax.plot(data)
      fig.show()
  
      while True:
          #get ping, if no string: stream has ended
          line = sys.stdin.readline()
          if line == '':
              break
          #conversion: 64 bytes from 127.0.0.1: icmp_seq=0 ttl=45 time=100.873 ms --&gt; 100.873
          match = regex.findall(line)
          number = 0.
  
          if len(match) &gt; 1:
              raise ValueError()
          if len(match) == 1:
              try:
                  number = float(match[0])
              except ValueError as e:
                  print e
          #add number to array, plot the data
          data.append(number)
          l1.set_xdata(range(len(data)))
          l1.set_ydata(data)
  
          ax.relim()
          ax.autoscale()
  
          plt.draw()
          fig.canvas.flush_events()
      return 0
  
  if __name__ == '__main__':
      sys.exit(main())
  </code></pre>