Beeswarm Plot Example
A beeswarm plot conveys the size of a group of items by visually clustering the each individual data point. This example uses Vega’s force transform to calculate the clustered layout. The example uses non-standard xfocus
and yfocus
encoding channels to create anchor coordinates that parameterize the x
and y
forces.
Vega JSON Specification <>
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A beeswarm chart example that uses a force-directed layout to group items by category.",
"width": 800,
"height": 100,
"padding": {"left": 5, "right": 5, "top": 0, "bottom": 20},
"autosize": "none",
"signals": [
{ "name": "cx", "update": "width / 2" },
{ "name": "cy", "update": "height / 2" },
{ "name": "radius", "value": 8, "bind": {"input": "range", "min": 2, "max": 15, "step": 1} },
{ "name": "collide", "value": 1, "bind": {"input": "range", "min": 1, "max": 10, "step": 1} },
{ "name": "gravityX", "value": 0.2, "bind": {"input": "range", "min": 0, "max": 1} },
{ "name": "gravityY", "value": 0.1, "bind": {"input": "range", "min": 0, "max": 1} },
{ "name": "static", "value": true, "bind": {"input": "checkbox"} }
],
"data": [
{
"name": "people",
"url": "data/miserables.json",
"format": {"type": "json", "property": "nodes"}
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {
"data": "people",
"field": "group",
"sort": true
},
"range": "width"
},
{
"name": "color",
"type": "ordinal",
"domain": {"data": "people", "field": "group"},
"range": {"scheme": "category20c"}
}
],
"axes": [
{ "orient": "bottom", "scale": "xscale" }
],
"marks": [
{
"name": "nodes",
"type": "symbol",
"from": {"data": "people"},
"encode": {
"enter": {
"fill": {"scale": "color", "field": "group"},
"xfocus": {"scale": "xscale", "field": "group", "band": 0.5},
"yfocus": {"signal": "cy"}
},
"update": {
"size": {"signal": "pow(2 * radius, 2)"},
"stroke": {"value": "white"},
"strokeWidth": {"value": 1},
"zindex": {"value": 0}
},
"hover": {
"stroke": {"value": "purple"},
"strokeWidth": {"value": 3},
"zindex": {"value": 1}
}
},
"transform": [
{
"type": "force",
"iterations": 300,
"static": {"signal": "static"},
"forces": [
{"force": "collide", "iterations": {"signal": "collide"}, "radius": {"signal": "radius"}},
{"force": "x", "x": "xfocus", "strength": {"signal": "gravityX"}},
{"force": "y", "y": "yfocus", "strength": {"signal": "gravityY"}}
]
}
]
}
]
}