By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,837 Members | 1,813 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,837 IT Pros & Developers. It's quick & easy.

Realtime interactive graphing of a simulation

P: 7
I am writing a program to simulate a double displacement reaction getting to equilibrium, but I am having some trouble graphing the particles' concentrations. It seems that it's only possible to pan and zoom the graph once the program exits (when running it from IDLE), but I don't want to have to kill the sim every time I want to view the graph (besides, when I do, the graph window dissappears).

The following code contains all the graphing functionality, the initGraph() function is called before the sim's main loop, and updateGraph() is called once a second with the current concentrations of 4 types of particles. The sim uses PyGame for graphics, and I didn't think that code was relevant: if it is, just let me know and I'll post it.

Expand|Select|Wrap|Line Numbers
  1. from pylab import *
  2.  
  3. # Turn on interactive mode for graphing
  4. ion()
  5. #hold(False)
  6. xlabel("time (seconds)")
  7. ylabel("concentration (particles/window)")
  8.  
  9. #graphLines = []
  10. graphData = []
  11. updateInterval = 0
  12.  
  13. def initGraph(interval, *colours):
  14.     """Initializes this module
  15.  
  16.     interval: the time, in seconds, btwn calls to updateGraph()
  17.     colours: list of 3-tuples (r,g,b) for each line's colour
  18.     """
  19.     updateInterval = interval
  20.     for c in colours:
  21.         line = plot([0],[0])[0]
  22.         line.set_color(c)
  23.         graphData.append({'x':[0],'y':[0]})
  24.         #graphLines.append(line)
  25.  
  26. def updateGraph(*cons):
  27.     """Updates graph data and draws it
  28.  
  29.     cons: a list of concentrations, the same length of colours arg to initGraph
  30.     """
  31.     #for line, con in zip(graphLines, cons):
  32.     for line, con in zip(graphData, cons):
  33.         #xdata, ydata = line.get_xdata(), line.get_ydata()
  34.         #xdata.append(xdata[-1] + updateInterval)
  35.         #ydata.append(con)
  36.         #line.set_data(xdata, ydata)
  37.         #plot(xdata, ydata)
  38.         line['x'].append(line['x'][-1] + updateInterval)
  39.         line['y'].append(con)
  40.  
  41.     plot(*[line['x'], line['y'] for line in graphData])
  42.  
Nov 22 '07 #1
Share this Question
Share on Google+
2 Replies


bartonc
Expert 5K+
P: 6,596
As much as I dislike globals, working on the module level like this, it is convenient:
Expand|Select|Wrap|Line Numbers
  1. updateInterval = 0
  2.  
  3. def initGraph(interval, *colours):
  4.     """Initializes this module
  5.  
  6.     interval: the time, in seconds, btwn calls to updateGraph()
  7.     colours: list of 3-tuples (r,g,b) for each line's colour
  8.     """
  9.     global updateInterval
  10.     updateInterval = interval
  11.     for c in colours:
  12.         line = plot([0],[0])[0]
  13.         line.set_color(c)
  14.         graphData.append({'x':[0],'y':[0]})
  15.         #graphLines.append(line)
Otherwise, updateInterval remains a function-scope variable and nobody else sees the change.

That's the first thing that caught my eye... I'll keep looking.
Nov 22 '07 #2

P: 7
thanks, i appreciate your help
Nov 26 '07 #3

Post your reply

Sign in to post your reply or Sign up for a free account.