2011-12-21 38 views
7

Cho một dòng X pixel dài như:tuyến tính X Logarithmic quy mô

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

Nếu 0 <= V <= max, quy mô tuyến tính V vị trí sẽ là X/max*V pixel.

Làm cách nào để tính vị trí pixel cho thang đo logarit và bắt đầu từ vị trí pixel làm cách nào để lấy lại giá trị của V?

  1. Nó không phải là bài tập về nhà
  2. Tôi muốn biết các môn toán (không "sử dụng FOO-plotlib" ý kiến, xin vui lòng)
  3. Tôi thích Python

Một thang logarit có tác dụng "phóng to" phía bên trái của thang đo. Có thể làm điều tương tự cho phía bên phải thay thế không?

[UPDATE]

Cảm ơn các bài học toán!

Tôi đã không sử dụng logarit. Tôi đã sử dụng giá trị trung bình (trong một tập hợp các giá trị) làm trung tâm của thang đo. Điều khiển này được sử dụng để chọn các phần trăm ranh giới nhóm cho một tập hợp các giá trị sẽ được sử dụng để vẽ một choropleth chart.

Nếu người dùng chọn một quy mô đối xứng (màu đỏ đánh dấu = trung bình, đánh dấu màu xanh lá cây = trung tâm, bóng tối đại diện cho số lần xuất hiện của một giá trị): enter image description here

Một quy mô không đối xứng làm cho điều chỉnh hạt mịn dễ dàng hơn: enter image description here

+0

ghi lại tất cả các giá trị và phần còn lại là như nhau. hãy cẩn thận rằng bạn không thể có số không (log (0) là neg. inf) cũng không vượt qua dấu hiệu – yosukesabai

+0

@yosukesabai: bất kỳ gợi ý nào về cách xử lý các giá trị rất thấp của 'max'? –

+2

Đó là '(X/max) * V', và đẹp hơn để đọc là' X * V/max' – wim

Trả lời

13

Vì vậy, bạn đã có một số giá trị tùy ý V, và bạn biết rằng 0 < = V < = Vmax. Bạn muốn tính tọa độ x của pixel, gọi nó là X, trong đó "màn hình" của bạn có tọa độ x từ 0 đến Xmax. Như bạn nói, để làm điều này một cách "bình thường", bạn sẽ làm

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

Tôi thích nghĩ về nó như tôi đầu tiên bình thường hóa các giá trị nằm giữa 0 và 1 bằng cách tính toán V/Vmax, và sau đó Tôi nhân giá trị này với giá trị tối đa để nhận giá trị từ 0 đến giá trị tối đa đó.

Để thực hiện cùng một lôgarit, bạn cần giới hạn dưới khác nhau cho giá trị V. Nếu V là bao giờ < = 0, bạn nhận được một ValueError. Vì vậy, giả sử 0 < Vmin < = V < = Vmax. Sau đó, bạn cần tìm hiểu những gì lôgarit để sử dụng, vì có vô số trong số chúng.Ba đang gặp phải thường, những người có cơ sở 2, e và 10, mà kết quả trong trục x mà trông như thế này:

------|------|------|------|----  ------|------|------|------|---- 
    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 

Vì vậy, về nguyên tắc, nếu chúng ta có thể có được ở các số mũ từ các biểu thức bên trái, . chúng ta có thể sử dụng cùng một nguyên tắc như trên để có được một giá trị từ 0 Xmax, và điều này là tất nhiên nơi log do thỏa thuận hợp Giả sử bạn sử dụng cơ sở b, bạn có thể sử dụng các biểu thức để chuyển đổi qua lại:

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

Đó là cách suy nghĩ tương tự, ngoại trừ trước tiên bạn cần đảm bảo rằng log(somevalue, b) sẽ cung cấp cho bạn thông tin không phải là negativ giá trị điện tử. Bạn làm điều này bằng cách chia cho Vmin bên trong hàm log. Bây giờ bạn có thể chia cho giá trị tối đa mà biểu thức có thể mang lại, tất nhiên là log(Vmax/Vmin, b) và bạn sẽ nhận được một giá trị từ 0 đến 1, giống như trước đây.

Cách khác, trước tiên chúng ta cần chuẩn hóa (X/Xmax), sau đó mở rộng lại (* logmax) đến mức tối đa được mong đợi bởi funciton nghịch đảo. Ngược lại, để tăng giá trị b lên một số giá trị. Bây giờ nếu X là 0, b ** (logmax * X/Xmax) bằng 1, vì vậy để có giới hạn dưới chính xác, chúng tôi nhân với Vmin. Hay nói cách khác, vì điều đầu tiên chúng tôi làm theo cách khác là chia cho Vmin, chúng ta cần nhân với Vmin là điều cuối cùng chúng ta làm bây giờ.

Để "thu phóng" phía bên phải "của phương trình, tất cả những gì bạn cần làm là chuyển đổi các phương trình, vì vậy bạn sẽ tăng số mũ từ V đến X và thực hiện theo lôgarit. Về nguyên tắc, đó là. Bởi vì bạn cũng đã có làm điều gì đó với thực tế là X có thể là 0:

logmax = log(Xmax + 1, b) 
X = b ** (logmax * (V - Vmin)/(Vmax - Vmin)) - 1 
V = (Vmax - Vmin) * log(X + 1, b)/logmax + Vmin 
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 là logarit của cơ sở)

Rõ ràng, bạn phải đảm bảo rằng V> = 1 (V = 1 sẽ tương ứng với pos = 0, V = 0..1 tương ứng với -inf..0, và đối với V < 0 logarit không được xác định).

2

Điều này có thể dễ dàng mở rộng cho các chức năng khác. Thước đo không gian của tôi được đưa ra trong ký tự thay vì pixel (đó là lý do tại sao max == ký tự (hoặc pixel)).
Chỉ dành cho các giá trị dương.

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

Hy vọng ở trên không được coi FOO-plotlib. Nhưng chết tiệt! đây là SO! :-)

Các vấn đề liên quan