2013-07-12 116 views
3

我正在嘗試創建一個曼哈頓的情節,類似於下面所看到的情節。到目前爲止,我所擁有的都是遵循的。有沒有一種方法可以創建具有子域的域的比例?

這就是我試圖創建: This is what I'm trying to create

這是我到目前爲止已經編寫了(笑):

This is what I've coded up so far.

有決定的兩個因素x點的位置。 (1)染色體指數範圍從[1, 22],(2)位置座標範圍從[1, 10,000,000]。染色體指數越大,位置座標越大。

現在的問題是:如何設置位置座標的域,以便像第一張圖片中所示的那樣將點保留在染色體索引邊界內。

下面是一些相關的代碼:

var x0 = d3.scale.linear().range([0, width]), 
    x1 = d3.scale.linear().range([0, width]), 
    y = d3.scale.linear().range([height, 0]), 
xAxis = d3.svg.axis().scale(x0).orient("bottom"), 
yAxis = d3.svg.axis().scale(y).orient("left").tickPadding(6), 
color = d3.scale.category20c(); 

var positions = [], 
    pvalues = []; 
this.data.forEach(function (d) { 
    d.values.forEach(function (v) { 
     positions.push(v.position); 
     pvalues.push(v.pvalue); 
    }); 
}); 

var xMax = d3.max(positions), 
    ymax = d3.max(pvalues); 

x0.domain([1, 22]); 
x1.domain([0, xMax]); 
y.domain([0, ymax]); 

svg.append("g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + height + ")") 
    .call(xAxis); 

svg.append("g") 
    .attr("class", "y axis") 
    .call(yAxis) 
    .append("text") 
    .attr("class", "label") 
    .attr("transform", "rotate(-90)") 
    .attr("y", 8) 
    .attr("dy", ".71em") 
    .style("text-anchor", "end") 
    .text("p-value"); 

var chromosome = svg.selectAll(".chr") 
    .data(this.data) 
    .enter().append("g") 
    .attr("class", "chr") 
    .attr("x", function (d) { 
     return x0(d.chr); 
    }) 
    .attr("width", width/22) 
    .style("fill", function (d) { 
     return color(d.chr); 
    }); 

chromosome.selectAll("circle") 
    .data(function (d) { 
     return d.values; 
    }) 
    .enter().append("circle") 
    .attr("r", 3) 
    .attr("cx", function (d) { 
     return x1(d.position); 
    }) 
    .attr("cy", function (d) { 
     return y(d.pvalue); 
    }); 

更新:所以我切換到下面的grouped barchart example使用d3.scale.ordinal()兩個x尺度。我想我接近了,但現在,我應該如何防止在同一個x的位置上畫點? enter image description here

數據格式

this.data

[ 
    { 
    chr: 1, 
    values: [ 
     { 
     snp: rs182799, 
     position: 1478180, 
     pvalue: 3.26E-05 
     }, 
     { 
     snp: rs182349, 
     position: 1598180, 
     pvalue: 3.26E-05 
     }, 
    ... 
    ] 
    }, 

    chr: 2, 
    values: [ 
     { 
     snp: rs199799, 
     position: 2678180, 
     pvalue: 3.26E-05 
     }, 
     { 
     snp: rs182349, 
     position: 2998180, 
     pvalue: 3.26E-05 
     }, 
    ... 
    ] 
    }, 
    ... 
] 

回答

1

對主域名[1, 22]採取正確的措施。

對於每個主要橫座標[1, 1e7]的子域,要做到這一點的方法是爲每個橫座標生成一個比例尺。有關範圍的幾個問題應該首先回答:

  1. 是否positions均勻分佈?
  2. 在主圖表中,看起來子域的range隨主要橫座標增加而收縮(例如,x = 22的面積寬度遠小於x = 2)。做position對於每個染色體指數有相同的範圍[1, 1e7]

假設position[1, 1e7]均勻分佈的和的position最大值爲1e7所有染色體的索引(其似乎不是這種情況),這樣做的方式這將是nudgex軸子域內的每個圓的值:

chromosome.selectAll("circle") 
    // ... 
    .attr("cx", function (d, i) { 
     /* Assuming that data provided is in the "correct" order 
     * and `x1` is the ordinal scale. 
     */ 
     return x1(i) - x1.rangeBand()/2 + d.position/1e7; 
    }) 
    // ... 

在這裏,子域的scale是隱式的,而不是一個d3.scale

1

xMax是22,所以你不會得到比枚舉的1到22個成員以外的行中的任何點。this.data中的對象的最大值爲value.position,這意味着您使用染色體值來確定position。實際上,您希望使用非常細微的position值(從1到10000000)來確定點的實際x位置,但僅在圖形前端顯示數字1到22。據我可以告訴這是問題。

如果我們能看到this.data指的是什麼,這將有所幫助。

+0

我已經使用示例數據更新了帖子。 –

+0

如果將'xAxis = d3.svg.axis()。scale(x0)'更改爲'xAxis = d3.svg.axis()。scale(x1)'?會發生什麼? – Joey

+0

這隻會改變可見軸。我認爲這與規模領域以及價值觀如何映射到這個領域沒有任何關係。 –

相關問題