2013-10-10 35 views
3

我正在使用dc.js,crossfilter.jsd3.js生成條形圖。生成高度歪斜的數據的直方圖

條形圖表示信用卡交易的數據。它繪製交易數量(Y軸)與交易金額(X軸)的關係。

它看起來像這樣:

Bar Chart

數據陣列基本上看起來像:

[ 
    ... 
    { 
    txn_id: 1, 
    txn_amount: 20 
    }, 
    ... 
] 

的數據變化很大取決於不同商家等,我不能做任何假設關於分配。

正如您所看到的,由於數據本身的原因,該圖並非全部有用。在這種情況下,在$7500附近有-$75002有1筆交易。

在其他金額之間,但大多數交易集中在$0 - $100附近,您可以看到高峯。

不幸的是,有足夠的差異,您甚至看不到交易金額較低的酒吧。

這個answer看起來很接近,但並不完全在那裏。

我真正想做的是將X軸刻度分成10個合理大小的塊,這些塊將事務量合理分組,以使圖更有用。

例如,在這種情況下,平均交易金額是$20。而極端的最小值和最大值是-$7500$7500

因此,在這個特殊的例子,我可能喜歡有x軸分塊起來像這樣:

Bin 1: -$1000 >= transaction amount 
Bin 2: -$100 >= transaction amount > -$1000 
Bin 3: -$50 >= transaction amount > -$100 
Bin 4: $0 >= transaction amount > -$50 
Bin 5: $15 >= transaction amount > $0 
Bin 6: $25 >= transaction amount > $15 
Bin 7: $40 >= transaction amount > $25 
Bin 8: $100 >= transaction amount > $40 
Bin 9: $1000 >= transaction amount > $100 
Bin 10: transaction amount > $1000 

(塊/箱的尺寸變小越小越接近我們得到的平均值)。

不可否認的是,自從我對統計學進行任何認真研究以來,這已經過了很多年了,所以我很生疏。但是,我認爲將數據分解成箱/卡盤的方式似乎與我的數據的標準偏差有很大關係。

我想我有我想要的好感覺,我只是有點失去了關於如何使用d3.jsd3.mean()d3.quantile()?)和dc.js以同樣獲得直方圖如何,我已經描述了。

那麼什麼是正確的方法,或者我應該使用什麼庫:

  1. 「合理」根據任意給定的數據大小的垃圾箱設置
  2. 將數據分組到這些塊創建10個(實際上,這部分應該是相當直截了當)

在物理間距直方圖的x軸而言,我不認爲對蜱被不均勻地間隔有必要或期望的(因此也許它不再是一個直方圖)。

儘管事實上塊大小不相等,但我更希望蜱保持均勻間隔。我將確保適當地標記標記。

任何正確的方向指針將不勝感激。

更新:

所以似乎d3.js是在我前面照例幾個步驟,並且已經得到了我的背部。我相信我可以使用d3.scale.quantile()將x軸分成10個分位數(十分位數)。事實上,我已經設置了分位數量級,並且它似乎正在做正確的事情,當我將數字直接輸入到分位數比例函數(通過JS控制檯)時,它會輸出正確的數據塊(超出10)。

但不幸的是我的圖表仍然搞砸了。這裏是我的代碼:

var datum = crossfilter(data), 
    amount = datum.dimension(function(d) { return +d.txn_amount; }), 
    amounts = amount.group(); 

amountsChart = dc.barChart("#dc-amounts-chart"); 
amountsChart 
    .width(defaultWidth) 
    .height(defaultHeight) 
    .margins({top: 20, right: 20, bottom: 20, left: 50}) 
    .dimension(amount) 
    .group(amounts) 
    .centerBar(true) 
    .gap(5) 
    .elasticY(true) 
    .x(d3.scale.quantile().domain(amounts.all().map(function(d) { 
          // d.key is the transaction dollar amount, 
          // d.value is the number of transactions at that amount 
          return d.key; 
         })) 
         .range([0,1,2,3,4,5,6,7,8,9])); 

amountsChart.yAxis().ticks(5); 

dc.renderAll(); 

所得圖表:

Quantiled Bar Chart

我覺得我越來越近,但還是不知道在哪裏,我採取了錯誤的轉彎。

+0

突破它爲十個等分位數:HTTP://www.bmj。com/content/309/6960/996 – bozdoz

回答

1

您可以使用異常值測試修剪掉您的異常值,然後將它們添加回極端箱。我也會將這些箱子上的文字更改爲y,但可以通過將自定義的一組滴答傳遞給該軸來輕鬆完成。

我嘲笑了一個例子,使用Chauvenet's criterion,一個異常測試之一。我原本以爲要使用Grubbs測試(或者甚至更好的多個Grubbs Beck測試),但是有一些工作需要編碼。 Chauvenet的標準很簡單地通過假設任何大於m的標準偏差的值是異常值。

我已經把這個一起here和功能是:

function chauvenet (x) { 
    var dMax = 3; 
    var mean = d3.mean(x); 
    var stdv = Math.sqrt(variance(x)); 
    var counter = 0; 
    var temp = []; 

    for (var i = 0; i < x.length; i++) { 
     if(dMax > (Math.abs(x[i] - mean))/stdv) { 
      temp[counter] = x[i]; 
      counter = counter + 1; 
     } 
    }; 

    return temp 
} 

條款都相當明顯,DMAX是標準偏差的數量,意思是均值和STDV是標準差(或方差的平方根)。

注意我沒有將異常值添加到直方圖中,但這應該很容易做到。

+0

謝謝你的回答。這很棒。因爲看起來完全合理,我可能最終會走這條路。儘管我的圖表存在問題,但我仍然感到困惑,因爲從理論上講,將我的數據分成10個相等的十分位數(相當於每個存儲桶中數據點的數量),應該做到這一點。我可以看到我的分位數是正確的,但該圖與分位數比例表現不佳。 – lostdorje

0

如果D3是給你一個很難..試試這個http://imaginea.github.com/uvCharts :) 你一定已經知道nvd3

+0

謝謝,有趣的看到另一個圖表庫。 d3不是給我的問題,而是dc.js.我之前使用nvd3取得了很大的成功,但是他們沒有內置交叉過濾器集成和過濾功能,這對我們來說非常重要。不幸的是,我們在這一點上已經投入了足夠的資金,我暫時沒有看到我們切換圖形庫。 – lostdorje