对于向右倾斜的数据,请使用正确的色标

问题描述 投票:4回答:3

我的数据域为[0,100],但它们并不统一,它们向右偏斜,即大多数数据的值介于80和100之间。

我想用这些数据进行可视化,并使用颜色来区分它们(例如:heatmap,map,...)。

什么是正确的色标使用?

我尝试了线性刻度,功率刻度和分位数刻度。最好的一个似乎是分位数尺度,但仍然存在问题:

  1. 我想更好地区分最后一个值的颜色(值到右边),它们都显得很黑,是否可能?
  2. 在这个例子中,我使用了灰度,如果我想使用Viridis或Magma量表?

enter image description here

这是我的代码。

function sortNumber(a, b) {
  return a - b;
}

var data = [90, 95, 50, 1, 99, 89.1, 87, 94, 95, 99, 99.5, 94.3, 96, 97, 85, 74, 66, 92, 68, 91, 93, 87, 79, 86, 89, 93.5, 97, 98];
data.sort(sortNumber); // [1, 50, 66, 68, 74, 79, 85, 86, 87, 87, 89, 89.1, 90, 91, 92, 93, 93.5, 94, 94.3, 95, 95, 96, 97, 97, 98, 99, 99, 99.5]
console.log(data);

var colMin = '#ffffff';
var colMax = '#000000';

// LINEAR SCALE
var scaleLinear = d3.scaleLinear()
  .domain([0, 100])
  .range([colMin, colMax]);

var div = d3.select("#lin").selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .attr("class", "dive")
  .style("background-color", d => scaleLinear(d));


// POWER SCALE
var scalePow = d3.scalePow()
  .exponent(10)
  .domain([0, 100])
  .range([colMin, colMax]);

var div = d3.select("#pow").selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .attr("class", "dive")
  .style("background-color", d => scalePow(d));


// QUANTILE SCALE (using https://meyerweb.com/eric/tools/color-blend/#:::hex to find intermediate colors)
var scaleQuantile = d3.scaleQuantile()
  .domain(data)
  .range([colMin, "#E8E8E8", "#D1D1D1", "#B9B9B9", "#A2A2A2", "#8B8B8B", "#747474", "#5D5D5D", "#464646", "#2E2E2E", "#171717", colMax]);

var div = d3.select("#qua").selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .attr("class", "dive")
  .style("background-color", d => scaleQuantile(d));
.dive {
  width: 20px;
  height: 20px;
  display: inline-block;
  margin: 4px;
  border: 0.5px black solid;
}
<html lang="en">

<head>
   <meta charset="utf-8">
   <title>color scheme</title>
   <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
   <script src="//d3js.org/d3-scale-chromatic.v0.3.min.js"></script> <!-- for scale color -->
   <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> <!-- for scale color -->

   <link rel="stylesheet" type="text/css" href="./style.css" media="screen"/>
</head>

<body>
   <div id="lin">
   	<p>Scale linear</p>
   </div><br>

   <div id="pow">
   	<p>Scale power</p>
   </div><br>

   <div id="qua">
   	<p>Scale quantile</p>
   </div>

   <script src="./script.js"></script>
</body>

</html>

这是结果:

enter image description here

javascript d3.js colors data-visualization
3个回答
0
投票

什么是正确的色标使用?

没有合适的色标。一切都取决于你想要展示,隐藏,出售,你的客户,客户,用户,公众.-

另一方面,你有D3作为工具来展示你需要的东西.-

您可以使用自定义比例,如下所示:

  // --------------------- Custom  SCALE
var custom = d3.scaleLinear()
  .domain([0,       50,       90,        95,       100])
  .range(['#edfc1b','#ec6f3b','#bc2e67','#7c0093', '#0b0074']);

var div = d3.select("#custom").selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .attr("class", "dive")
  .style("background-color", d => custom(d));

哪个给你这个:

enter image description here

还有其他尺度。

enter image description here

我把你的Plunker分叉以扩展它:HERE

我认为你错过了一个重要的观点:你丢失了信息。显示这一点的正确方法是留下空白空间以缺少数据,例如任何颜色标度都可以。像这样:

enter image description here

从你的形象

enter image description here

