views:

178

answers:

1

Further to: http://stackoverflow.com/questions/326679/choosing-an-attractive-linear-scale-for-a-graphs-y-axis

And what to do when some of the points are negative?

I believe this part of the question was not answered but it seems I can't comment or extend that question so I've created a new one

Values -100, 0, 100 with 5 ticks:
  1. lower bound = -100
  2. upper bound = 100
  3. range = 100--100 = 200
  4. tick range = 40
    1. Divide by 10^2 for 0.4, translates to 0.4, which gives (multiplied by 10^2) 40.
  5. new lower bound = 40 * round(-100/40) = -80
  6. new upper bound = 40 * round(1+100/40) = 120

or

  1. new lower bound = 40 * floor(-100/40) = -120
  2. new upper bound = 40 * floor(1+100/40) = 120

Now the range has been increased to 240 (an extra tick!), with 5 ticks at 40 each. it will take 6 steps to fill the new range!

Solution?

A: 

I use the following code. It produces nicely spaced steps for human viewers and caters for ranges that pass through zero :)

public static class AxisUtil
{
    public static float CalculateStepSize(float range, float targetSteps)
    {
        // calculate an initial guess at step size
        float tempStep = range/targetSteps;

        // get the magnitude of the step size
        float mag = (float)Math.Floor(Math.Log10(tempStep));
        float magPow = (float)Math.Pow(10, mag);

        // calculate most significant digit of the new step size
        float magMsd = (int)(tempStep/magPow + 0.5);

        // promote the MSD to either 1, 2, or 5
        if (magMsd > 5.0)
            magMsd = 10.0f;
        else if (magMsd > 2.0)
            magMsd = 5.0f;
        else if (magMsd > 1.0)
            magMsd = 2.0f;

        return magMsd*magPow;
    }
}
Drew Noakes
I see it returns a step value, what do you use as the starting value for the axis?
McBainUK
I would use zero and work out from there until your range is covered. This will give you nice steps that are easily readable and sum together into an intelligible series (eg. imagine a series created by each of 0.25/0.5/1/2/5/10/25/50/100/250/etc added repeatedly).
Drew Noakes