I am plotting some float data in a 2D graph and I need to calibrate the axis of graph into small units that looks neat. Obviously this unit varies based on magnitude of the data. I am trying to find out a good way to divide the axis into nice looking number. for example if my data runs from -1.3345 to +5.882 may be divide in units of 1.0 or 0.5. if my data us from -100 to 800 divide the axes into units of 100 or 50. (I hope that makes sense) right now I am dividing the range (largest value - lowest value) by some fixed integer and getting the units but that gives me ugly looking number with long trailing digits. Is there any smart way of doing this?
2 回答
One way to calculate a good step would be to find the value of the most significant digit of the range's length (i.e. the diff = maxVlaue - minValue
), and use that as your step. To calculate the value of the most significant digit use this simple formula:
pow(10, floor(log10(diff)))
This takes a decimal logarithm of the difference, discards the fractional part, if any, and raises ten to the power of that logarithm. For a difference of 7.2165, the calculation would return 1; for 721.65, it would return 100, and so on.
One shortcoming of this calculation is that the grid step for the diff
of 9.99 and the diff
of 1.001 would be the same. One way to address this would be to calculate the number of grid lines you'd get for the step, and decrease the step ten times if the number of lines is insufficient (say, less than three).
ACM Algorithm 463 provides three simple functions to produce good axis scales with outputs xminp, xmaxp and dist for the minimum and maximum values on the scale and the distance between tick marks on the scale, given a request for n
intervals that include the data points xmin
and xmax
:
Scale1()
gives a linear scale with approximatelyn
intervals anddist
being an integer power of 10 times 1, 2 or 5.Scale2()
gives a linear scale with exactlyn
intervals (the gap between xminp and xmaxp tends to be larger than the gap produced byScale1()
).Scale3()
gives a logarithmic scale.
The code is in Fortran but it is very straightforward to interpret and convert into other languages. There are more complicated functions that give prettier scales (e.g. the ones in gnuplot
), but Scale1 would likely do the job for you with minimal code.
(EDIT)
I found the text of the original 1973 paper online here, which provides more explanation than the code linked to above.