NVD3 离散条形图上的钟形曲线/正态分布曲线
Bell Curve / Normal Disribution Curve On A NVD3 Discrete Bar Chart
我正在尝试找出一种将分布曲线/钟形曲线绘制到 NVD3 图表上的方法。我在网上搜索了很多,发现几乎没有什么可以与我所拥有的一起工作。也许这实际上是不可能的,但我认为这值得一问,也很高兴知道其他任何会寻找类似东西的人。
这是我需要的图形示例(在 google 图片上找到)
从示例中可以看出,直线不需要第二个轴,因此不需要 'bar and line chart combo'。我知道您可以使用 D3 直接在 canvas 上绘图,但我对此经验不足。
这是我的代码,jsfiddle如果有人想看
var json = [{ "values": [{"label":"450-456", "value":0, "color":"#D62728"},{"label":"456-462", "value":0, "color":"#D62728"},{"label":"462-468", "value":0, "color":"#D62728"},{"label":"468-474", "value":0, "color":"#D62728"},{"label":"474-480", "value":0, "color":"#D62728"},{"label":"480-486", "value":1, "color":"#D62728"},{"label":"486-492", "value":5, "color":"#D62728"},{"label":"492-498", "value":3, "color":"#D62728"},{"label":"498-504", "value":5, "color":"#D62728"},{"label":"504-510", "value":6, "color":"#D62728"},{"label":"510-516", "value":9, "color":"#D62728"},{"label":"516-522", "value":6, "color":"#D62728"},{"label":"522-528", "value":1, "color":"#D62728"},{"label":"528-534", "value":0, "color":"#D62728"},{"label":"534-540", "value":0, "color":"#D62728"},{"label":"540-546", "value":0, "color":"#D62728"},{"label":"546-552", "value":0, "color":"#D62728"},{"label":"552-558", "value":0, "color":"#D62728"},{"label":"558-564", "value":0, "color":"#D62728"},{"label":"564-570", "value":0, "color":"#D62728"}]}];
nv.addGraph(function() {
var chart = nv.models.discreteBarChart()
.x(function(d) {
return d.label
})
.y(function(d) {
return d.value
})
.staggerLabels(true)
.tooltips(true)
.showValues(true)
.transitionDuration(250)
;
chart.yAxis
.tickFormat(d3.format('.0f'))
chart.valueFormat(d3.format('d'));
// REMOVE DECIMAL PLACES FROM Y AXIS
chart.forceY([0,10]);
d3.select('#chartDisribution svg')
.datum(json)
.call(chart);
d3.select('#chartDisribution svg')
.append("text")
.attr("x", '50%')
.attr("y", 10)
.attr("text-anchor", "middle")
.style("font-size", "14px")
.style("text-decoration", "underline")
.style("font-weight", "bold")
.style("height", "20px")
.text("DISRIBUTION");
nv.utils.windowResize(chart.update);
return chart;
});
分发前的原始数据 -
[518, 514, 512, 514, 518, 498, 510, 516, 520, 508, 504, 504, 517, 494, 492, 491, 515, 507, 492, 527, 509, 500, 491, 506, 517, 516, 518, 505, 514, 486, 516, 504, 503, 490, 515, 498]
如果需要更多信息,请询问。
谢谢
如@Altocumulus 所述,您可以使用 LinePlusBarChart。
有很多关于如何执行此操作的信息,因此我将仅解释如何为正态分布生成数据。
以下公式用于创建数据:Wikipedia Source
所以我们需要的是总数据集的标准差和平均值以及您用于直方图的 bin。
我不会详细介绍如何根据您的数据集计算平均值和标准偏差,但执行此操作的代码包含在下面的 fiddle 中。
我们首先声明数据集和 bins:
var values = [518, 514, 512, 514, 518, 498, 510, 516, 520, 508, 504, 504, 517, 494, 492, 491, 515, 507, 492, 527, 509, 500, 491, 506, 517, 516, 518, 505, 514, 486, 516, 504, 503, 490, 515, 498];
var bins=[450, 456, 462, 468, 474, 480, 486, 492, 498, 504, 510, 516, 522, 528, 534, 540, 546, 552, 558, 564]
该数据集的均值和标准差如下:
var average = 507.1944444
var std = 10.43022927
根据这些数据,我们可以计算出公式的第一部分:
var ni1 = 1 / (std * Math.sqrt(2 * Math.PI));
公式的第二部分使用 bin,因此我们循环遍历每个 bin 以计算正态曲线的值。
为了将正常值缩放到图表中,我们需要每个 bin 之间的大小以及值的总数。
(我还添加了一个名为 norm 的变量,但我们仅使用它来将结果输出到屏幕)
var norm ="norm data"
var length = bins.length;
var bin_distance = 6;
var num_records = 36;
for(var i=0;i<length;i++){
// This is the second part of the formula
var ni2 = Math.exp(-1*((bins[i]-average)*(bins[i]-average))/(2* (std*std)))
// this is the final calculation for the norm values. I also rounded the value but thats up to you if you want, you can remove this for unrounded values.
var normdata = Math.round(ni1*ni2*bin_distance*num_records);
//append value to norm to output to screen
norm = norm +"<p>"+ bins[i]+" - "+normdata+"</p>"
}
//output results to screen:
document.getElementById('chartDisribution').innerHTML = norm;
这里是working fiddle.
对于您的图表,您可能希望将 normdata 值推送到您为您的线声明的对象中。
我正在尝试找出一种将分布曲线/钟形曲线绘制到 NVD3 图表上的方法。我在网上搜索了很多,发现几乎没有什么可以与我所拥有的一起工作。也许这实际上是不可能的,但我认为这值得一问,也很高兴知道其他任何会寻找类似东西的人。
这是我需要的图形示例(在 google 图片上找到)
从示例中可以看出,直线不需要第二个轴,因此不需要 'bar and line chart combo'。我知道您可以使用 D3 直接在 canvas 上绘图,但我对此经验不足。
这是我的代码,jsfiddle如果有人想看
var json = [{ "values": [{"label":"450-456", "value":0, "color":"#D62728"},{"label":"456-462", "value":0, "color":"#D62728"},{"label":"462-468", "value":0, "color":"#D62728"},{"label":"468-474", "value":0, "color":"#D62728"},{"label":"474-480", "value":0, "color":"#D62728"},{"label":"480-486", "value":1, "color":"#D62728"},{"label":"486-492", "value":5, "color":"#D62728"},{"label":"492-498", "value":3, "color":"#D62728"},{"label":"498-504", "value":5, "color":"#D62728"},{"label":"504-510", "value":6, "color":"#D62728"},{"label":"510-516", "value":9, "color":"#D62728"},{"label":"516-522", "value":6, "color":"#D62728"},{"label":"522-528", "value":1, "color":"#D62728"},{"label":"528-534", "value":0, "color":"#D62728"},{"label":"534-540", "value":0, "color":"#D62728"},{"label":"540-546", "value":0, "color":"#D62728"},{"label":"546-552", "value":0, "color":"#D62728"},{"label":"552-558", "value":0, "color":"#D62728"},{"label":"558-564", "value":0, "color":"#D62728"},{"label":"564-570", "value":0, "color":"#D62728"}]}];
nv.addGraph(function() {
var chart = nv.models.discreteBarChart()
.x(function(d) {
return d.label
})
.y(function(d) {
return d.value
})
.staggerLabels(true)
.tooltips(true)
.showValues(true)
.transitionDuration(250)
;
chart.yAxis
.tickFormat(d3.format('.0f'))
chart.valueFormat(d3.format('d'));
// REMOVE DECIMAL PLACES FROM Y AXIS
chart.forceY([0,10]);
d3.select('#chartDisribution svg')
.datum(json)
.call(chart);
d3.select('#chartDisribution svg')
.append("text")
.attr("x", '50%')
.attr("y", 10)
.attr("text-anchor", "middle")
.style("font-size", "14px")
.style("text-decoration", "underline")
.style("font-weight", "bold")
.style("height", "20px")
.text("DISRIBUTION");
nv.utils.windowResize(chart.update);
return chart;
});
分发前的原始数据 -
[518, 514, 512, 514, 518, 498, 510, 516, 520, 508, 504, 504, 517, 494, 492, 491, 515, 507, 492, 527, 509, 500, 491, 506, 517, 516, 518, 505, 514, 486, 516, 504, 503, 490, 515, 498]
如果需要更多信息,请询问。
谢谢
如@Altocumulus 所述,您可以使用 LinePlusBarChart。
有很多关于如何执行此操作的信息,因此我将仅解释如何为正态分布生成数据。
以下公式用于创建数据:Wikipedia Source
所以我们需要的是总数据集的标准差和平均值以及您用于直方图的 bin。
我不会详细介绍如何根据您的数据集计算平均值和标准偏差,但执行此操作的代码包含在下面的 fiddle 中。
我们首先声明数据集和 bins:
var values = [518, 514, 512, 514, 518, 498, 510, 516, 520, 508, 504, 504, 517, 494, 492, 491, 515, 507, 492, 527, 509, 500, 491, 506, 517, 516, 518, 505, 514, 486, 516, 504, 503, 490, 515, 498];
var bins=[450, 456, 462, 468, 474, 480, 486, 492, 498, 504, 510, 516, 522, 528, 534, 540, 546, 552, 558, 564]
该数据集的均值和标准差如下:
var average = 507.1944444
var std = 10.43022927
根据这些数据,我们可以计算出公式的第一部分:
var ni1 = 1 / (std * Math.sqrt(2 * Math.PI));
公式的第二部分使用 bin,因此我们循环遍历每个 bin 以计算正态曲线的值。
为了将正常值缩放到图表中,我们需要每个 bin 之间的大小以及值的总数。
(我还添加了一个名为 norm 的变量,但我们仅使用它来将结果输出到屏幕)
var norm ="norm data"
var length = bins.length;
var bin_distance = 6;
var num_records = 36;
for(var i=0;i<length;i++){
// This is the second part of the formula
var ni2 = Math.exp(-1*((bins[i]-average)*(bins[i]-average))/(2* (std*std)))
// this is the final calculation for the norm values. I also rounded the value but thats up to you if you want, you can remove this for unrounded values.
var normdata = Math.round(ni1*ni2*bin_distance*num_records);
//append value to norm to output to screen
norm = norm +"<p>"+ bins[i]+" - "+normdata+"</p>"
}
//output results to screen:
document.getElementById('chartDisribution').innerHTML = norm;
这里是working fiddle.
对于您的图表,您可能希望将 normdata 值推送到您为您的线声明的对象中。