显示从最小值到最大值的轴 - 计算比例和标签

时间:2013-02-17 17:22:09

标签: php algorithm php-gd axis-labels

编写例程以在水平轴上显示数据(使用PHP gd2,但这不是重点)。

轴从$min$max开始,并在$result显示一颗钻石,这样的图像宽约300像素,高30像素,如下所示:

example http://www.testwolke.de/profile.png

在上面的示例中,$min=0$max=3$result=0.6。 现在,我需要计算一个有意义的比例和标签,在上面的例子中,例如0 .25 .50 .75 1 1.25 ... up to 3处的虚线,数字标签位于0 1 2 3

如果$min=-200$max=600,虚线应位于-200 -150 -100 -50 0 50 100 ... up to 600,数字标签位于-200 -100 0 100 ... up to 600

$min=.02$max=5.80.02 .5 1 1.5 2 2.5 ... 5.5 5.8的虚线和.02 1 2 3 4 5 5.8的数字。

我试着明确地告诉函数将数据放在虚线和数字的位置,但是嘿,这是应该工作的计算机,而不是我,对吧?!

那么,如何计算???

4 个答案:

答案 0 :(得分:4)

ACM Algorithm 463提供了三个简单的函数来生成良好的轴刻度,输出xminp,xmaxp和dist用于刻度上的最小值和最大值以及刻度上刻度线之间的距离,给出{{1}的请求包含数据点nxmin的区间:

  1. xmax给出一个线性刻度,间隔大约为Scale1()n为整数倍,为1倍,2倍或5倍。
  2. dist给出一个线性刻度,其间隔为Scale2()(xminp和xmaxp之间的间隙往往大于n产生的间隙)。
  3. Scale1()给出对数刻度。
  4. 1973年的原始论文在线here,提供的解释比上面链接的代码更多。

    代码在Fortran中,但它只是一组算术计算,所以解释和转换成其他语言非常简单。我自己没有编写任何PHP,但它看起来很像C,所以你可能想要通过f2c运行代码来开始,这应该会给你一些接近在PHP中运行的东西。

    有更复杂的功能可以提供更漂亮的比例(例如Scale3()中的那些),但gnuplot可能会以最少的代码为您完成工作。

    (这个答案建立在我对上一个问题Graph axis calibration in C++

    的答案的基础上

    (编辑 - 我发现了我在Perl中执行的Scale1()):

    Scale1()

答案 1 :(得分:4)

算法(示例值$min=-186$max=+153作为限制):

  1. 取两个限制$min$max并在需要时标记

  2. 计算$max$min之间的差异:$diff = $max - $min
    153 - (-186) = 339

  3. 计算差异的第10个对数$base10 = log($diff,10) = 2,5302

  4. 向下舍入:$power = round($base10) = 2.
    这是你作为基本单位的第十个权力

  5. 要计算$step计算一下:
    $base_unit = 10^$power = 100;
    $step = $base_unit / 2; (如果你想要每个$base_unit 2个滴答。)

  6. 计算$min是否可以$step整除,如果不是最近的(向上)一个 (在$step = 50的情况下,$loop_start = -150

  7. for ($i=$loop_start; $i<=$max; $i++=$step){ // $i's are your ticks

  8. 我在Excel中进行了测试,结果非常好,您可能希望增加其功能,

    例如(在第5点),首先从$step计算$diff
    $step = $diff / 4可以整除$step的方式说出$base_unit并围绕$step;

    这样可以避免在(101; 201)四个刻度与$step=25之间出现这种情况,并且在0到999之间有39步$step=25

答案 2 :(得分:3)

我知道这并不是你想要的,但希望它会让你开始朝着正确的方向前进。

$min = -200;
$max = 600;
$difference = $max - $min;
$labels = 10;
$picture_width = 300;
/* Get units per label */
$difference_between = $difference / ($labels - 1);
$width_between = $picture_width / $labels;
/* Make the label array */
$label_arr = array();
$label_arr[] = array('label' => $min, 'x_pos' => 0);
/* Loop through the number of labels */
for($i = 1, $l = $labels; $i < $l; $i++) {
    $label = $min + ($difference_between * $i);
    $label_arr[] = array('label' => $label, 'x_pos' => $width_between * $i);
}

答案 3 :(得分:1)

一个简单的例子就是$increment = ($max-$min)/$scale中的某些内容,您可以将比例调整为增量所用的变量。由于你不遵守它,它应该随着你的最大值和最小值的变化而成比例地改变。之后,您将拥有如下功能:

$end = false;
while($end==false){
    $breakpoint = $last_value + $increment; // that's your current breakpoint
    if($breakpoint > $max){
        $end = true;
    } 
}

至少就是这个概念......如果你遇到麻烦,请告诉我。