1

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

-2, 2, 3

-105, 0.5, 10

-5、10、80.6、120 等

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

Fe代表数字:

-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

非常感谢您的帮助:)

4

1 回答 1

1

下面显示的实现是在 python 中。如果您精通两种语言,它的大多数元素都可以轻松直接地翻译成 C#。一些陈述可能需要一系列if陈述或不同的方法。

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

stepCalcspan = max(hiVal,0) - min(loVal,0)which 开始,确保 x=0 适合刻度范围。然后decade = 10**(math.log(span/6.0)//math.log(10))计算不大于跨度 1/6 的 10 的最大幂。(Python 的//运算符返回一个整数结果并**表示求幂。 )如果刻度大小可能介于 1 和 10 之间,则将multis = (1,1.5,2,3,5,10) if decade==1 else (1,2,5,10)元组设置为 (1,1.5,2,3,5,10),否则将其设置为 (1,2 multis,5,10)。循环中的代码for m in multis:计算tickSizeleftTick值;当它们足够大时,它会跳出循环并返回它们。

在该程序的输出中,每个大小的两个测试用例通常具有相同的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两种情况之间有所不同,如上面示例行的第一行和最后一行。尽管两个测试用例中的总跨度相同,为 110% sizetickSize但当 0 刻度不在范围末尾时,如果loValhiVal不再适合较小值覆盖的跨度,则需要较大的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

上面显示的代码不会尝试使刻度的位置对称。如果你想这样做,你可以添加代码 beforereturn (leftTick, tickSize)减少leftTick的倍数,tickSizetickSizeabove的倍数hiVal比 below的倍数多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 
于 2013-08-19T07:32:03.063 回答