Vega Zoom Circle Packing Chart - vega

I'm somewhat lost. I try to realize zoom in a circle packing chart but I don't know how to do it. There are two examples zoomable-scatter-plot zoomable-world-map but both approaches doesn't seem too fit for my chart type.
Any pointers/examples would be greatly appreciated.

Disclaimer: I still haven't had much time to get into Vega but I found a solution for this particular problem. I guess it is still not technical mature but it works.
The basic idea is to scale the circles and then move them into the middle of the graphic. To achieve this I added these signals:
"signals": [
{
"name": "scaleX",
"value": 1,
"on": [{"events": "click", "update": "(width/2)/datum.r"}]
},
{
"name": "scaleY",
"value": 1,
"on": [{"events": "click", "update": "(height/2)/datum.r"}]
},
{
"name": "xTranslation",
"value": 0,
"on": [{"events": "click", "update": "(width/2) - datum.x * scaleX"}]
},
{
"name": "yTranslation",
"value": 0,
"on": [{"events": "click", "update": "(height/2) - datum.y * scaleY"}]
}
]
and use them inside the mark encoding:
"update": {
"x": {"signal": "datum.x * scaleX + xTranslation"},
"y": {"signal": "datum.y * scaleY + yTranslation"},
"size": {"signal": "4 * datum.r * datum.r * scaleX * scaleY"},
"stroke": {"value": "white"},
"strokeWidth": {"value": 0.5}
}
Full example in Vega-Editor

Related

Vega Wordcloud Faceting

i really like the look of the vega Word Clouds:
https://vega.github.io/vega/examples/word-cloud/
I'm currently using the spec from the link as follows in colab:
spec = "insert spec here"
#Option one:
from altair import vega
vega.renderers.enable('colab')
vega.Vega(spec)
#Option two:
import panel as pn
from vega import Vega
pn.extension('vega')
pn.pane.Vega(spec)
But actually i want to make faceted wordclouds with vega. I currently load my data as json from my github account which is also slightly annoying, but i found no way to reference python variables in the vega spec.
Does anyone maybe have a hint, how i could layout the vega wordcloud in a grid by groups specified in my data? My json has this structure: [{"text":text,"group":group}], drawing the wordclouds from this works, but not the faceting by the group field. I know vega-lite can do faceting, but it can't draw the beautiful wordcloud it seems.
Thanks for any help!
Here is a working example of Vega spec using facet with your data.
For illustration only, the formula field for angle places words with larger field size in horizontal position.
View in Vega online editor
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A word cloud visualization depicting Vega research paper abstracts.",
"title": "A Wordcloud",
"width": 400,
"height": 400,
"padding": 10,
"background": "ghostwhite",
"layout": {
"bounds": "flush",
"columns": 2,
"padding": 10
},
"data": [
{
"name": "table",
"url": "https://raw.githubusercontent.com/nyanxo/vega_facet_wordcloud/main/split.json",
"transform": [
{
"type": "formula",
"as": "angle",
"expr": "datum.size >= 3 ? 0 : [-45,-30, -15, 0, 15, 30, 45][floor(random() * 7)]"
}
]
}
],
"scales": [
{
"name": "color",
"type": "ordinal",
"domain": {"data": "table", "field": "text_split"},
"range": ["#d5a928", "#652c90", "#939597"]
}
],
"marks": [
{
"type": "group",
"from": {
"facet": {
"name": "facet",
"data": "table",
"groupby": "group"
}
},
"title": {
"text": {"signal": "parent.group"},
"frame": "group"
},
"encode": {
"update": {
"width": {"signal": "width"},
"height": {"signal": "height"}
}
},
"marks": [
{
"type": "rect",
"encode": {
"enter": {
"x": {"value": 0},
"width": {"signal": "width" },
"y": {"value": 0},
"height": {"signal": "height"},
"fill": {"value": "beige"}
}
}
},
{
"type": "text",
"from": {"data": "facet"},
"encode": {
"enter": {
"text": {"field": "text_split"},
"align": {"value": "center"},
"baseline": {"value": "alphabetic"},
"fill": {"scale": "color", "field": "text_split"}
},
"update": {"fillOpacity": {"value": 1}},
"hover": {"fillOpacity": {"value": 0.5}}
},
"transform": [
{
"type": "wordcloud",
"size": {"signal": "[width, height]"},
"text": {"field": "text_split"},
"rotate": {"field": "datum.angle"},
"font": "Helvetica Neue, Arial",
"fontSize": {"field": "datum.size"},
"fontSizeRange": [12, 28],
"padding": 2
}
]
}
]
}
]
}
You can't facet a word cloud as it requires a CountPattern transform which will destroy any faceting field you try to use. Instead you will need to provide a separate data object for each word cloud you want and then concatenate them together.
Edit
Link
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A word cloud visualization depicting Vega research paper abstracts.",
"title": "A Wordcloud",
"width": 420,
"height": 400,
"padding": 0,
"data": [
{
"name": "table",
"url": "https://raw.githubusercontent.com/nyanxo/vega_facet_wordcloud/main/split.json"
}
],
"scales": [
{
"name": "color",
"type": "ordinal",
"domain": {"data": "table", "field": "text_split"},
"range": ["#d5a928", "#652c90", "#939597"]
}
],
"layout": {"padding": 20, "columns": 2, "bounds": "full", "align": "all"},
"marks": [
{
"name": "cell",
"type": "group",
"style": "cell",
"from": {
"facet": {"name": "facet", "data": "table", "groupby": ["group"]}
},
"encode": {
"update": {"width": {"signal": "400"}, "height": {"signal": "400"}}
},
"marks": [
{
"type": "text",
"from": {"data": "facet"},
"encode": {
"enter": {
"text": {"field": "text_split"},
"align": {"value": "center"},
"baseline": {"value": "alphabetic"},
"fill": {"scale": "color", "field": "text_split"}
},
"update": {"fillOpacity": {"value": 1}},
"hover": {"fillOpacity": {"value": 0.5}}
},
"transform": [
{
"type": "wordcloud",
"size": [400, 400],
"text": {"field": "text_split"},
"font": "Helvetica Neue, Arial",
"fontSizeRange": [12, 56],
"padding": 2
}
]
}
]
}
]
}

