3

我正在尝试创建一个曼哈顿情节,类似于下面看到的情节。到目前为止,我所拥有的已经被遵循。

这就是我要创建的内容: 这就是我想要创造的

这是我迄今为止编写的代码(大声笑):

这是我到目前为止编写的代码。

有两个因素决定了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);
    });

更新:所以我按照分组条形图示例d3.scale.ordinal()切换到使用两种x比例尺。我想我离得更近了,但是,现在,我如何防止点被画在同一个位置? x在此处输入图像描述

数据格式

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
      },
    ...
    ]
  },
  ...
]
4

2 回答 2

1

xMax是 22,所以除了从 1 到 22 的枚举成员之外,您不会在一行上得到任何点。其中的对象this.data最多value.position为 22,这意味着您正在使用染色体值来确定position. 实际上,您希望使用非常细粒度的position值(从 1 到 10000000)来确定点的实际 x 位置,但仅在图形前端显示数字 1 到 22。据我所知,这是问题所在。

如果我们能看到this.data指的是什么,那将会有所帮助。

于 2013-07-12T19:06:40.567 回答
1

转移到序数规模是对主要领域的正确做法[1, 22]

对于[1, 1e7]每个主横坐标的子域,方法是为每个横坐标生成一个比例。不过,应首先回答有关范围的几个问题:

  1. 是否positions均匀分布?
  2. 在主图表中,看起来range子域的 似乎随着主横坐标的增加而缩小(例如,区域的宽度 forx = 22远小于 for x = 2)。position每个染色体索引是否具有相同的范围[1, 1e7]

假设position均匀分布在所有染色体索引中[1, 1e7],最大值position1e7(似乎并非如此),这样做的方法将是子域内每个圆圈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.

于 2013-07-14T10:09:03.313 回答