Forum Discussion
Trelli/multiple scatter deneb
- 3 years ago
Hey Anonymous. Here's my implementation of the SPLOM (scatterplot matrix). Your dataset will need to be flattened and the structure will consist of the following 4 fields:
- Index - a sequential integer identifier for the row
- Observation - The idenitifying name for each dot in the matrix
- Attribute - The variable that will show up on the x and y axes
- Value - The value for the attribute for the given observation
{ "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "params": [{"name": "observation", "expr": "toString(brush['Observation'])"}], "data": { "name": "dataset", "url": "https://raw.githubusercontent.com/Giammaria/PublicFiles/master/pbi/pbi_community_help/20230309_trellis_scatter/data/mtcars_unpivoted.tsv", "format": {"parse": {"Index": "number", "Value": "number"}} }, "transform": [ {"joinaggregate": [{"op": "count", "as": "total_observation_count"}]}, { "calculate": "sequence(1,datum['total_observation_count']+1,1)", "as": "index_2" }, { "calculate": "split(replace(replace(join(datum['index_2'], ','), toString(datum['Index']), ''), ',,', ','), ',')", "as": "index_2" }, {"flatten": ["index_2"], "as": ["index_2"]}, {"filter": "datum['index_2']"}, {"calculate": "+datum['index_2']", "as": "index_2"}, { "lookup": "index_2", "from": { "data": {"name": "dataset"}, "key": "index", "fields": ["Attribute", "Value"] }, "as": ["attribute_2", "value_2"] }, { "calculate": "data('dataset')[datum['index_2']-1]", "as": "row_to_compare" }, {"filter": "datum['Observation']===datum['row_to_compare']['Observation']"}, {"calculate": "datum['row_to_compare']['Attribute']", "as": "attribute_2"}, {"calculate": "datum['row_to_compare']['Value']", "as": "value_2"}, { "calculate": "[datum['Attribute'], datum['attribute_2']]", "as": "variables" }, { "window": [{"op": "distinct", "field": "variables", "as": "facet_count"}], "frame": [null, null], "sort": [{"field": "facet_index", "order": "ascending"}] }, { "window": [ {"op": "dense_rank", "field": "variables", "as": "facet_index"} ], "sort": [{"field": "variables", "order": "ascending"}], "frame": [null, null] }, {"calculate": "floor(sqrt(datum['facet_count']))", "as": "row_count"}, { "calculate": "ceil(datum['facet_count']/datum['row_count'])", "as": "column_count" }, { "calculate": "datum['facet_index']%datum['column_count'] === 0 ? datum['column_count'] : datum['facet_index']%datum['column_count']", "as": "column" }, { "window": [{"op": "dense_rank", "as": "row"}], "groupby": ["column"], "frame": [null, 1], "sort": [{"field": "facet_index", "order": "ascending"}] }, { "window": [{"op": "row_number", "as": "facet_data_index"}], "groupby": ["facet_index"], "frame": [null, null] }, { "calculate": "datum['Attribute']+': '+toString(datum['Value'])", "as": "tooltipX" }, { "calculate": "datum['attribute_2']+': '+toString(datum['value_2'])", "as": "tooltipY" } ], "facet": { "row": {"field": "row", "title": null, "header": null, "type": "ordinal"}, "column": { "field": "column", "type": "ordinal", "title": null, "header": null } }, "spec": { "width": 150, "height": 150, "layer": [ { "name": "splom", "params": [ { "name": "brush", "select": { "type": "point", "on": "mouseover", "encodings": ["color"], "nearest": true, "clear": { "type": "mouseout" } } } ], "mark": {"type": "point", "filled": true}, "encoding": { "x": { "field": "Value", "type": "quantitative", "axis": {"title": null} }, "y": {"field": "value_2", "type": "quantitative", "title": null}, "color": { "condition": { "test": "observation===datum['Observation']", "field": "Observation", "type": "nominal", "legend": null }, "value": "steelblue" }, "size": { "condition": { "test": "observation===datum['Observation']", "value": 400 }, "value": 40 }, "tooltip": [ {"title": "Observation", "field": "Observation"}, {"title": "x", "field": "tooltipX"}, {"title": "y", "field": "tooltipY"} ] } }, { "name": "x-title", "transform": [{"filter": "datum['facet_data_index']===1"}], "mark": { "type": "text", "y": {"expr": "child_height"}, "yOffset": 25, "fontSize": 14 }, "encoding": {"text": {"field": "Attribute"}} }, { "name": "y-title", "transform": [{"filter": "datum['facet_data_index']===1"}], "mark": { "type": "text", "align": "center", "angle": 270, "x": {"expr": "0"}, "xOffset": -30, "fontSize": 14 }, "encoding": {"text": {"field": "attribute_2"}} } ] }, "resolve": { "axis": {"x": "independent", "y": "independent"}, "scale": {"x": "independent", "y": "independent"} }, "config": {"range": {"category": ["orange"]}} } - 3 years ago
Hey Jim. This is far from an idea solution but it's as close as I was able to get given the current limitations. Unfortunately we do not currently have control as to where the input elements (in this case, a slider) can be placed). I also had to switch from vega-lite to vega to implement this, so you'll want to make sure that the spec is set to vega in Deneb:
Ideally with your real dataset, you'd have fewer variables (attributes) and therefore, fewer charts in your SPLOM.If you need to change the initial size of your cells (which you probably should), you'll want to update this value:
could we imagine creating a small additional module or in the left part of the framework, which would allow an inexperienced user to modify, adjust the height and the width of the graphs? thanks again
This may be possible with input parameters. For example, I may be able to add a slider at the top that will allow the user to adjust the width and height of the facet cells. I will have to play around with the idea a bit later today when I have time and see if it's possible.
- giammariam3 years agoSolution Sage
Hey Jim. This is far from an idea solution but it's as close as I was able to get given the current limitations. Unfortunately we do not currently have control as to where the input elements (in this case, a slider) can be placed). I also had to switch from vega-lite to vega to implement this, so you'll want to make sure that the spec is set to vega in Deneb:
Ideally with your real dataset, you'd have fewer variables (attributes) and therefore, fewer charts in your SPLOM.If you need to change the initial size of your cells (which you probably should), you'll want to update this value:
- Anonymous3 years agoNot applicable
This is perfect. thanks a lot. The only point is maybe if you can just remove the requirement to press control to select certain attributes ....