d3.js热图传奇

时间:2015-05-29 09:49:27

标签: javascript d3.js

我已经设法根据一些样本基因表达数据生成热图,我根据基因表达水平为每个细胞分配填充。我将填充与颜色抽屉比例映射,即:

var z           = d3.scale.log().base(2).domain([min, max]).range([0,1]),
    fills       = colorbrewer.RdBu[6];
    heatmapFill = d3.scale.linear().domain(d3.range(0, 1, 1.0 / (fills.length - 1))).range(fills);

...对我来说完全没问题。但是,我在将这些填充分配给随附的图例时遇到问题,该图例具有#NaNNaNNaN填充。

// Get data
svg.selectAll('.tile')
    .data(data.melted)
    .enter()
    .append('rect')
    .attr({
        'x': function(d) { return x(d.condition); },
        'y': function(d) { return y(d.geneID); },
        'fill': function(d) { return heatmapFill(z(d.value)); },
        'width': x.rangeBand(),
        'height': y.rangeBand()
    });
// Add a legend for the color values.
var legend = svg.selectAll(".legend")
    .data(z.ticks())
    .enter()
    .append("g")
        .attr({
            'class': 'legend',
            'transform': function(d, i) {
                return "translate(" + (i * 40) + "," + (height + margin.bottom - 40) + ")";
            }
        });

legend.append("rect")
.attr({
    'width': 40,
    'height': 20,
    'fill': z  // Problem likely to be arising from here
});

根据我的理解,似乎我无法根据z的值获取填充值。

这里是完整的小提琴:http://jsfiddle.net/teddyrised/jLxbawhz/2/

如果我选择不将我的表达级别映射到一个colorbrewer比例,而只是一个开始和结束颜色,那么该脚本可以正常工作(http://jsfiddle.net/teddyrised/jLxbawhz/3/):

// Scale
var z = d3.scale.log().base(2).domain([min, max]).range(['white','steelblue']);

// Get data
svg.selectAll('.tile')
    .data(data.melted)
    .enter()
    .append('rect')
    .attr({
        'x': function(d) { return x(d.condition); },
        'y': function(d) { return y(d.geneID); },
        'fill': function(d) { return z(d.value); },
        'width': x.rangeBand(),
        'height': y.rangeBand()
    });
// Add a legend for the color values.
var legend = svg.selectAll(".legend")
    .data(z.ticks())
    .enter()
    .append("g")
        .attr({
            'class': 'legend',
            'transform': function(d, i) {
                return "translate(" + (i * 40) + "," + (height + margin.bottom - 40) + ")";
            }
        });

legend.append("rect")
.attr({
    'width': 40,
    'height': 20,
    'fill': z
});

1 个答案:

答案 0 :(得分:1)

我不确定我是否完全关注您的代码,但您的图例填充不应该与热图填充功能相同吗?

legend.append("rect")
  .attr({
    'width': 40,
    'height': 20,
    'fill': function(d) { 
        return heatmapFill(z(d)); 
    }
});

更新了fiddle