[Matrix-SIG] algorithm for intelligent axis scaling?

Oliver Gathmann gathmann@scar.utoronto.ca
Fri, 19 Mar 1999 07:57:41 -0500 (EST)


On Thu, 18 Mar 1999, Alexander Lawhead wrote:

> This is not directly a NumPy question, but I figured that the best answer
> might come from this group. :) I'm looking for a simple algorithm for
> generating intelligent axis scalings for a graph. Basically what I need is
> the axis minimum, axis maximum, and step length between ticks given the
> minimum data value, maximum data value, and suggested number of ticks.
> By intelligent, I mean reasonably intuitive rounding for the axis labels!
> 

I'm afraid this might not be needed anymore, but I guess it's good to have
as many different opinions on how to solve a particular problem as
possible...:

from Numeric import *

def _calcMinMax(self, x, p = 0.05):
    '''
    Compute initial min and max axis scaling points.
    Approach: 
    a) with buffer:
       reserve a fraction p of the total span of an axis as buffer and
       round to next order of magnitude
    b) strict (p==0):
       just round to the next order of magnitude
    Special cases: 
    x_min==x_max : assign symmetric interval or [0,1], if zero.
    '''
    if len(x)>0:             # not an empty array passed
	x_max,x_min = maximum.reduce(x),minimum.reduce(x)
	if x_min <> x_max:   # esp. not both x_min,x_max equal to zero
	    span = x_max - x_min
	    buffer = p * span
	    if x_min-buffer > 0:    # both (x_min-buffer),(x_max+buffer) > 0
		x_min = round(x_min - buffer, -(floor(log10(buffer) - 1)))
		x_max = round(x_max + buffer, -(ceil(log10(buffer) - 1)))
	    elif x_max+buffer < 0:  # both (x_min-buffer),(x_max+buffer) < 0
		x_min = round(x_min - buffer, -(ceil(log10(buffer) - 1)))
		x_max = round(x_max + buffer, -(floor(log10(buffer) - 1)))
	    else: # (x_min-buffer </= 0)and(x_max+buffer >/= 0) 
		try:
		    x_min = round(x_min - buffer, -(ceil(log10(buffer) - 1)))
		except OverflowError: # buffer == 0
		    x_min = 0
		try:
		    x_max = round(x_max + buffer, -(ceil(log10(buffer) - 1)))
		except OverflowError: # buffer == 0
		    x_max = 0
	else:
	    if x_min <> 0:
		x_min = x_min - x_min/2.0
		x_max = x_max + x_max/2.0
	    else:
		x_min = 0
		x_max = 1
    else:
	x_min = 0
	x_max = 1
    return x_min,x_max



Regards,

Oliver

F. Oliver Gathmann (gathmann@scar.utoronto.ca)
Surface and Groundwater Ecology Research Group      
University of Toronto
phone: (416) - 287 7420 ; fax: (416) - 287 7423     
web: http://www.scar.utoronto.ca/~gathmann