2013-07-12 31 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

这只会改变可见轴。我认为这与规模领域以及价值观如何映射到这个领域没有任何关系。 –

相关问题