2011-12-21 59 views
1

我想創建一個折線圖,但數字的範圍是不同的,有時它像:如何確定的數字範圍的正確的域用於繪製線圖?

1,2,5,8,10

,有時它像:

-5, - 1,4,5,15,第8,20,...

通過研究的Excel和OpenOffice我理解,他們可以指明的範圍是這樣的:

minNumber - k到MAXNUMBER + K

和它們劃分Y軸成相等的區域。

有沒有做這些事情的具體公式?

回答

1

當我看到這個問題時,我發現商業產品在擴展範圍方面做得非常好,足以實現令人滿意的圓形數字作爲刻度。如果這是你有興趣,就來看看這個C#代碼,我寫了嘗試不同的算法:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace TickPicker 
{ 
    class TickPicker 
    { 
     double tickLow; 
     double tickHigh; 
     double tickUnit; 
     double tickCount; 
     //static double[] targetUnits = { 1, 2, 5, 10 }; 
     static double[] targetUnits = { 1, 2, 2.5, 5, 10 }; 
     static int[] roundFactors = { 1, 5, 4, 2, 1 }; 
     //static double[] targetUnits = { 1, 1.5, 2.5, 5, 10 }; 
     //static double[] targetUnits = { 1, 1.25, 2, 2.5, 5, 10 }; 
     //static double[] targetUnits = { 1, 1.25, 1.5, 2, 2.5, 5, 10 }; 
     //static double[] targetUnits = { 1, 1.25, 2, 5, 10 }; 
     //static double[] targetUnits = { 1, 1.25, 1.5, 2, 5, 10 }; 
     static double[] targetLogs = arrayLog(targetUnits); 

     TickPicker(double low, double high, int tickCountGoal) 
     { 
      double range = high - low; 
      double divGoal = range/(tickCountGoal - 2); 
      double logGoal = Math.Log10(divGoal); 
      double powerFactor = Math.Floor(logGoal); 
      logGoal = logGoal - powerFactor; 
      int closestIndex = findClosest(targetLogs, logGoal); 
      tickUnit = targetUnits[closestIndex] * (Math.Pow(10, powerFactor)); 
      // Ensure the actual range encompasses the intended range 
      // The roundFactor discourages the .5 on the low and high range 
      int roundFactor = roundFactors[closestIndex]; 
      tickLow = Math.Floor(low/tickUnit/roundFactor) * tickUnit * roundFactor; 
      tickHigh = Math.Ceiling(high/tickUnit/roundFactor) * tickUnit * roundFactor; 
      tickCount = (tickHigh - tickLow)/tickUnit; 
     } 

     static double[] arrayLog(double[] inputs) 
     { 
      double[] retVal = new double[inputs.Length]; 
      int x = 0; 
      foreach (double input in inputs) 
      { 
       retVal[x] = Math.Log10(inputs[x]); 
       x++; 
      } 
      return retVal; 
     } 

     static int findClosest(double[] candidates, double input) 
     { 
      int low = 0; 
      for(int i = 1; i < candidates.Length && input > candidates[i]; i++) 
      { 
       low = i; 
      } 
      int high = low + 1; 
      return candidates[high] - input < input - candidates[low] ? high : low; 
     } 

     static void testPicker(double low, double high, int tickCountGoal) 
     { 
      TickPicker picker = new TickPicker(low, high, tickCountGoal); 
      System.Console.WriteLine("[{0}:{1}]/{2} gives [{3}:{4}] with {5} ticks of {6} units each.", low, high, tickCountGoal, picker.tickLow, picker.tickHigh, picker.tickCount, picker.tickUnit); 
     } 

     static void Main(string[] args) 
     { 
      testPicker(4.7, 39.2, 13); 
      testPicker(4.7, 39.2, 16); 
      testPicker(4.7, 39.2, 19); 
      testPicker(4.7, 39.2, 21); 
      testPicker(4.7, 39.2, 24); 
      testPicker(1967, 2011, 20); 
      testPicker(1967, 2011, 10); 
      testPicker(2.71, 3.14, 5); 
      testPicker(.0568, 13, 20); 
     } 
    } 
} 
+0

coooooooooool這就是我所能說的。 – 2011-12-23 17:16:16

+0

想知道你是怎麼結束這個算法的?實際上熱衷於更多地瞭解這些問題以及如何解決這些問題。感謝您是否可以給我建議。 – 2011-12-24 02:04:17

+1

我沒有一個正式的算法,儘管可能有它的名字,我只是無知。我只知道它必須是對數的,並且在這個時候擺弄它。 – 2011-12-24 03:54:25

1

我認爲你的意思是minNumber而不是意味着數字。

的公式是接近你說什麼。你的範圍是maxNumber - minNumber。如果你想在任何一方添加2k空間,其中k是任何一方的空間。你知道你的圖是Y像素寬。 Y /範圍是圖形每單位有多少個像素。

您在繪製圖形時主要應用此調整。根據你的最小值,然後根據你的像素/單位應用一個移位。

所以繪製點X意味着您實際上以((X - min)/像素/單位)繪圖。

1

我並不是100%確信這是一個編程問題(儘管可以使用一小部分圖形庫),但總體思路是這樣的。

你有這些點進來,讓我們說-5。這是我們收到的第0個值,因此對於0的x值,我們把-5在y軸。我們重複了-1,4等

所以,你會得到一個列表看起來像這樣(比喻):

X | Y 
0 | -5 
1 | -1 
2 | 4 
3 | 5 
4 | 15 

結果是散點圖(不是線),但有是Excel中的工具,可以幫助你。

[編輯]爲了得到它作爲實際的功能,可以使用以下形式:

的y Y_1 = M(X-X_1)

,其中M =(Y_2-Y_1)/( X_2-X_1),Y_2是你的最高y值,Y_1是你最低的,X_2是您最高的x值,和X_1是你最低的。

+0

假設我們有很多的數字說,像1000,然後顯示在X這些多號軸是不正確的,並且在Y軸上顯示每個精確值也不好,這就是爲什麼我們需要有一個範圍。我知道有很多libs,但我正在尋找的算法! – 2011-12-21 20:12:57

+0

我不是100%確定我理解你的問題。你是說你正在尋找一個算法來繪製1,000或更多的數字,或者只是極端點?上面的公式[(線性方程式)](http://en.wikipedia.org/wiki/Linear_equation)會給你這條線,如果你只是採取數據集中的兩個極端點。 – Makoto 2011-12-21 21:08:43