How would I add a tooltip to a multi series line chart

I'm new to WebStorm and vega/vegalite and I am working on creating a visual with different types of gasoline and their prices from 1996-2020.
I've been able to create a graph with all of the information, but it's pretty hard to discern anything.
I've been going over the Vega-Lite documentation and I see that that I can use tooltips to zoom into the graphic. I tried implementing it, but I don't think I quite understand the scope of some of the properties.
Could someone show me how they might approach this task? Or perhaps even recommend videos or websites that might help me better understand how to do?
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "Area charts of stock prices, with an interactive overview and filtered detail views.",
"width": 720,
"height": 480,
"padding": 5,
"data": {
"name": "gas_prices",
"url": "data/testInfo.csv",
"format": {"type": "csv", "parse": {"A1": "number", "date": "date"}}
},
"repeat": {
"layer": ["A1","A2","A3","R1","R2","R3","M1","M2","M3","P1","P2","P3","D1"]
},
"spec": {
"mark": "line",
"encoding": {
"x": {
"timeUnit": "yearmonth",
"title": "Date",
"field": "date"
},
"y": {
"field": {"repeat":"layer"},
"title": "Gas Prices",
"type": "quantitative"
},
"color": {
"datum": {"repeat": "layer"},
"type": "nominal"
}
}
}
}
You can refer the documentation for tooltip, which says about the options available to enable tooltips on your chart.
Below is a sample config having default tooltip or refer editor:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"repeat": ["Horsepower", "Miles_per_Gallon", "Acceleration", "Displacement"],
"columns": 2,
"spec": {
"data": {"url": "data/cars.json"},
"mark": {"type": "bar", "tooltip": true},
"encoding": {
"x": {"field": {"repeat": "repeat"}, "bin": true},
"y": {"aggregate": "count"},
"color": {"field": "Origin"}
}
}
}
To have tooltips with some customizations, you can refer below code or editor:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"repeat": ["Horsepower", "Miles_per_Gallon", "Acceleration", "Displacement"],
"columns": 2,
"spec": {
"data": {"url": "data/cars.json"},
"mark": "bar",
"encoding": {
"tooltip": [
{"aggregate": "count", "title": "YAxis"},
{"field": {"repeat": "repeat"}, "title": "myXAxis"}
],
"x": {"field": {"repeat": "repeat"}, "bin": true},
"y": {"aggregate": "count"},
"color": {"field": "Origin"}
}
}
}

Legend overlaps with donut chart vega

I'm creating a donut chart using Vega and the legend overlaps the chart despite everything I've tried.
Using orient: bottom-right: https://imgur.com/RZ2msqF
I've also tried to finagle the image into the empty space using legendX, legendY but the text cuts off.
Increasing width of the specification would work except it auto-centers the visualization, and I'm trying to avoid any more empty space than necessary.
I'm looking for a way to align the chart to the left instead of auto-centering, or anything else you guys can think of. Thanks!
You can set the outerRadius of each arc "slice of pie" in the marks section of the spec.json file, it is divided by width so increasing the default to 2.5 or 3 worked for me.
"marks": [
{
"type": "arc",
"from": {
"data": "table"
},
"encode": {
"enter": {
"fill": {
"scale": "color",
"field": "id"
},
"x": {
"signal": "width / 2"
},
"y": {
"signal": "height / 2"
}
},
"update": {
"startAngle": {
"field": "startAngle"
},
"endAngle": {
"field": "endAngle"
},
"padAngle": {
"signal": "padAngle"
},
"innerRadius": {
"signal": "width / 4"
},
"outerRadius": {
"signal": "width / 2.5"
},
"cornerRadius": {
"signal": "cornerRadius"
}
}
}
}
]

