Vega低密度数据等高线显示及点按边界着色实现问题
解决方案
1. 先修复现有配置的基础语法问题
原配置中source数据集的url字段定义后缺少逗号,会直接导致配置加载失败,需要先修正该语法问题。
2. 应用Python计算的边界阈值
直接替换两处配置即可使用你提前算好的阈值,同时解决低密度数据下边界显示异常的问题:
- 把
boundary信号的bind交互配置删掉,直接将value固定为你用Python计算得到的实际阈值 - 修改
isocontour转换的levels参数,仅指定你需要的阈值作为唯一等高线层级,避免生成多余的无意义边界
3. 实现等高线内外数据点的颜色区分
新增数据转换给每个原始点标注是否在边界内,再修改着色逻辑即可:
- 给
source数据集新增转换步骤,计算每个点对应的密度值,和阈值比较生成in_contour标记字段 - 修改散点标记的填充色逻辑,同时结合
outlier分组和in_contour标记判断颜色,可直接用不同色值,也可以用透明度区分
4. 完整修改后的配置示例
{ "$schema": "https://vega.github.io/schema/vega/v4.json", "title": { "text": "异常值分布:贷款期限VS年龄", "anchor": "middle", "fontSize": 16, "frame": "group", "offset": 4 }, "signals": [ { "name": "boundary", "value": 0.3 // 此处替换为你Python计算得到的实际阈值 } ], "data": [ { "name": "source", "url" : { "index": "model_data", "body": { "size":10000, "_source": ["duration", "credit_amount", "asnm", "age", "outlier"] } }, "format": {"property": "hits.hits"}, "transform": [ { "type": "kde2d", "groupby": ["_source.outlier"], "size": [{"signal": "width"}, {"signal": "height"}], "x": {"expr": "scale('x', datum._source.duration)"}, "y": {"expr": "scale('y', datum._source.age)"}, "bandwidth": {"signal": "[boundary, boundary]"}, "as": "density_val" }, {"calculate": "datum.density_val >= boundary", "as": "in_contour"} ] }, { "name": "density", "source": "source", "transform": [ { "type": "kde2d", "groupby": ["_source.outlier"], "size": [{"signal": "width"}, {"signal": "height"}], "x": {"expr": "scale('x', datum._source.duration)"}, "y": {"expr": "scale('y', datum._source.age)"}, "bandwidth": {"signal": "[boundary, boundary]"} } ] }, { "name": "contours", "source": "density", "transform": [ { "type": "isocontour", "field": "grid", "levels": [{"signal": "boundary"}] } ] } ], "scales": [ { "name": "x", "type": "linear", "round": true, "nice": true, "zero": true, "domain": {"data": "source", "field": "_source.duration"}, "range": "width" }, { "name": "y", "type": "linear", "round": true, "nice": true, "zero": true, "domain": {"data": "source", "field": "_source.age"}, "range": "height" }, { "name": "color", "type": "ordinal", "domain": [0,1], "range": ["#1f77b4", "#ff7f0e"] } ], "axes": [ { "scale": "x", "grid": true, "domain": false, "orient": "bottom", "tickCount": 5, "title": "贷款期限" }, { "scale": "y", "grid": true, "domain": false, "orient": "left", "titlePadding": 5, "title": "年龄" } ], "legends": [ {"stroke": "color", "symbolType": "stroke", "title": "是否为异常值"} ], "marks": [ { "name": "marks", "type": "symbol", "from": {"data": "source"}, "encode": { "enter": { "fill": {"expr": "datum._source.outlier == 1 ? (datum.in_contour ? '#d62728' : '#ff9896') : (datum.in_contour ? '#2ca02c' : '#98df8a')"}, "size": {"value": 150} }, "update": { "x": {"scale": "x", "field": "_source.duration"}, "y": {"scale": "y", "field": "_source.age"} } } }, { "type": "path", "clip": true, "from": {"data": "contours"}, "encode": { "enter": { "strokeWidth": {"value": 2}, "strokeOpacity": {"value": 1}, "stroke": {"scale": "color", "field": "_source.outlier"} } }, "transform": [ { "type": "geopath", "field": "datum.contour" } ] } ] }
如果需要调整颜色直接修改fill的expr中的色值即可,和Python生成的效果对齐。
内容的提问来源于stack exchange,提问作者hanzgs
相关产品推荐
相关产品推荐