在“Scale Quantile”和“Scale Power”上,“value 1”具有与“value 50”相同的颜色。即使你用他的价值标记每个盒子,也很难注意到.-

希望这有帮助


5
投票

我想更好地区分最后一个值的颜色(值到右边),它们都显得很黑,是否可能?

正如Klaujesi建议的那样,制作自己的色标可能是最好的选择。我会参考Klaujesi的答案来编写关于创建自己的配色方案的指导。

正如您所确定的那样,您有许多具有相似价值的数据点,这些数据点已经反映出您正在尝试的尺度。就个人而言,我会考虑仍然让你的规模反映这个事实,而不是太努力地用更具吸引力的规模隐藏它。我建议考虑一下您的数据意味着什么,并创建一个比例来反映这一点。例如,可能90到100范围内的所有数据点应该具有比80到100范围内的数据点更相似的颜色。或许你真的应该让所有的颜色看起来都一样,因为所有的数据都是相同的。

在这个例子中,我使用了灰度,如果我想使用Viridis或Magma量表?

由于您在组合一个好例子方面的工作,添加其中一种配色方案应该不会太困难。这是一个线性比例的例子。

添加到script.js的底部:

// VIRIDIS
var colorScale = d3.scaleLinear()
  .domain([0, 100])
  .range([0, 1]);

var div = d3.select("#vir").selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .attr("class", "dive")
  .style("background-color", d => d3.interpolateViridis(colorScale(d)));

<body>index.html中添加:

<div id="vir">
    <p>Viridis colors</p>
</div>

1
投票

由于您的数据偏向右侧,这是我的建议:

使用sequential scale,在此示例中使用interpolateViridis

var scale = d3.scaleSequential(d3.interpolateViridis);

只需使用插值器的基准索引:

.style("background-color", function(_, i) {
    return scale(i / (data.length - 1))
});

或者,当你使用viridis逆转时:

.style("background-color", function(_, i) {
    return scale(1 - (i / (data.length - 1)))
});

原因在于,使用顺序标度,只有数据数组中的数据索引很重要,而不是数据本身。因此,请确保对数据数组进行排序。

这是演示:

var data = [90, 95, 50, 1, 99, 89.1, 87, 94, 95, 99, 99.5, 94.3, 96, 97, 85, 74, 66, 92, 68, 91, 93, 87, 79, 86, 89, 93.5, 97, 98];
data.sort();
var scale = d3.scaleSequential(d3.interpolateViridis);
var div = d3.select("#myDiv").selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .attr("class", "div")
  .style("background-color", function(_, i) {
    return scale(1 - (i / (data.length - 1)))
  });
  
var divValue = d3.select("#myDivValue").selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .attr("class", "div2")
  .html(Number)
.div {
  width: 14px;
  height: 14px;
  display: inline-block;
  margin: 2px;
  border: 0.5px black solid;
}

.div2 {
  width: 14px;
  height: 14px;
  display: inline-block;
  margin: 2px;
  font-size: 10px;
  border: 0.5px white solid;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="myDiv">
  <p>Sequential scale with Viridis</p>
</div>
<div id="myDivValue"></div>

相同的代码,使用interpolateMagma

var data = [90, 95, 50, 1, 99, 89.1, 87, 94, 95, 99, 99.5, 94.3, 96, 97, 85, 74, 66, 92, 68, 91, 93, 87, 79, 86, 89, 93.5, 97, 98];
data.sort();
var scale = d3.scaleSequential(d3.interpolateMagma);
var div = d3.select("#myDiv").selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .attr("class", "div")
  .style("background-color", function(_, i) {
    return scale(1 - (i / (data.length - 1)))
  });
var divValue = d3.select("#myDivValue").selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .attr("class", "div2")
  .html(Number);
.div {
  width: 14px;
  height: 14px;
  display: inline-block;
  margin: 2px;
  border: 0.5px black solid;
}

.div2 {
  width: 14px;
  height: 14px;
  display: inline-block;
  margin: 2px;
  font-size: 10px;
  border: 0.5px white solid;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="myDiv">
  <p>Sequential scale with Magma</p>
</div>
<div id="myDivValue"></div>

PS:我在这里使用D3 v5。如果您使用的是v4,则可能需要参考必要的微库。

© www.soinside.com 2019 - 2024. All rights reserved.