线性X对数刻度

时间:2011-12-21 07:12:27

标签: python math

给定一行X像素长度:

0-------|---V---|-------|-------|-------max

如果0 <= V <= max,则线性比例V位置将为X/max*V像素。

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

  1. 这不是家庭作业
  2. 我想知道数学(请不要“使用FOO-plotlib”评论)
  3. 我喜欢Python
  4. 对数刻度具有“缩放”刻度左侧的效果。是否有可能为右侧做同样的事情?

    [UPDATE]

    感谢数学课程!

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

    如果用户选择对称刻度(红色标记=平均值,绿色标记=中心,黑暗表示值的出现次数): enter image description here

    非对称比例使细粒度调整更容易: enter image description here

3 个答案:

答案 0 :(得分:14)

所以你有一些任意值V,而且你知道0&lt; = V&lt; = Vmax。您想要计算像素的x坐标,将其称为X,其中“屏幕”的x坐标从0到Xmax。正如你所说,要做到“正常”的方式,你要做

X = Xmax * V / Vmax
V = Vmax * X / Xmax

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

要进行相同的logaritmically,您需要V值的不同下限。如果V始终<= 0,则得到ValueError。所以我们说0&lt; Vmin&lt; = V&lt; = 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

所以原则上,如果我们可以从左边的表达式得到指数,我们就可以使用与上面相同的原理得到一个介于0和Xmax之间的值,这当然是log来的地方在。假设您使用基础b,您可以使用这些表达式来回转换:

from math import log
logmax = log(Vmax / Vmin, b)
X = Xmax * log(V / Vmin, b) / logmax
V = Vmin * b ** (logmax * X / Xmax)

这几乎是相同的思维方式,除了你需要首先确保log(somevalue, b)会给你一个非负值。您可以在Vmin函数中除以log来执行此操作。现在你可以除以表达式可以产生的最大值,当然是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

答案 1 :(得分:2)

           Linear               Logarithmic
Forward    pos = V * X/max      pos = log(V) * X/log(max)
Reverse    V = pos * max/X      V = B^( pos * log(max)/X )

(B是对数的基础)

显然你必须确保V&gt; = 1(V = 1将对应于pos = 0,V = 0..1对应于-inf..0,而对于V&lt; 0对数未定义)。< / p>

答案 2 :(得分:2)

这可以很容易地扩展到其他功能。我的空间度量是以字符而不是像素给出的(这就是为什么max == chars(或像素)) 仅适用于正值。

import math

def scale(myval, mode='lin'):
    steps = 7
    chars = max = 10 * steps

    if mode=='log':
        val = 10 * math.log10(myval)
    else:
        val = myval

    coord = []
    count = 0
    not_yet = True
    for i in range(steps):
        for j in range(10):
            count += 1
            if val <= count and not_yet:
                coord.append('V')
                not_yet = False
                pos = count
            elif j==9:
                coord.append('|')
            else:
                coord.append('*')

    graph = ''.join(coord)
    text = 'graph %s\n\n%s\nvalue = %5.1f   rel.pos. = %5.2f\n'
    print  text % (mode, graph, myval, chars * pos/max) 


scale(50, 'lin')
scale(50, 'log')

enter image description here

希望以上不被认为是FOO-plotlib。该死的!这是啊! : - )