"""Make bar chart from a bunch of columns from a simple data file Each *column* is a bar graph bar file: x_1 y1_1 y2_1 y3_1 ... x_2 y1_2 y2_2 y3_2 ... : x_n y1_n y2_n y3_n ... Also recognizes structured comments #t, #x, #y, #s """ from pylab import * # required for matplotlib import sys # argv[] import numpy # mean, std y=array([]) name='' # filename to save plot in f=open(sys.argv[1], "rU") # readonly, unformatted? xlim = (0,) # default: no X-limits given def readfile(filename): global labels,y,name,nlab,ylab, nrow, ncol, nlabel labels = [] # the data column labels y = array([]) # the 2D array of numbers read in print "Reading",filename f=open(filename, "rU") # readonly, unformatted? for line in f: line = line.replace("\n","") # strip trailing '\n' #print line #debug if line=="": continue #ignore blank lines line = line.replace("\\n", "\n") # replace user 2-char \n with real \n if line[:3]=="#t ": title(line[3:]) continue if line[:3]=="#n ": # only used for 'n' choice of X values nlab = line[3:] continue if line[:3]=="#x ": # backward compatibility: becomes label[0] labels.insert(0, line[3:]) continue if line[:3]=="#y ": # append another column label to the list labels.append(line[3:]) continue if line[:3]=="#s ": name = line[3:].strip() continue if line[:1]=="#": continue # ignore comments # must be data: strip trailing comments and remove commas s = line.find("#") if s >= 0: line = line[:s] words = line.replace("{"," ").replace("}"," ") # remove C punctuation words = words.replace("/"," ") words = words.replace(","," ").split() # remove columns that aren't numbers for i in range(len(words)-1, -1, -1): # oddly, goes from (len-1) to 0 if "+-.0123456789".find(words[i][0]) < 0: words.pop(i) new = [float(s) for s in words] # the new row of data new = array(new) #print len(y),y,new if len(y) == 0: y = new ncol = len(new) else: y = vstack( (y, new) ) f.close() print "shape(y) = ",shape(y) nrow,ncol = shape(y) nlabel = size(labels) print " nrow=", nrow,"ncol=",ncol #end readfile() readfile(sys.argv[1]) # all the data are read into 2D array y[,]. #for i in range(nrow): # print i, "%17.12f" % numpy.average(y[i,:]), \ # "%17.12f" % numpy.std(y[i,:], ddof=1) # Now plot 'em # each plot string specifies the column, and color nbar = size(sys.argv[2:]) plotn = 0 width = 0 for i in sys.argv[2:]: if i[:3] == "fi=": readfile(i[3:]) #ys = 1; yo = 0 # scale and offset continue if i[:3]=="ti=": title(i[3:]) continue if i[:3]=="sa=": name = i[3:] # save filename continue if i[:3]=="xl=": # X label xlabel(i[3:]) continue if i[:3]=="yl=": # Y label ylabel(i[3:]) continue if i[:3]=="xa=": # X-axis limits words=i[3:].split(":") xlim=(float(words[0]), float(words[1]) ) #axis(xmin=float(words[0]), xmax=float(words[1]) ) continue if i[:3]=="ya=": # Y-axis limits words=i[3:].split(":") axis(ymin=float(words[0]), ymax=float(words[1]) ) continue if i[0]=='n': x = range(1,nrow+1) # 1..n xlabel(nlab) # special label else: col = int(i[0], 36) # radix 36 allows >9 columns x = y[:,col] if col < nlabel: xlabel(labels[col]) if width == 0: width = 0.8*(x[1]-x[0]) # total width of all bars in a column col = int(i[1], 36) # radix 36 allows >9 columns plotn += 1 left = width/nbar*(plotn-1) color = i[2:] if col < size(labels): label = labels[col] else: label = "" print i,col,left,color,label bar(x+left, y[:,col], width/nbar, align='center', color=color, \ label=label) if len(xlim) > 1: axis(xmin=xlim[0], xmax=xlim[1]) if len(labels) > 1: legend(loc=0) grid(True) if name != '': savefig(name) show()