首页 > 解决方案 > 对于给定的数字范围,用 1-2-5-ticks 标记坐标轴

问题描述

有点不清楚的问题Exponential Graph Animation P5js Canvas包含有关以编程方式为各种范围标记轴的有趣细节。我立刻想起了gnuplot做了我搜索的事情。通过交互式放大预览窗口(并且没有任何特定的刻度规范),我观察到它会自动选择一个标签方案,其数量在 4 到 10 个刻度之间,固定距离为 1、2 或 5 倍的 10 次幂.

以下4个例子可以作为这个交互过程的快照。

gnuplot> set xrange [0:1]
gnuplot> set yrange [0:exp(1)]
gnuplot> plot exp(x)

xrange 0..1 中的 exp(x) 函数

gnuplot> set xrange [0:2]
gnuplot> set yrange [0:exp(2)]
gnuplot> plot exp(x)

xrange 0..2 中的 exp(x) 函数

gnuplot> set yrange [0:exp(5)]
gnuplot> set xrange [0:5]
gnuplot> plot exp(x)

xrange 0..5 中的 exp(x) 函数

gnuplot> set yrange [0:exp(10)]
gnuplot> set xrange [0:10]
gnuplot> plot exp(x)

xrange 0..10 中的 exp(x) 函数

要实施这样的标记方案, 我如何找到给定范围的理想 1-2-5-tick 距离?
(使用伪代码或一些常用语言,如 JavaScript 或 Python)

标签: algorithmplotlanguage-agnosticaxis-labels

解决方案


要从range( 0..max) 中获得这些 1-2-5-tick 方案之一,我们必须将数量级 ( exponent) 和数字 ( mantissa) 分开,并找到低于或等于的最合适的数字 (1、2 或 5)到 a 的最高位representative

在 JavaScript 中查看这样的函数:

// find 1-2-5-tick distance for a given range
function tick_distance(range) {
  let find_factor = function(v) {
    if (v >= 5) {
      v = 5;
    } else if (v >= 2) {
      v = 2;
    } else if (v >= 1) {
      v = 1;
    }
    return v;
  };

  let representative = range * 0.24
  let l10 = Math.log10(representative);
  let exponent = Math.floor(l10);
  let mantissa = l10-exponent;
  let realdist = Math.pow(10, mantissa);
  let factor = find_factor(realdist);
  let dist = factor * Math.pow(10, exponent);
  return dist;
}

的启发式因子给出0.24representative4 到 10 之间变化数量级的滴答计数;0.23也可以工作,而0.25仅针对2*10^n.

  • 0.22有时给出 11 个刻度
  • 2.26有时给出 3 个刻度

我承认我自己对这个因素的“确切价值”感兴趣。


推荐阅读