图表轴的步长计算

本文关键字:计算 | 更新日期: 2023-09-27 18:28:02

我需要计算图表y轴的步长,以便它总是有7个刻度(通常是特定数量的刻度)。没有指定数据的范围,因此y轴的值可能类似于:

-2、2、3

-105、0.5、10

-5、10、80.6、120等

是否有任何算法(尤其是C#实现)可以计算图表始终具有相同刻度数的步长

F.e.号码:

-2,2,3它将是-4.5,-3,-1.5,0,1.5,3,4.5

-105,0.5,10它将是-125,-100,-75,-50,-25,0,25

非常感谢您的帮助:)

图表轴的步长计算

下面显示的实现是在python中实现的。如果你精通这两种语言,它的大多数元素都可以很容易地直接翻译成C#。少数语句可能需要一系列if语句或不同的方法。

在程序中,最后四行是主程序。如图所示,main有一个生成80个测试用例的循环,大小从0.04几何增加到大约200。如果您想更粗略地测试,请将40(尺寸数)更改为较小的数字,将1.24(几何比例)更改为较大的数字。对于每个测试的大小,main调用stepShow两次,第一次的测试范围从size的10%到size的110%,然后的测试范围是-28%到82%。stepShow是一个调用stepCalc的测试例程,CCD_6是一个包含计算leftTicktickSize的算法的例程,这两个值是最左边刻度的位置和刻度之间的间隔。

