Линейный X логарифмический масштаб

Дана строка X пикселей, таких как:

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

если 0 <= V <= max, в линейной шкале V будет X/max*V пикселей.

как я могу вычислить положение пикселя для логарифмической шкалы и, начиная с положения пикселя, как я могу вернуть значение V?

  1. это не домашнее задание
  2. я хочу знать математику (нет комментариев" использовать FOO-plotlib", пожалуйста)
  3. мне нравится Питон

логарифмическая шкала имеет эффект "масштабирования" с левой стороны шкалы. Можно ли сделать то же самое для правой стороны?

[обновление]

Спасибо за уроки математики!

Я закончил тем, что не использовал логарифмы. Я просто использовал среднее значение (в наборе значений) в качестве центра шкалы. Этот элемент управления используется для выбора групповых граничных процентилей для набора значений, которые будут использоваться для choropleth chart.

если пользователь выбирает симметричную шкалу (красная метка=средняя, зеленая метка=центр, темнота представляет количество вхождений значения): enter image description here

асимметричная шкала облегчает мелкозернистой корректировки : enter image description here

3 ответов


Итак, у вас есть произвольное значение V, а вы знаете, что 0 V Vmax. Вы хотите вычислить координату X пикселя, назовите ее X, где ваш "экран" имеет X-координаты от 0 до Xmax. Как вы говорите, чтобы сделать это "нормальным" способом, вы бы сделали

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

мне нравится думать об этом, как будто я сначала нормализую значение между 0 и 1, вычисляя V / Vmax, а потом умножьте это значение на максимум, чтобы получить значение между 0 и максимальный.

сделать то же самое logaritmically вам нужен другой нижний предел V значение. Если V когда-либо 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

Итак, в принципе, если мы можем получить показатели из выражений слева, мы можем использовать тот же принцип, что и выше, чтобы получить значение между 0 и Xmax, и это, конечно, где войти. Предполагая, что вы используете базу 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 внутри


           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


Это можно легко расширить для других функций. Моя мера пространства задается в символах вместо пикселей(вот почему 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. Но черт побери ! это так ! :-)