抑制 d3plus 方框和晶须绘图中的极端异常值
Suppress extreme outliers from d3plus box and whiskers plot drawing
我正在尝试在 d3plus 上创建带胡须的箱形图,以比较我数据库中 "this" 提供商和 "all" 提供商之间的指标。我已经在预处理阶段从非常大的数组中计算出 5 统计摘要,并将它们传递到 data
变量中。如果你 运行 附加的片段(从 d3plus website example 修改而来),你可以看到代码和图表的样子。然而,实际上,"All" 类别中有一些极端异常值,在我的代码中作为注释行提供:663373.22 for "max"(for "All")和 -18427.39 for "min"(同样,"All")。
我看到有一个 mute
method 可以用于 .y
,但我不确定如何让它与函数一起使用。
是否有一种相当直接的方法来 "suppress" 绘制这些极端异常值(如果允许,这会将两个箱线图折叠成扁平线),或者任何极端异常值,比如说,高于(或低于)IQR 的某个倍数?
<script src="//d3plus.org/js/d3.js"></script>
<script src="//d3plus.org/js/d3plus.js"></script>
<div id="viz"></div>
<script>
var data = [
{"provider": "This", "name":"min", "value": -1055.79},
{"provider": "This", "name":"q1", "value": -172.819},
{"provider": "This", "name":"med", "value": -46.795},
{"provider": "This", "name":"q3", "value": 8.378},
{"provider": "This", "name":"max", "value": 1033.15},
{"provider": "All", "name":"min", "value": -1000},
{"provider": "All", "name":"q1", "value": -111.60999999999999},
{"provider": "All", "name":"med", "value": -13.92},
{"provider": "All", "name":"q3", "value": 124.22},
{"provider": "All", "name":"max", "value": 1000}
]
//663373.22, -18427.39
var visualization = d3plus.viz()
.container("#viz")
.data(data)
.type("box")
.id("name")
.x("provider")
.y("value")
.ui([{
"label": "Visualization Type",
"method": "type",
"value": ["scatter","box"]
}])
.draw()
</script>
根据我对文档的了解,mute
用作对象键,其中值可以是字符串、函数或数组。因此,如果您想静音所有名称为 q1
的数据点,您可以执行 .y({value:'value',mute:'q1'})
。
至于解决方案,您需要一个函数来确定异常值。我发现并编辑了一个函数以 return 可接受的值范围(IQR * 倍数),您可以根据需要修改 multiple
变量。然后你使用一个简单的函数 isOutlier
来检查传入的值是否超出范围。
<script src="//d3plus.org/js/d3.js"></script>
<script src="//d3plus.org/js/d3plus.js"></script>
<div id="viz"></div>
<script>
var data = [
{"provider": "This", "name":"min", "value": -1055.79},
{"provider": "This", "name":"q1", "value": -172.819},
{"provider": "This", "name":"med", "value": -46.795},
{"provider": "This", "name":"q3", "value": 8.378},
{"provider": "This", "name":"max", "value": 1033.15},
{"provider": "All", "name":"min", "value": -1000},
{"provider": "All", "name":"q1", "value": -111.60999999999999},
{"provider": "All", "name":"med", "value": -13.92},
{"provider": "All", "name":"q3", "value": 124.22},
{"provider": "All", "name":"max", "value": 1000}
]
var outlierRange = outlierRange(data.map(d=>d.value))
var isOutlier = val => (val < outlierRange[0] || val > outlierRange[1])
//663373.22, -18427.39
var visualization = d3plus.viz()
.container("#viz")
.data(data)
.type("box")
.id("name")
.x("provider")
.y({value:'value', mute: isOutlier })
.ui([{
"label": "Visualization Type",
"method": "type",
"value": ["scatter","box"]
}])
.draw()
function outlierRange(someArray) {
if(someArray.length < 4)
return someArray;
let values, q1, q3, iqr, maxValue, minValue, multiple = 0.5;
values = someArray.slice().sort( (a, b) => a - b);//copy array fast and sort
if((values.length / 4) % 1 === 0){//find quartiles
q1 = 1/2 * (values[(values.length / 4)] + values[(values.length / 4) + 1]);
q3 = 1/2 * (values[(values.length * (3 / 4))] + values[(values.length * (3 / 4)) + 1]);
} else {
q1 = values[Math.floor(values.length / 4 + 1)];
q3 = values[Math.ceil(values.length * (3 / 4) + 1)];
}
iqr = q3 - q1;
maxValue = q3 + iqr * multiple;
minValue = q1 - iqr * multiple;
return [minValue, maxValue]
}
</script>
我正在尝试在 d3plus 上创建带胡须的箱形图,以比较我数据库中 "this" 提供商和 "all" 提供商之间的指标。我已经在预处理阶段从非常大的数组中计算出 5 统计摘要,并将它们传递到 data
变量中。如果你 运行 附加的片段(从 d3plus website example 修改而来),你可以看到代码和图表的样子。然而,实际上,"All" 类别中有一些极端异常值,在我的代码中作为注释行提供:663373.22 for "max"(for "All")和 -18427.39 for "min"(同样,"All")。
我看到有一个 mute
method 可以用于 .y
,但我不确定如何让它与函数一起使用。
是否有一种相当直接的方法来 "suppress" 绘制这些极端异常值(如果允许,这会将两个箱线图折叠成扁平线),或者任何极端异常值,比如说,高于(或低于)IQR 的某个倍数?
<script src="//d3plus.org/js/d3.js"></script>
<script src="//d3plus.org/js/d3plus.js"></script>
<div id="viz"></div>
<script>
var data = [
{"provider": "This", "name":"min", "value": -1055.79},
{"provider": "This", "name":"q1", "value": -172.819},
{"provider": "This", "name":"med", "value": -46.795},
{"provider": "This", "name":"q3", "value": 8.378},
{"provider": "This", "name":"max", "value": 1033.15},
{"provider": "All", "name":"min", "value": -1000},
{"provider": "All", "name":"q1", "value": -111.60999999999999},
{"provider": "All", "name":"med", "value": -13.92},
{"provider": "All", "name":"q3", "value": 124.22},
{"provider": "All", "name":"max", "value": 1000}
]
//663373.22, -18427.39
var visualization = d3plus.viz()
.container("#viz")
.data(data)
.type("box")
.id("name")
.x("provider")
.y("value")
.ui([{
"label": "Visualization Type",
"method": "type",
"value": ["scatter","box"]
}])
.draw()
</script>
根据我对文档的了解,mute
用作对象键,其中值可以是字符串、函数或数组。因此,如果您想静音所有名称为 q1
的数据点,您可以执行 .y({value:'value',mute:'q1'})
。
至于解决方案,您需要一个函数来确定异常值。我发现并编辑了一个函数以 return 可接受的值范围(IQR * 倍数),您可以根据需要修改 multiple
变量。然后你使用一个简单的函数 isOutlier
来检查传入的值是否超出范围。
<script src="//d3plus.org/js/d3.js"></script>
<script src="//d3plus.org/js/d3plus.js"></script>
<div id="viz"></div>
<script>
var data = [
{"provider": "This", "name":"min", "value": -1055.79},
{"provider": "This", "name":"q1", "value": -172.819},
{"provider": "This", "name":"med", "value": -46.795},
{"provider": "This", "name":"q3", "value": 8.378},
{"provider": "This", "name":"max", "value": 1033.15},
{"provider": "All", "name":"min", "value": -1000},
{"provider": "All", "name":"q1", "value": -111.60999999999999},
{"provider": "All", "name":"med", "value": -13.92},
{"provider": "All", "name":"q3", "value": 124.22},
{"provider": "All", "name":"max", "value": 1000}
]
var outlierRange = outlierRange(data.map(d=>d.value))
var isOutlier = val => (val < outlierRange[0] || val > outlierRange[1])
//663373.22, -18427.39
var visualization = d3plus.viz()
.container("#viz")
.data(data)
.type("box")
.id("name")
.x("provider")
.y({value:'value', mute: isOutlier })
.ui([{
"label": "Visualization Type",
"method": "type",
"value": ["scatter","box"]
}])
.draw()
function outlierRange(someArray) {
if(someArray.length < 4)
return someArray;
let values, q1, q3, iqr, maxValue, minValue, multiple = 0.5;
values = someArray.slice().sort( (a, b) => a - b);//copy array fast and sort
if((values.length / 4) % 1 === 0){//find quartiles
q1 = 1/2 * (values[(values.length / 4)] + values[(values.length / 4) + 1]);
q3 = 1/2 * (values[(values.length * (3 / 4))] + values[(values.length * (3 / 4)) + 1]);
} else {
q1 = values[Math.floor(values.length / 4 + 1)];
q3 = values[Math.ceil(values.length * (3 / 4) + 1)];
}
iqr = q3 - q1;
maxValue = q3 + iqr * multiple;
minValue = q1 - iqr * multiple;
return [minValue, maxValue]
}
</script>