stepCalcspan = max(hiVal,0) - min(loVal,0)开始,确保x=0将适合刻度的范围。然后CCD_ 11计算不大于跨度的1/6的10的最大幂。(Python的//运算符返回一个整数结果,**表示取幂。)如果刻度大小可能在1到10之间,则multis = (1,1.5,2,3,5,10) if decade==1 else (1,2,5,10)将元组multis设置为(1,1.5,2,3,5,10),否则将其设置为(1,2,5,10)。循环中的代码CCD_ 16计算CCD_;当它们足够大时,它会脱离循环并返回它们。

在该程序的输出中,每个大小的两个测试用例通常具有相同的tickSize,但当然,第一种情况下leftTick为零,第二种情况下为负。以下是一些示例行。(完整输出显示在程序之后。)每个5数字组包括leftTick, loVal, hiVal, rightTick, tickSize的值。

0.000   0.101   1.109   1.200   0.200    -0.500  -0.282   0.826   2.500   0.500 
0.000   0.238   2.621   3.000   0.500    -1.000  -0.667   1.954   2.000   0.500 
0.000   0.295   3.250   6.000   1.000    -1.000  -0.827   2.423   5.000   1.000 
0.000   0.563   6.197   9.000   1.500    -3.000  -1.577   4.619   6.000   1.500 
0.000   0.866   9.528  12.000   2.000    -4.000  -2.425   7.103   8.000   2.000 
0.000   1.074  11.815  12.000   2.000    -6.000  -3.007   8.807  12.000   3.000 

对于某些大小,tickSize在两种情况下不同,如上面示例行的第一行和最后一行。尽管两种测试情况下的总跨度相同,即size的110%,但如果loValhiVal不再都适合较小的tickSize值所覆盖的跨度,则当0刻度不在范围的末尾时,需要较大的tickSize值。在multis元组中包含10处理这种情况。

def stepCalc(loVal, hiVal):
    import math
    span = max(hiVal,0) - min(loVal,0)  # have to have 0 in span
    decade = 10**(math.log(span/6.0)//math.log(10))
    multis = (1,1.5,2,3,5,10) if decade==1 else (1,2,5,10)
    for m in multis:
        tickSize = m * decade
        cover = 6.0 * tickSize;
        leftTick = 0 if loVal >= 0 else -cover if hiVal <= 0 else (loVal//tickSize)*tickSize
        if leftTick+cover >= hiVal: break
    return (leftTick, tickSize)
def stepShow(loVal, hiVal):
    (leftTick, tickSize) = stepCalc(loVal, hiVal)
    return ' {:7.3f} {:7.3f} {:7.3f} {:7.3f} {:7.3f} '.format(leftTick, loVal, hiVal, leftTick+6*tickSize, tickSize)
size = 0.04
for i in range(40):
    print stepShow(0.1*size, 1.1*size), stepShow(-0.28*size, 0.82*size)
    size *= 1.24

上面显示的代码并没有试图对称化记号的位置。如果你想做到这一点,你可以在return (leftTick, tickSize)之前添加代码,将leftTick减少tickSize的倍数,而hiVal之上的tickSize的倍数比loVal之下的要多。

程序输出:

0.000   0.004   0.044   0.060   0.010    -0.020  -0.011   0.033   0.040   0.010 
0.000   0.005   0.055   0.060   0.010    -0.020  -0.014   0.041   0.040   0.010 
0.000   0.006   0.068   0.120   0.020    -0.020  -0.017   0.050   0.100   0.020 
0.000   0.008   0.084   0.120   0.020    -0.040  -0.021   0.063   0.080   0.020 
0.000   0.009   0.104   0.120   0.020    -0.040  -0.026   0.078   0.080   0.020 
0.000   0.012   0.129   0.300   0.050    -0.050  -0.033   0.096   0.250   0.050 
0.000   0.015   0.160   0.300   0.050    -0.050  -0.041   0.119   0.250   0.050 
0.000   0.018   0.198   0.300   0.050    -0.100  -0.050   0.148   0.200   0.050 
0.000   0.022   0.246   0.300   0.050    -0.100  -0.063   0.183   0.200   0.050 
0.000   0.028   0.305   0.600   0.100    -0.100  -0.078   0.227   0.500   0.100 
0.000   0.034   0.378   0.600   0.100    -0.100  -0.096   0.282   0.500   0.100 
0.000   0.043   0.469   0.600   0.100    -0.200  -0.119   0.350   0.400   0.100 
0.000   0.053   0.581   0.600   0.100    -0.200  -0.148   0.433   0.400   0.100 
0.000   0.066   0.721   1.200   0.200    -0.200  -0.184   0.537   1.000   0.200 
0.000   0.081   0.894   1.200   0.200    -0.400  -0.228   0.666   0.800   0.200 
0.000   0.101   1.109   1.200   0.200    -0.500  -0.282   0.826   2.500   0.500 
0.000   0.125   1.375   3.000   0.500    -0.500  -0.350   1.025   2.500   0.500 
0.000   0.155   1.705   3.000   0.500    -0.500  -0.434   1.271   2.500   0.500 
0.000   0.192   2.114   3.000   0.500    -1.000  -0.538   1.576   2.000   0.500 
0.000   0.238   2.621   3.000   0.500    -1.000  -0.667   1.954   2.000   0.500 
0.000   0.295   3.250   6.000   1.000    -1.000  -0.827   2.423   5.000   1.000 
0.000   0.366   4.030   6.000   1.000    -2.000  -1.026   3.004   4.000   1.000 
0.000   0.454   4.997   6.000   1.000    -2.000  -1.272   3.725   4.000   1.000 
0.000   0.563   6.197   9.000   1.500    -3.000  -1.577   4.619   6.000   1.500 
0.000   0.699   7.684   9.000   1.500    -3.000  -1.956   5.728   6.000   1.500 
0.000   0.866   9.528  12.000   2.000    -4.000  -2.425   7.103   8.000   2.000 
0.000   1.074  11.815  12.000   2.000    -6.000  -3.007   8.807  12.000   3.000 
0.000   1.332  14.650  18.000   3.000    -6.000  -3.729  10.921  12.000   3.000 
0.000   1.651  18.166  30.000   5.000    -5.000  -4.624  13.542  25.000   5.000 
0.000   2.048  22.526  30.000   5.000   -10.000  -5.734  16.792  20.000   5.000 
0.000   2.539  27.932  30.000   5.000   -10.000  -7.110  20.822  50.000  10.000 
0.000   3.149  34.636  60.000  10.000   -10.000  -8.816  25.819  50.000  10.000 
0.000   3.904  42.948  60.000  10.000   -20.000 -10.932  32.016  40.000  10.000 
0.000   4.841  53.256  60.000  10.000   -20.000 -13.556  39.700  40.000  10.000 
0.000   6.003  66.037 120.000  20.000   -20.000 -16.810  49.228 100.000  20.000 
0.000   7.444  81.886 120.000  20.000   -40.000 -20.844  61.043  80.000  20.000 
0.000   9.231 101.539 120.000  20.000   -40.000 -25.846  75.693  80.000  20.000 
0.000  11.446 125.908 300.000  50.000   -50.000 -32.049  93.859 250.000  50.000 
0.000  14.193 156.127 300.000  50.000   -50.000 -39.741 116.385 250.000  50.000 
0.000  17.600 193.597 300.000  50.000   -50.000 -49.279 144.318 250.000  50.000