线性X对数

2024-05-27 11:17:57 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一行X像素,如下所示:

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

如果0 <= V <= max,在线性尺度下V的位置将是X/max*V个像素。在

我如何计算一个对数刻度的像素位置,从像素位置开始,我如何得到V的值?在

  1. 这不是家庭作业
  2. 我想知道数学(请不要“使用FOO plotlib”注释)
  3. 我喜欢Python

对数刻度具有“缩放”刻度左侧的效果。有没有可能对右侧做同样的事情?在

[更新]

谢谢你的数学课!在

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

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

不对称的规模使细粒度调整更容易: enter image description here


Tags: 标记fooplotlib对数线性数学像素中心
3条回答
           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>;=1(V=1对应于pos=0,V=0..1对应于-inf..0,对于V<;0,没有定义对数)。在

所以你有一些任意值V,你知道0<;=V<;=Vmax。你想计算一个像素的x坐标,称之为X,其中“screen”的x坐标为0到Xmax。正如你所说,要用“正常”的方式来做,你应该这样做

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

我喜欢这样想,就像我首先通过计算V / Vmax将值规范化为介于0和1之间,然后将这个值乘以最大值,得到一个介于0和那个最大值之间的值。在

要在逻辑上执行相同的操作,您需要为V值设置一个不同的下限。如果V曾经是<;=0,则得到一个ValueError。假设0<;Vmin<;=V<;=Vmax。然后你需要找出使用什么对数,因为对数是无穷多的。通常会遇到三种情况,即基数为2、e和10的情况下,x轴如下所示:

^{pr2}$

所以原则上,如果我们能从左边的表达式中得到指数,我们可以用同样的原理来得到一个介于0和Xmax之间的值,当然这就是log的来源。假设您使用baseb,则可以使用以下表达式来回转换:

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)将给您一个非负值。通过在log函数中除以Vmin来实现这一点。现在你可以除以表达式所能产生的最大值,当然是log(Vmax / Vmin, b),你将得到一个介于0和1之间的值,与之前一样。在

另一种方法我们需要首先规范化(X / Xmax),然后再次放大(* logmax)到逆函数所期望的最大值。顺便说一下,相反的方法是将b提高到某个值。现在如果X为0,b ** (logmax * X / Xmax)将等于1,所以为了得到正确的下限,我们将Vmin相乘。或者换一种说法,因为我们做的第一件事就是用Vmin除,所以我们现在做的最后一件事就是用Vmin相乘。在

要“缩放”方程的“右侧”,您只需切换方程,这样您就可以从V到{}进行幂运算,并将对数取反方向。原则上,就是这样。因为你还得做一些事情,因为X可以是0:

logmax = log(Xmax + 1, b)
X = b ** (logmax * (V - Vmin) / (Vmax - Vmin)) - 1
V = (Vmax - Vmin) * log(X + 1, b) / logmax + Vmin

这可以很容易地扩展到其他功能。我对空间的度量是用字符而不是像素来表示的(这就是max==chars(或pixels))的原因。
只适用于正值。在

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。但该死的!真是这样!:-)

相关问题 更多 >

    热门问题