Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vega Heatmap #389

Closed
wants to merge 13 commits into from
188 changes: 160 additions & 28 deletions notebook/integration_demo/demo.ipynb

Large diffs are not rendered by default.

658 changes: 423 additions & 235 deletions notebook/visual examples/Graphs.ipynb

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/pyciemss/visuals/graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,10 @@ def spring_force_graph(
labels = vega.find_named(schema["marks"], "labels")
labels["encode"]["enter"]["text"]["field"] = f"datum.{node_labels}"

if not directed_graph:
schema["marks"] = vega.delete_named(schema["marks"], "arrows")

return schema



78 changes: 78 additions & 0 deletions src/pyciemss/visuals/histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,81 @@ def as_value_list(label, data):
return schema, pd.DataFrame(desc).set_index(["bin0", "bin1"])
else:
return schema



def heatmap_scatter(
data: pd.DataFrame,
x_name: str = "x_name",
y_name: str = "y_name",
x_bin: int = 10,
y_bin: int = 10
) -> vega.VegaSchema:
"""
**data -- Datasets as pandas dataframe, should contain x_name and y_name,
x_name: str name of column in dataset for x axis,
y_name: str, name of column in dataset for y axis,
x_bin: int = 10, max bins by x axis,
y_bin: int = 10, max bins by y axis,
"""
json_dict = data.to_json(orient = 'records')
schema = vega.load_schema("heatmap_scatter.vg.json")

schema["data"] = vega.replace_named_with(schema["data"], "points", ["values"], json_dict)

schema["data"] = vega.replace_named_with(schema["data"], "source_0", ["values"], json_dict)

schema["signals"] = vega.replace_named_with(
schema["signals"], "bandwidthX", ["value"], x_bin
)
schema["signals"] = vega.replace_named_with(
schema["signals"], "bandwidthY", ["value"], y_bin
)
schema["signals"] = vega.replace_named_with(
schema["signals"], "x_name", ["value"], x_name
)

schema["signals"] = vega.replace_named_with(
schema["signals"], "y_name", ["value"], y_name
)

return schema



def mesh_scatter(
mesh_data,
scatter_data: pd.DataFrame,
) -> vega.VegaSchema:
"""
**mesh_data -- input as mesh data, will be converted to grids
**scatter_data -- with alpha and gamma data
"""

schema = vega.load_schema("mesh_scatter.vg.json")

def mesh_to_heatmap(mesh_data):
"""
**mesh_data -- input as mesh data, will be converted to grids
adding half the difference in grid spacing to each coordinate
so point becomes center of a grid for heatmap
"""
xv, yv, zz = mesh_data
half_spacing_x = (xv[0, 1] - xv[0, 0])/2
half_spacing_y = (yv[1, 0] - yv[0, 0])/2
dataset = pd.DataFrame({"x_start": xv.ravel() - half_spacing_x, \
"x_end": xv.ravel() + half_spacing_x, \
"y_start": yv.ravel() - half_spacing_y,
"y_end": yv.ravel() + half_spacing_y,
'__count': zz.ravel()})
return dataset.to_json(orient="records")

# convert to json
json_heatmap = mesh_to_heatmap(mesh_data)
json_scatter = scatter_data.to_json(orient="records")

# update data in schema
schema["data"] = vega.replace_named_with(schema["data"], "points", ["values"], json_scatter)
schema["data"] = vega.replace_named_with(schema["data"], "mesh", ["values"], json_heatmap)

return schema
4 changes: 3 additions & 1 deletion src/pyciemss/visuals/plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from .barycenter import triangle_contour
from .trajectories import trajectories
from .calibration import calibration
from .histogram import histogram_multi
from .histogram import histogram_multi, heatmap_scatter, mesh_scatter
from .graphs import attributed_graph, spring_force_graph


Expand All @@ -26,6 +26,8 @@
histogram_multi,
attributed_graph,
spring_force_graph,
heatmap_scatter,
mesh_scatter
]