Render different fill/stroke colours depending on positive/negative x-axis value

I'm trying to code a little chart for use in risk/opportunity analysis. You feed in 4 values:
PreConsequence & PostConsequence (int's ranging -4 to +4)
PreLikelihood & PostLikelihood (int's ranging 0 to 4)
And it visualises those with charts as follows:
The shaded fill renders the Pre values, whilst the stroke renders the Post values.
Geometry in the left quadrant represents risk and should be red, whilst geometry in the right quadrant represents opportunity and should be green.
I'm struggling to find out how to check for negative consequence values and assign colour accordingly. I think it'll be done in the last two lines of my code below:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 500,
"height": 250,
"data": [
{
"name": "table",
"values": [
{"C": -4, "L": 0, "f":"Pre"}, {"C": 0, "L": 4, "f":"Pre"},
{"C": 0, "L": 2, "f":"Post"}, {"C": -1, "L": 0, "f":"Post"}
]
}
],
"scales": [
{
"name": "xscale",
"type": "linear",
"range": "width",
"nice": true,
"zero": true,
"domain": {"data": "table", "field": "C"},
"domainMax": 4,
"domainMin": -4
},
{
"name": "yscale",
"type": "linear",
"range": "height",
"domain": {"data": "table", "field": "L"},
"domainMax": 4,
"domainMin": 0
},
{
"name": "color",
"type": "ordinal",
"range":"ordinal",
"domain": {"data": "table", "field": "f"}
}
],
"axes": [
{"orient": "bottom", "scale": "xscale", "tickCount": 10 },
{"orient": "left", "scale": "yscale", "tickCount": 5, "offset": -250 }
],
"marks": [
{
"type": "group",
"from": {
"facet": {
"name": "series",
"data": "table",
"groupby": "f"
}
},
"marks": [
{
"type": "area",
"from": {"data": "series"},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "C" },
"y": {"scale": "yscale", "field": "L"},
"y2": {"scale": "yscale", "value": 0 },
"fillOpacity": [{ "test": "indata('series', 'f', 'Pre')", "value": 0.3 }, {"value": 0}],
"strokeWidth": [{ "test": "indata('series', 'f', 'Pre')", "value": 0 }, {"value": 2}],
"fill": [{ "test": "indata('series', 'f', 'Pre')", "value": "red" }, {"value": "red"}],
"stroke": [{ "test": "indata('series', 'f', 'Pre')", "value": "red" }, {"value": "red"}]
}
}
}
]
}
]
}
Can anyone give me some pointers as to how to test the data values & set fill & stroke colours accordingly?
Thanks
Vega signals can be used to conditionally paint colors based on data values.
In the given vega spec, changing the fill property like this should do what you are expecting if data has Positive quadrant C values also.
"fill": { "signal": "datum.C > 0 ? 'green': 'red'"},

How to create a stacked bar chart with values in Vega?

I'm creating a custom visualization in Vega for Kibana. It should display vertical stacked bars and their values in numbers.
The "y" axis is the doc count and the "x" axis a time scale.
I'm not familiar with Vega and I first tried to display numbers on simple bars. I copy/pasted, tweeked some parameters and had this version :
"marks": [
{
"type": "group",
"marks": [
{
"type": "rect",
"name": "bars",
"from": {"data":"table"},
"encode": {
"enter": {
"x": {"scale": "xbars", "field": "key"},
"width": {"scale": "xbars", "band": 1},
"y": {"scale": "yscale", "field": "doc_count"},
"y2": {"scale": "yscale", "value": 0}
}
}
},
{
"type": "text",
"from": {"data": "bars"},
"align": "center",
"encode": {
"enter": {
"y": {"field": "y", "offset": -5},
"x": {"field": "x", "offset": 0},
"text": {"field": "datum.doc_count"}
}
}
}
]
}
]
The result displays simple bars, numbers, the time format is good.
I used a "y"and a "y2" to be able to display both bars and text, but I can't add anymore "y" axis ("y3", "y4"...).
Idon't even know if it's possible to do what I want.
It want the chart to look like this example but with numbers :
https://vega.github.io/vega/examples/stacked-bar-chart/