给定X像素长的行像:
Run Code Online (Sandbox Code Playgroud)0-------|---V---|-------|-------|-------max
如果0 <= V <= max,在线性比例V位置将是X/max*V像素.
如何计算对数刻度的像素位置,并从像素位置开始如何取回V的值?
对数刻度具有"缩放"刻度左侧的效果.相反,是否有可能为右侧做同样的事情?
[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)会给你一个非负值.你可以通过Vmin在log函数内部进行划分来实现.现在你可以除以表达式可以产生的最大值,当然log(Vmax / Vmin, b),你将获得一个介于0和1之间的值,与之前相同.
另一种方式我们需要首先规范化(X / Xmax),然后再次(* logmax)向上扩展()到反函数所期望的最大值.b顺便说一句,反过来是提高到某个值.现在如果X为0,b ** (logmax * X / Xmax)则等于1,所以为了得到正确的下限,我们乘以Vmin.换句话说,因为我们以另一种方式做的第一件事就是除以Vmin,我们需要成倍增加,Vmin这是我们现在做的最后一件事.
要"缩放"等式的"右侧",您需要做的就是切换方程式,这样您V就X可以取代,从而以相反的方式取对数.原则上,就是这样.因为你还必须对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)
| 归档时间: |
|
| 查看次数: |
3852 次 |
| 最近记录: |