在d3 sequential.interpolator中,是否可以仅使用一段光谱而不是全范围?看起来这样的调色板只需要输入域而不是范围,想知道是否可以指定某些东西只能占据色谱的中间或下部。感谢。
答案 0 :(得分:1)
如果您不想创建自定义插补器,您可以通过两种方式实现所需的效果:
如果您将域分配给具有两倍于数据实际域范围的比例,那么您将只使用一半的颜色范围。
但是,我将在这里扩展第二个,因为它允许您轻松修改比例类型。插值器的t
参数是0到1之间的值:
给定范围[0,1]中的数字t,返回相应的颜色 来自...方案表示为RGB字符串。 (from the API docs)。
我们可以通过几种方式操纵t
,以便我们只使用颜色渐变的一部分。例如,要仅显示渐变的前半部分的颜色,我们可以确保t
永远不会超过0.5:
var truncated = d3.scaleSequential(function(t) {
return d3.interpolateViridis((t/2)) })
.domain([1,10]);
或者得到中间:
var middle = d3.scaleSequential(function(t) {
return d3.interpolateViridis(t/2+0.25) })
.domain([1,10]);
如果使用t*2
之类的内容,超过1或低于0的值将显示为极端值。
你也可以通过使用平方根或t的其他幂来做偏斜颜色,这在处理非线性数据时可能很有用。
var scale = d3.scaleSequential(d3.interpolateViridis)
.domain([1,10]);
var truncated = d3.scaleSequential(function(t) {
return d3.interpolateViridis((t/2)) })
.domain([1,10]);
var middle = d3.scaleSequential(function(t) {
return d3.interpolateViridis(t/2+0.25)
})
.domain([1,10]);
var data = d3.range(10);
var svg = d3.select("body")
.append("svg");
svg.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("x", function(d) { return d * 12 + 12; })
.attr("y", 20)
.attr("fill", function(d) { return scale(d); })
svg.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("x", function(d) { return d * 12 + 12; })
.attr("y", 32)
.attr("fill", function(d) { return truncated(d); })
svg.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("x", function(d) { return d * 12 + 12; })
.attr("y", 44)
.attr("fill", function(d) { return middle(d); })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>