Expand Down
191 changes: 191 additions & 0 deletions src/pyciemss/visuals/schemas/heatmap_scatter.vg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 300,
"height": 200,
"signals": [
{
"name": "bandwidthX", "value": 3,
"bind": {"input": "range", "min": 1, "max": 100, "step": 1}
},
{
"name": "bandwidthY", "value": 3,
"bind": {"input": "range", "min": 1, "max": 100, "step": 1}
},
{ "name": "x_name", "value": "x_value",
"bind": {"input": "text"}
},

{ "name": "y_name", "value": "y_value",
"bind": {"input": "text"}
}
],
"data": [
{
"name": "points",
"values": [
{"x_value": 2, "y_value": 10},
{"x_value": 3, "y_value": 5},
{"x_value": 3, "y_value": 5},
{"x_value": 10, "y_value": 6},
{"x_value": 2, "y_value": 3},
{"x_value": 4, "y_value": 10},
{"x_value": 3, "y_value": 1}
]
},
{
"name": "source_0",
"values": [
{"x_value": 2, "y_value": 10},
{"x_value": 3, "y_value": 5},
{"x_value": 3, "y_value": 5},
{"x_value": 2, "y_value": 3},
{"x_value": 4, "y_value": 10},
{"x_value": 3, "y_value": 1}
],
"format": {"type": "json"},
"transform": [

{
"type": "extent",
"field": {"signal": "x_name"},
"signal": "x_extent"
},
{
"type": "bin",
"field": {"signal": "x_name"},
"as": [
"x_start",
"x_end"
],
"signal": "x_bins",
"extent": {"signal": "x_extent"},
"maxbins": {"signal": "bandwidthX"}
},
{
"type": "extent",
"field": {"signal": "y_name"},
"signal": "y_extent"
},
{
"type": "bin",
"field": {"signal": "y_name"},
"as": [
"y_start",
"y_end"
],
"signal": "y_bins",
"extent": {"signal": "y_extent"},
"maxbins": {"signal": "bandwidthY"}
},
{
"type": "aggregate",
"groupby": [
"x_start",
"x_end",
"y_start",
"y_end"
],
"ops": ["count"],
"as": ["__count"]
}
]
}
],
"marks": [
{
"name": "marks",
"type": "rect",
"style": ["rect"],
"from": {"data": "source_0"},
"encode": {
"update": {
"fill": {"scale": "color", "field": "__count"},
"x2": {
"scale": "x",
"field": "x_start"
},
"x": {
"scale": "x",
"field": "x_end"
},
"y2": {
"scale": "y",
"field": "y_start"
},
"y": {
"scale": "y",
"field": "y_end"
}
}
}
},
{
"type": "symbol",
"from": {"data": "points"},
"encode": {
"enter": {
"fillOpacity": {"value": 1},
"fill": {"value": "black"}
},
"update": {
"x": {"scale": "x", "field" : {"signal": "x_name"}},
"y": {"scale": "y", "field" : {"signal": "y_name"}},
"size": {"value": 10}
}
}
}
],
"scales": [
{
"name": "x",
"type": "linear",
"domain": {
"signal": "[x_bins.start, x_bins.stop]"
},
"range": [0, {"signal": "width"}],
"bins": {"signal": "x_bins"},
"zero": false
},
{
"name": "y",
"type": "linear",
"domain": {
"signal": "[y_bins.start, y_bins.stop]"
},
"range": [{"signal": "height"}, 0],
"bins": {"signal": "y_bins"},
"zero": false
},
{
"name": "color",
"type": "linear",
"domain": {"data": "source_0", "field": "__count"},
"range": "heatmap",
"interpolate": "hcl",
"zero": false
}
],
"axes": [
{
"scale": "x",
"orient": "bottom",
"title": {"signal": "x_name"},
"labelOverlap": true,
"tickCount": {"signal": "ceil(width/3)"}
},
{
"scale": "y",
"orient": "left",
"title": {"signal": "y_name"},
"labelOverlap": true,
"tickCount": {"signal": "ceil(height/3)"}
}
],
"legends": [
{
"fill": "color",
"gradientLength": {"signal": "height - 16"},
"title": "Count of Records"
}
]
}
Loading