繁体   English   中英

vega-lite 中的累积密度图

[英]Cumulative Density plot in vega-lite

我使用这个vega-lite 示例创建了累积密度可视化,如下所示:

 var data = [{"student_name": "student 0", "e": "100.15", "d": "127.81"}, {"student_name": "student 1", "e": "100.30", "d": "189.94"}, {"student_name": "student 2", "e": "100.15", "d": "105.33"}, {"student_name": "student 3", "e": "99.41", "d": "85.36"}, {"student_name": "student 4", "e": "100.00", "d": "203.70"}, {"student_name": "student 5", "e": "100.15", "d": "139.05"}, {"student_name": "student 19", "e": "100.15", "d": "102.66"}, {"student_name": "student 20", "e": "95.71", "d": "52.96"}, {"student_name": "student 21", "e": "99.85", "d": "99.41"}, {"student_name": "student 22", "e": "98.96", "d": "100.44"}, {"student_name": "student 23", "e": "100.15", "d": "131.07"}, {"student_name": "student 24", "e": "99.56", "d": "76.92"}, {"student_name": "student 25", "e": "100.15", "d": "213.46"}, {"student_name": "student 26", "e": "100.15", "d": "311.24"}, {"student_name": "student 27", "e": "100.15", "d": "21.89"}, {"student_name": "student 28", "e": "96.60", "d": "6.36"}, {"student_name": "student 29", "e": "53.70", "d": "3.70"}, {"student_name": "student 30", "e": "96.75", "d": "46.60"}, {"student_name": "student 31", "e": "100.15", "d": "100.15"}, {"student_name": "student 32", "e": "100.30", "d": "115.68"}, {"student_name": "student 33", "e": "87.13", "d": "103.85"}, {"student_name": "student 34", "e": "100.15", "d": "104.14"}, {"student_name": "student 35", "e": "99.26", "d": "59.17"}, {"student_name": "student 36", "e": "100.15", "d": "171.30"}, {"student_name": "student 37", "e": "99.11", "d": "94.08"}, {"student_name": "student 38", "e": "81.66", "d": "57.40"}, {"student_name": "student 39", "e": "96.01", "d": "154.59"}, {"student_name": "student 90", "e": "1.04", "d": "1.33"}, {"student_name": "student 91", "e": "99.70", "d": "26.18"}, {"student_name": "student 92", "e": "96.30", "d": "78.11"}, {"student_name": "student 93", "e": "99.85", "d": "11.83"}, {"student_name": "student 94", "e": "100.15", "d": "172.93"}, {"student_name": "student 95", "e": "100.00", "d": "198.82"}, {"student_name": "student 96", "e": "100.15", "d": "155.92"}, {"student_name": "student 97", "e": "92.01", "d": "97.19"}, {"student_name": "student 98", "e": "98.52", "d": "71.30"}, {"student_name": "student 99", "e": "100.15", "d": "111.69"}, {"student_name": "student 100", "e": "0.30", "d": "0.30"}, {"student_name": "student 175", "e": "98.96", "d": "91.12"}, {"student_name": "student 176", "e": "100.00", "d": "226.04"}, {"student_name": "student 177", "e": "98.67", "d": "150.89"}, {"student_name": "student 178", "e": "97.49", "d": "68.79"}, {"student_name": "student 179", "e": "100.15", "d": "133.58"}, {"student_name": "student 180", "e": 0, "d": 0}, {"student_name": "student 181", "e": 0, "d": 0}, {"student_name": "student 182", "e": 0, "d": 0}, {"student_name": "student 183", "e": 0, "d": 0}, {"student_name": "student 184", "e": 0, "d": 0}, {"student_name": "student 185", "e": 0, "d": 0}, {"student_name": "student 186", "e": 0, "d": 0}, {"student_name": "student 187", "e": 0, "d": 0}, {"student_name": "student 188", "e": 0, "d": 0}, {"student_name": "student 189", "e": 0, "d": 0}, {"student_name": "student 190", "e": 0, "d": 0}, {"student_name": "student 191", "e": 0, "d": 0}]; createChart = function (data) { let max_d = d3.max(data, record => parseFloat(record.d)); let max_e = d3.max(data, record => parseFloat(record.e)); let max_y_scale_value_for_d = d3.max([100, max_d]); let max_y_scale_value_for_e = d3.max([100, max_e]); const plot = vl.markArea() .data(data) .transform([{ "calculate": "toNumber(datum.d)", "as": "d2" } , { "calculate": "toNumber(datum.e)", "as": "e2" } , { "sort": [{"field": "d2"}], "window": [{"op": "count", "field": "student_name", "as": "Cumulative Count"}], "frame": [null, 0] } ]) .encode( vl.y().fieldQ('Cumulative Count') .title('# students'), vl.x() .fieldQ('d2')//.bin(true) .scale({ "domain": [0, max_y_scale_value_for_d] }) .title('D') ).width(500).height(250); return plot.toObject(); } const chart_spec_json = this.createChart(data) const opt = { renderer: "canvas", actions: false }; vegaEmbed("#stats", chart_spec_json, opt);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script> <script src="https://unpkg.com/vega@5.21.0/build/vega.min.js"></script> <script src="https://unpkg.com/vega-lite@5.2.0/build/vega-lite.min.js"></script> <script src="https://www.unpkg.com/vega-embed@6.20.8/build/vega-embed.min.js"></script> <script src="https://unpkg.com/vega-lite-api@5.0.0/build/vega-lite-api.min.js"></script> <div id="stats" />

这是它的外观(您也可以单击“运行代码片段”按钮来查看它的运行情况):

在此处输入图像描述

现在,我想将其转换为条形图。 所以我将markArea()更改为markRect()并添加了bin(true)

 var data = [{"student_name": "student 0", "e": "100.15", "d": "127.81"}, {"student_name": "student 1", "e": "100.30", "d": "189.94"}, {"student_name": "student 2", "e": "100.15", "d": "105.33"}, {"student_name": "student 3", "e": "99.41", "d": "85.36"}, {"student_name": "student 4", "e": "100.00", "d": "203.70"}, {"student_name": "student 5", "e": "100.15", "d": "139.05"}, {"student_name": "student 19", "e": "100.15", "d": "102.66"}, {"student_name": "student 20", "e": "95.71", "d": "52.96"}, {"student_name": "student 21", "e": "99.85", "d": "99.41"}, {"student_name": "student 22", "e": "98.96", "d": "100.44"}, {"student_name": "student 23", "e": "100.15", "d": "131.07"}, {"student_name": "student 24", "e": "99.56", "d": "76.92"}, {"student_name": "student 25", "e": "100.15", "d": "213.46"}, {"student_name": "student 26", "e": "100.15", "d": "311.24"}, {"student_name": "student 27", "e": "100.15", "d": "21.89"}, {"student_name": "student 28", "e": "96.60", "d": "6.36"}, {"student_name": "student 29", "e": "53.70", "d": "3.70"}, {"student_name": "student 30", "e": "96.75", "d": "46.60"}, {"student_name": "student 31", "e": "100.15", "d": "100.15"}, {"student_name": "student 32", "e": "100.30", "d": "115.68"}, {"student_name": "student 33", "e": "87.13", "d": "103.85"}, {"student_name": "student 34", "e": "100.15", "d": "104.14"}, {"student_name": "student 35", "e": "99.26", "d": "59.17"}, {"student_name": "student 36", "e": "100.15", "d": "171.30"}, {"student_name": "student 37", "e": "99.11", "d": "94.08"}, {"student_name": "student 38", "e": "81.66", "d": "57.40"}, {"student_name": "student 39", "e": "96.01", "d": "154.59"}, {"student_name": "student 90", "e": "1.04", "d": "1.33"}, {"student_name": "student 91", "e": "99.70", "d": "26.18"}, {"student_name": "student 92", "e": "96.30", "d": "78.11"}, {"student_name": "student 93", "e": "99.85", "d": "11.83"}, {"student_name": "student 94", "e": "100.15", "d": "172.93"}, {"student_name": "student 95", "e": "100.00", "d": "198.82"}, {"student_name": "student 96", "e": "100.15", "d": "155.92"}, {"student_name": "student 97", "e": "92.01", "d": "97.19"}, {"student_name": "student 98", "e": "98.52", "d": "71.30"}, {"student_name": "student 99", "e": "100.15", "d": "111.69"}, {"student_name": "student 100", "e": "0.30", "d": "0.30"}, {"student_name": "student 175", "e": "98.96", "d": "91.12"}, {"student_name": "student 176", "e": "100.00", "d": "226.04"}, {"student_name": "student 177", "e": "98.67", "d": "150.89"}, {"student_name": "student 178", "e": "97.49", "d": "68.79"}, {"student_name": "student 179", "e": "100.15", "d": "133.58"}, {"student_name": "student 180", "e": 0, "d": 0}, {"student_name": "student 181", "e": 0, "d": 0}, {"student_name": "student 182", "e": 0, "d": 0}, {"student_name": "student 183", "e": 0, "d": 0}, {"student_name": "student 184", "e": 0, "d": 0}, {"student_name": "student 185", "e": 0, "d": 0}, {"student_name": "student 186", "e": 0, "d": 0}, {"student_name": "student 187", "e": 0, "d": 0}, {"student_name": "student 188", "e": 0, "d": 0}, {"student_name": "student 189", "e": 0, "d": 0}, {"student_name": "student 190", "e": 0, "d": 0}, {"student_name": "student 191", "e": 0, "d": 0}]; createChart = function (data) { let max_d = d3.max(data, record => parseFloat(record.d)); let max_e = d3.max(data, record => parseFloat(record.e)); let max_y_scale_value_for_d = d3.max([100, max_d]); let max_y_scale_value_for_e = d3.max([100, max_e]); const plot = vl.markRect() .data(data) .transform([{ "calculate": "toNumber(datum.d)", "as": "d2" } , { "calculate": "toNumber(datum.e)", "as": "e2" } , { "sort": [{"field": "d2"}], "window": [{"op": "count", "field": "student_name", "as": "Cumulative Count"}], "frame": [null, 0] } ]) .encode( vl.y().fieldQ('Cumulative Count') .title('# students'), vl.x() .fieldQ('d2').bin(true) .scale({ "domain": [0, max_y_scale_value_for_d] }) .title('D') .bin({maxbins: 20}) ).width(500).height(250); return plot.toObject(); } const chart_spec_json = this.createChart(data) const opt = { renderer: "canvas", actions: false }; vegaEmbed("#stats", chart_spec_json, opt);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script> <script src="https://unpkg.com/vega@5.21.0/build/vega.min.js"></script> <script src="https://unpkg.com/vega-lite@5.2.0/build/vega-lite.min.js"></script> <script src="https://www.unpkg.com/vega-embed@6.20.8/build/vega-embed.min.js"></script> <script src="https://unpkg.com/vega-lite-api@5.0.0/build/vega-lite-api.min.js"></script> <div id="stats" />

这是它的外观(您也可以单击“运行代码片段”按钮来查看它的运行情况):

在此处输入图像描述

第二个图没有显示240-300范围内的条形图,大概是因为没有D值介于 240 和 300 之间的学生。但是为什么会这样呢? 我的理解是,它应该显示与220-240的高度完全相同的条形图,类似于第一个图表。 至少第一张图表没有显示240-300的这种差距。

PS: 是可观察的笔记本链接。

bin 变换的预期目的是创建一个直方图,用于计算每个桶上的元素数量。 正如您在原始帖子中所说,如果没有值,则有桶。

基本上,您有以下数据。 我先将 d 值分箱,然后计算累积计数。

分箱数据点

如果您使用线标记,您几乎可以获得所需的图表,但您想使用rect标记。

rect标记需要矩形的宽度和高度,或者编码通道 x2 和 y2。 您如何向这些渠道提供数据? 如果您使用Vega-lite ,则应使用序数比例来提供这些值。 Vega-lite 是更复杂的文法 Vega 的简化版,并没有那么灵活。

幸运的是,Vega-lite 有密度变换。 从您帖子的标题来看,这似乎是您要查找的内容。 这是使用密度变换的代码。

 var data = [{"student_name": "student 0", "e": "100.15", "d": "127.81"}, {"student_name": "student 1", "e": "100.30", "d": "189.94"}, {"student_name": "student 2", "e": "100.15", "d": "105.33"}, {"student_name": "student 3", "e": "99.41", "d": "85.36"}, {"student_name": "student 4", "e": "100.00", "d": "203.70"}, {"student_name": "student 5", "e": "100.15", "d": "139.05"}, {"student_name": "student 19", "e": "100.15", "d": "102.66"}, {"student_name": "student 20", "e": "95.71", "d": "52.96"}, {"student_name": "student 21", "e": "99.85", "d": "99.41"}, {"student_name": "student 22", "e": "98.96", "d": "100.44"}, {"student_name": "student 23", "e": "100.15", "d": "131.07"}, {"student_name": "student 24", "e": "99.56", "d": "76.92"}, {"student_name": "student 25", "e": "100.15", "d": "213.46"}, {"student_name": "student 26", "e": "100.15", "d": "311.24"}, {"student_name": "student 27", "e": "100.15", "d": "21.89"}, {"student_name": "student 28", "e": "96.60", "d": "6.36"}, {"student_name": "student 29", "e": "53.70", "d": "3.70"}, {"student_name": "student 30", "e": "96.75", "d": "46.60"}, {"student_name": "student 31", "e": "100.15", "d": "100.15"}, {"student_name": "student 32", "e": "100.30", "d": "115.68"}, {"student_name": "student 33", "e": "87.13", "d": "103.85"}, {"student_name": "student 34", "e": "100.15", "d": "104.14"}, {"student_name": "student 35", "e": "99.26", "d": "59.17"}, {"student_name": "student 36", "e": "100.15", "d": "171.30"}, {"student_name": "student 37", "e": "99.11", "d": "94.08"}, {"student_name": "student 38", "e": "81.66", "d": "57.40"}, {"student_name": "student 39", "e": "96.01", "d": "154.59"}, {"student_name": "student 90", "e": "1.04", "d": "1.33"}, {"student_name": "student 91", "e": "99.70", "d": "26.18"}, {"student_name": "student 92", "e": "96.30", "d": "78.11"}, {"student_name": "student 93", "e": "99.85", "d": "11.83"}, {"student_name": "student 94", "e": "100.15", "d": "172.93"}, {"student_name": "student 95", "e": "100.00", "d": "198.82"}, {"student_name": "student 96", "e": "100.15", "d": "155.92"}, {"student_name": "student 97", "e": "92.01", "d": "97.19"}, {"student_name": "student 98", "e": "98.52", "d": "71.30"}, {"student_name": "student 99", "e": "100.15", "d": "111.69"}, {"student_name": "student 100", "e": "0.30", "d": "0.30"}, {"student_name": "student 175", "e": "98.96", "d": "91.12"}, {"student_name": "student 176", "e": "100.00", "d": "226.04"}, {"student_name": "student 177", "e": "98.67", "d": "150.89"}, {"student_name": "student 178", "e": "97.49", "d": "68.79"}, {"student_name": "student 179", "e": "100.15", "d": "133.58"}, {"student_name": "student 180", "e": 0, "d": 0}, {"student_name": "student 181", "e": 0, "d": 0}, {"student_name": "student 182", "e": 0, "d": 0}, {"student_name": "student 183", "e": 0, "d": 0}, {"student_name": "student 184", "e": 0, "d": 0}, {"student_name": "student 185", "e": 0, "d": 0}, {"student_name": "student 186", "e": 0, "d": 0}, {"student_name": "student 187", "e": 0, "d": 0}, {"student_name": "student 188", "e": 0, "d": 0}, {"student_name": "student 189", "e": 0, "d": 0}, {"student_name": "student 190", "e": 0, "d": 0}, {"student_name": "student 191", "e": 0, "d": 0}]; createChart = function (data) { let max_d = d3.max(data, record => parseFloat(record.d)); let max_e = d3.max(data, record => parseFloat(record.e)); let max_y_scale_value_for_d = d3.max([100, max_d]); let max_y_scale_value_for_e = d3.max([100, max_e]); const plot = vl.markRect() .data(data) .transform([ { "calculate": "toNumber(datum.d)", "as": "d2" } ,{ "calculate": "toNumber(datum.e)", "as": "e2" } ,{ "density": "d2", "cumulative": true, "counts":true, "steps": 20 } ]) .encode( vl.y().fieldQ('density') .title('# students'), vl.x() .fieldO('value')//.bin(true) .axis({labelAngle:0,format:"d"}) .title('D') ).width(500).height(250); return plot.toObject(); } const chart_spec_json = this.createChart(data) const opt = { renderer: "canvas", actions: false }; vegaEmbed("#stats", chart_spec_json, opt);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script> <script src="https://unpkg.com/vega@5.21.0/build/vega.min.js"></script> <script src="https://unpkg.com/vega-lite@5.2.0/build/vega-lite.min.js"></script> <script src="https://www.unpkg.com/vega-embed@6.20.8/build/vega-embed.min.js"></script> <script src="https://unpkg.com/vega-lite-api@5.0.0/build/vega-lite-api.min.js"></script> <div id="stats" />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM