使用最小值、最大值和离散值创建对数刻度 "steps"
Creating a Logarithm Scale with Min, Max and Discrete "steps"
我正在构建一个比例尺来为地图生成颜色,其中不同范围的数字对应于颜色。在下面的比例尺中,a
、b
和 c
值(连同最小值和最大值)形成与颜色对应的“步长”或“桶”。在此示例中,-1
和 min
之间的任何内容都将着色为 "#ffeda0
,而 min
和 a
之间的任何内容将以不同的方式着色:
return [
"#e7e9e9",
-1,
"#ffeda0",
min,
"#fed976",
a
"#feb24c",
b
"#fd8d3c",
c
"#fc4e2a",
max
"#e31a1c"
];
此比例始终以最小值 min 开始,以最大值 max 结束。我目前有一个像这样的简单线性比例尺:
const min = Math.min(data);
const range = Math.max(data) - min;
const step = range / 4;
return [
"#e7e9e9",
-1,
"#ffeda0",
min,
"#fed976",
min + step,
"#feb24c",
min + step * 2,
"#fd8d3c",
min + step * 3,
"#fc4e2a",
max,
"#e31a1c"
];
如何编写一个函数,给定最小值、最大值和刻度中的步数(在本例中为三)输出 对数 的正确数字规模?
对数标度的对数是线性的。所以:
const min = Math.min(data);
const max = Math.max(data);
const logmin = Math.log(min);
const logmax = Math.log(max);
const logrange = logmax - logmin;
const logstep = logrange / 4;
现在线性刻度有
value = min + n * step;
对数刻度有:
value = Math.exp(logmin + n * logstep);
这仅在 min
和 max
均为正数时有效,因为您不能取零或负数的对数,并且在对数标度中,每个值都有一个常数正因子到上一个。您可以通过调整符号使负 min
和 max
起作用。
您可以在其他基数中进行计算,例如 10:
const logmin = Math.log10(min);
const logmax = Math.log10(max);
value = Math.pow(10, logmin + n * logstep);
或者,您可以通过取最小值和最大值的商的第 n 次根来求出一步到下一步的公因数:
const min = Math.min(data);
const max = Math.max(data);
const fact = Math.pow(max / min, 1.0 / 4.0);
然后通过重复乘法找到值:
value = prev_value * fact
或
value = xmin * Math.pow(fact, n);
这两种方法都可能产生“不整洁”的数字,即使比例应该有很好的整数,因为对数和 n-th 根可能会产生不准确的 floating-point 结果.如果您选择一个舍入因子并调整您的 min/max 值,您可能会得到更好的结果。
我正在构建一个比例尺来为地图生成颜色,其中不同范围的数字对应于颜色。在下面的比例尺中,a
、b
和 c
值(连同最小值和最大值)形成与颜色对应的“步长”或“桶”。在此示例中,-1
和 min
之间的任何内容都将着色为 "#ffeda0
,而 min
和 a
之间的任何内容将以不同的方式着色:
return [
"#e7e9e9",
-1,
"#ffeda0",
min,
"#fed976",
a
"#feb24c",
b
"#fd8d3c",
c
"#fc4e2a",
max
"#e31a1c"
];
此比例始终以最小值 min 开始,以最大值 max 结束。我目前有一个像这样的简单线性比例尺:
const min = Math.min(data);
const range = Math.max(data) - min;
const step = range / 4;
return [
"#e7e9e9",
-1,
"#ffeda0",
min,
"#fed976",
min + step,
"#feb24c",
min + step * 2,
"#fd8d3c",
min + step * 3,
"#fc4e2a",
max,
"#e31a1c"
];
如何编写一个函数,给定最小值、最大值和刻度中的步数(在本例中为三)输出 对数 的正确数字规模?
对数标度的对数是线性的。所以:
const min = Math.min(data);
const max = Math.max(data);
const logmin = Math.log(min);
const logmax = Math.log(max);
const logrange = logmax - logmin;
const logstep = logrange / 4;
现在线性刻度有
value = min + n * step;
对数刻度有:
value = Math.exp(logmin + n * logstep);
这仅在 min
和 max
均为正数时有效,因为您不能取零或负数的对数,并且在对数标度中,每个值都有一个常数正因子到上一个。您可以通过调整符号使负 min
和 max
起作用。
您可以在其他基数中进行计算,例如 10:
const logmin = Math.log10(min);
const logmax = Math.log10(max);
value = Math.pow(10, logmin + n * logstep);
或者,您可以通过取最小值和最大值的商的第 n 次根来求出一步到下一步的公因数:
const min = Math.min(data);
const max = Math.max(data);
const fact = Math.pow(max / min, 1.0 / 4.0);
然后通过重复乘法找到值:
value = prev_value * fact
或
value = xmin * Math.pow(fact, n);
这两种方法都可能产生“不整洁”的数字,即使比例应该有很好的整数,因为对数和 n-th 根可能会产生不准确的 floating-point 结果.如果您选择一个舍入因子并调整您的 min/max 值,您可能会得到更好的结果。