import numpy as np def nicenum(x, round=True): ''' find a nice number approximately equal to x, where nice means a number divisible by 2 or 10. x : input floating point number round : True = round number, False = take ceiling ''' exponent = np.floor(np.log10(x)) frac = x/10**exponent if round : if frac < 1.5: ans = 1. elif frac < 3.: ans = 2. elif frac < 7. : ans = 5. else : ans = 10. else : if frac < 1.: ans = 1. elif frac <= 2.: ans = 2. elif frac <= 5. : ans = 5. else : ans = 10. return ans*10**exponent def pretty(data, ntics=5, tight=True): ''' Come up with a nice range of values for a graph where the start and end values are divisible by 2 or 5, and we can have ntics tics which are "nice" numbers. data : input array of float or int ntics : number of tics to create tight : by default put a buffer of potentially zero space around data. If False, then put a buffer of about 1/2 step past min and max data. return array of tic values and number of decimals ''' data_range = data.max() - data.min() nice_range = nicenum(data_range, round=False) step = nicenum(nice_range/(ntics-1)) graph_min = np.floor(data.min()/step)*step graph_max = np.ceil(data.max()/step)*step digits = np.floor(np.log10(step)) num_frac = max(-digits, 0) if tight == False : return np.arange(graph_min, graph_max+step, step), int(digits) else : gmin = graph_min if abs(graph_min - data.min()) > 0.75*step: gmin = graph_min + step/4. # pull in boundary a bit elif abs(graph_min - data.min()) < 0.25*step: gmin = graph_min - step/4. # extend boundary a bit gmax = graph_max if abs(graph_max - data.max()) > 0.75*step: gmax = graph_max - step/4. # pull in boundary a bit elif abs(graph_max - data.max()) < 0.25*step: gmax = graph_max + step/4. # extend boundary a bit return np.array([gmin] + list(np.arange(graph_min+step, graph_max, step)) + [gmax]), int(digits) if __name__ == '__main__' : data = np.array([4.8, 6.5, 12., 14.9, 10., 10.7, 7.9, 21.9, 12.5, 14.5, 9.2]) print "---------- test 1 ---------------" print pretty(data) print "---------- test 2 ---------------" print pretty(data*100000) print "---------- test 3 ---------------" print pretty(data/100000) print "---------- test 3 ---------------" print pretty(data, tight=False)