From: Patrick K. <pa...@ke...> - 2002-12-04 05:06:13
|
As you probably know, if you just close a Vpython display which was started from a program running under Pythonwin, it causes Pythonwin to die, even after the program terminates. So I had to "invent" a method of gracefully terminating a Vpython program. Not too difficult I know, but having done so, I thought I might as well share it. So here is a function (a histogram plotter), with this capability. #!/usr/bin/python # # Histo - plot a histogram of stacked cylinders using Vpython # # Author Patrick Keogh # from visual import * def histo(stacked, data): """ The second parameter which is passed is assumed to be a sequence, which has: - The first element is a sequence of category labels - The second element is a sequence of data series labels. - The third element is a sequence of sequences of the data values """ # # This try/except figures out if there is already a scene. If not, it creates it. # try: type(scene) except: scene = display() scene.show() max_entries = len(data[0]) col = (color.red,color.blue,color.green,color.yellow) data_array = [] for i in data[2]: max_entries = max((max_entries, len(i))) arrow(axis=(max_entries+1,0,0), shaftwidth=0.1, fixedwidth=1) max_height = 0.0 for i in range(max_entries): data_array.append([]) for j in range(len(data[2])): data_array[i].append(data[2][j][i]) max_height=max((max_height,sum(data_array[i]))) arrow(axis=(0,10,0), shaftwidth=0.1, fixedwidth=1) for j in range(len(data_array[0])): label(pos=(-5,j*2,j*2),text=data[1][j],color=col[j],opacity=0,box=0,border=0 ) for i in range(len(data_array)): base = 0 for j in range(len(data_array[i])): cyl_height = data_array[i][j]*10.0/max_height if stacked: pos = (i+1,base,0) base = base + cyl_height else: pos = (i+1,0,j*2) axis = (0,cyl_height,0) c = cylinder(pos=pos,axis=axis,radius=0.3,color=col[j]) c.label = "(" + data[0][i] + "," + repr(data_array[i][j]) + ")" scene.center = (len(data_array)/2,5,0) again = 1 prev = None # # Apart from the standard zoom and rotate capabilities, we will add # # Left click = Set a new center # Ctrl-C = Exit # Move over a bar = Display the (x,y) label for the histogram bar # Note the "hack" of inserting the label as an attribute of the cylinder # while again: while scene.mouse.events: if scene.mouse.clicked: scene.center = scene.mouse.getclick().pos if scene.kb.keys: if scene.kb.getkey() == 'ctrl+c': again = 0 if scene.mouse.pick <> None: if prev <> scene.mouse.pick: try: l.visible = 0 except: pass prev = scene.mouse.pick if prev.__class__ == cylinder: l = label(pos=scene.mouse.pos, text=prev.label, box=0) # # If a control-c was entered, then the while loop exits, and we close down the display and exit # scene.hide() del(scene) |