线性X对数刻度

Pau*_*ine 8 python math

给定X像素长的行像:

0-------|---V---|-------|-------|-------max
Run Code Online (Sandbox Code Playgroud)

如果0 <= V <= max,在线性比例V位置将是X/max*V像素.

如何计算对数刻度的像素位置,并从像素位置开始如何取回V的值?

  1. 这不是功课
  2. 我想知道数学(请不要"使用FOO-plotlib"评论)
  3. 我喜欢Python

对数刻度具有"缩放"刻度左侧的效果.相反,是否有可能为右侧做同样的事情?

[UPDATE]

谢谢你的数学课!

我最终没有使用对数.我只是使用平均值(在一组值中)作为比例的中心.此控件用于为将用于绘制等值线图的一组值选择组边界百分位数.

如果用户选择对称刻度(红色标记=平均值,绿色标记=中心,黑暗表示值的出现次数): 在此输入图像描述

不对称比例使细粒度调整更容易: 在此输入图像描述

Lau*_*low 14

所以你有一些任意值V,你知道0 <= V<= Vmax.你想要计算像素的x坐标,调用它X,你的"屏幕"的x坐标从0到Xmax.正如你所说,要做到这一点是"正常"的方式,你就行了

X = Xmax * V / Vmax
V = Vmax * X / Xmax
Run Code Online (Sandbox Code Playgroud)

我喜欢把它想象成我首先通过计算将值归一化到介于0和1之间V / Vmax,然后我将该值乘以最大值以获得介于0和最大值之间的值.

要以对数方式执行相同的操作,您需要为该V值设置不同的下限.如果V <= 0,你会得到一个ValueError.所以假设0 Vmin<< = V= Vmax.然后你需要找出使用什么对数,因为它们中有很多.通常遇到三个,那些有基数2,e和10,这导致x轴看起来像这样:

------|------|------|------|----      ------|------|------|------|----
    2^-1    2^0    2^1    2^2     ==       0.5     1      2      4

------|------|------|------|----      ------|------|------|------|----
    e^-1    e^0    e^1    e^2     ==       0.4     1     2.7    7.4

------|------|------|------|----      ------|------|------|------|----
    10^-1  10^0   10^1   10^2     ==       0.1     1     10     100
Run Code Online (Sandbox Code Playgroud)

所以原则上,如果我们可以从左边的表达式得到指数,我们可以使用与上面相同的原理来获得0和之间的值Xmax,这当然是日志的来源.假设你使用base b,你可以使用这些表达式来回转换:

from math import log
logmax = log(Vmax / Vmin, b)
X = Xmax * log(V / Vmin, b) / logmax
V = Vmin * b ** (logmax * X / Xmax)
Run Code Online (Sandbox Code Playgroud)

这几乎是相同的思维方式,除非你需要首先确保它log(somevalue, b)会给你一个非负值.你可以通过Vminlog函数内部进行划分来实现.现在你可以除以表达式可以产生的最大值,当然log(Vmax / Vmin, b),你将获得一个介于0和1之间的值,与之前相同.

另一种方式我们需要首先规范化(X / Xmax),然后再次(* logmax)向上扩展()到反函数所期望的最大值.b顺便说一句,反过来是提高到某个值.现在如果X为0,b ** (logmax * X / Xmax)则等于1,所以为了得到正确的下限,我们乘以Vmin.换句话说,因为我们以另一种方式做的第一件事就是除以Vmin,我们需要成倍增加,Vmin这是我们现在做的最后一件事.

要"缩放"等式的"右侧",您需要做的就是切换方程式,这样您VX可以取代,从而以相反的方式取对数.原则上,就是这样.因为你还必须对X可以为0 的事实做一些事情:

logmax = log(Xmax + 1, b)
X = b ** (logmax * (V - Vmin) / (Vmax - Vmin)) - 1
V = (Vmax - Vmin) * log(X + 1, b) / logmax + Vmin
Run Code Online (Sandbox Code Playgroud)