Vega avanzado para visualizar datos electorales

Aprendí un poco de Vega hace un tiempo, pero no me adentré tanto en sus mecanismos y capacidades. Tal parece que Vega permite hacer todo tipo de visualizaciones. Es realmente una gramática con posibilidades infinitas. He logrado hacer un explorador de datos electorales en Guatemala, pero la idea no es quedarse solo en ver conteos si no otras dimensiones más interesantes, como patrones de votos por municipios, partidos y departamentos. El proyecto aún no está listo, así que dejo un adelanto de cómo se verá.

 

 

Lo pueden probar en el editor de vega:

 

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "autosize": "pad",
  "padding": 5,
  "height": 400,
  "title": {"text": "Votos Emitidos", "fontSize": 20, "anchor": "start"},
  "data": [
    {
      "name": "deptosGT",
      "url": "https://bodegona.nyc3.digitaloceanspaces.com/data/GIS-GT/gt-deptos-lowq-2017.geojson",
      "format": {"property": "features", "type": "json"}
    },
    {
      "name": "source_0",
      "url": "https://bodegona.nyc3.digitaloceanspaces.com/data/Nomada/elecciones-gt-2007-2011-2015.csv",
      "format": {"type": "csv"},
      "transform": [
        {
          "type": "formula",
          "expr": "(datum.municode >=200? floor(datum.municode/100)*100 : 101) + ''",
          "as": "deptocode"
        }
      ]
    },
    {
      "name": "source_1",
      "url": "https://bodegona.nyc3.digitaloceanspaces.com/data/GIS-GT/gt-munis-lowq-2017.geojson",
      "format": {"property": "features", "type": "json"}
    },
    {
      "name": "data_0",
      "source": "source_0",
      "transform": [
        {
          "type": "aggregate",
          "groupby": ["Vuelta"],
          "ops": ["sum"],
          "fields": ["Emitidos"],
          "as": ["sum_Emitidos"]
        }
      ]
    },
    {
      "name": "data_1",
      "source": "source_0",
      "transform": [
        {
          "type": "filter",
          "expr": "datum.Vuelta == vuelta_select"
        },
        {
          "type": "aggregate",
          "groupby": ["deptocode"],
          "ops": ["sum"],
          "fields": ["Emitidos"],
          "as": ["vdep"]
        },
        {
          "type": "lookup",
          "from": "deptosGT",
          "key": "properties.CODIGO",
          "fields": ["deptocode"],
          "as": ["geo"]
        },
        {
          "type": "formula",
          "expr": "datum[\"geo\"] && datum[\"geo\"][\"properties\"] && datum[\"geo\"][\"properties\"][\"DEPARTAMEN\"]",
          "as": "geo.properties.DEPARTAMEN"
        },
        {"type": "filter", "expr": "datum.geo.properties.CODIGO!='2300'"},
        {
          "type": "geojson",
          "geojson": "geo",
          "signal": "concat_0_concat_1_geojson_0"
        },
        {
          "type": "filter",
          "expr": "datum[\"vdep\"] !== null && !isNaN(datum[\"vdep\"])"
        }
      ]
    },
    {
      "name": "data_3",
      "source": "source_0",
      "transform": [
        {
          "type": "filter",
          "expr": "datum.Vuelta == vuelta_select"
        },
        {
          "type": "filter",
          "expr": "depto_select == null? true : (datum.deptocode == depto_select)"
        },
        {
          "type": "lookup",
          "from": "source_1",
          "key": "properties.COD_MUNI__",
          "fields": ["municode"],
          "as": ["geo"]
        },
        {
          "type": "formula",
          "expr": "datum[\"geo\"] && datum[\"geo\"][\"properties\"] && datum[\"geo\"][\"properties\"][\"DEPTO__\"]",
          "as": "geo.properties.DEPTO__"
        },
        {
          "type": "formula",
          "expr": "datum[\"geo\"] && datum[\"geo\"][\"properties\"] && datum[\"geo\"][\"properties\"][\"NOMBRE__\"]",
          "as": "geo.properties.NOMBRE__"
        },
        {"type": "geojson", "geojson": "geo", "signal": "concat_1_geojson_0"},
        {
          "type": "filter",
          "expr": "datum[\"Emitidos\"] !== null && !isNaN(datum[\"Emitidos\"])"
        }
      ]
    }
  ],
  "projections": [
    {
      "name": "projection",
      "size": {"signal": "[concat_0_width, concat_0_concat_1_height]"},
      "fit": {"signal": "concat_0_concat_1_geojson_0"},
      "type": "mercator"
    },
    {
      "name": "concat_1_projection",
      "size": {"signal": "[concat_1_width, height]"},
      "fit": {"signal": "concat_1_geojson_0"},
      "type": "mercator"
    }
  ],
  "signals": [
    {
        "name": "vuelta_select", 
        "value": "2007 - 1ra Vuelta", 
        "on": [{
            "events": "@concat_0_concat_0_marks:click",
            "update": "datum.Vuelta"
        }]
    },
    {
        "name": "depto_select", 
        "value": null, 
        "on": [{
            "events": "@concat_0_concat_1_group:click, @concat_0_concat_1_marks:click",
            "update": "( item().mark.marktype == 'group' ? null : (depto_select == datum['geo']['properties']['CODIGO']? null : datum['geo']['properties']['CODIGO']) )"
        }]
    },
    {"name": "concat_0_width", "value": 200},
    {"name": "concat_0_concat_0_height", "value": 90},
    {"name": "concat_0_concat_1_height", "value": 200},
    {"name": "concat_1_width", "value": 400},
    {
      "name": "unit",
      "value": {},
      "on": [
        {"events": "mousemove", "update": "isTuple(group()) ? group() : unit"}
      ]
    }
  ],
  "layout": {"padding": 30, "bounds": "full", "align": "each"},
  "marks": [
    {
      "type": "group",
      "name": "concat_0_group",
      "layout": {
        "padding": 30,
        "columns": 1,
        "bounds": "full",
        "align": "each"
      },
      "marks": [
        {
          "type": "group",
          "name": "concat_0_concat_0_group",
          "style": "cell",
          "encode": {
            "update": {
              "width": {"signal": "concat_0_width"},
              "height": {"signal": "concat_0_concat_0_height"}
            }
          },
          "signals": [
          ],
          "marks": [
            {
              "name": "concat_0_concat_0_marks",
              "type": "rect",
              "style": ["bar"],
              "from": {"data": "data_0"},
              "encode": {
                "update": {
                  "fill": [
                    {
                      "test": "datum.Vuelta == vuelta_select",
                      "value": "#1155bb"
                    },
                    {"value": "#aaaaaa"}
                  ],
                  "opacity": {"value": 0.8},
                  "tooltip": {
                    "signal": "{\"Vuelta\": ''+datum[\"Vuelta\"], \"Votos Emitidos\": format(datum[\"sum_Emitidos\"], \"\")}"
                  },
                  "x": {
                    "scale": "concat_0_concat_0_x",
                    "field": "sum_Emitidos"
                  },
                  "x2": {"scale": "concat_0_concat_0_x", "value": 0},
                  "y": {"scale": "concat_0_concat_0_y", "field": "Vuelta"},
                  "height": {"scale": "concat_0_concat_0_y", "band": true}
                }
              }
            }
          ],
          "axes": [
            {
              "scale": "concat_0_concat_0_x",
              "orient": "bottom",
              "grid": false,
              "title": "Votos Emitidos",
              "labelFlush": true,
              "labelOverlap": true,
              "tickCount": {"signal": "ceil(concat_0_width/40)"},
              "zindex": 1
            },
            {
              "scale": "concat_0_concat_0_x",
              "orient": "bottom",
              "gridScale": "concat_0_concat_0_y",
              "grid": true,
              "tickCount": {"signal": "ceil(concat_0_width/40)"},
              "domain": false,
              "labels": false,
              "maxExtent": 0,
              "minExtent": 0,
              "ticks": false,
              "zindex": 0
            },
            {
              "scale": "concat_0_concat_0_y",
              "orient": "right",
              "grid": false,
              "title": "Vuelta",
              "zindex": 1
            }
          ]
        },
        {
          "type": "group",
          "name": "concat_0_concat_1_group",
          "title": {"text": "Departamentos", "frame": "group"},
          "style": "cell",
          "encode": {
            "update": {
              "width": {"signal": "concat_0_width"},
              "height": {"signal": "concat_0_concat_1_height"}
            }
          },
          "signals": [
          ],
          "marks": [
            {
              "name": "concat_0_concat_1_marks",
              "type": "shape",
              "style": ["geoshape"],
              "from": {"data": "data_1"},
              "encode": {
                "update": {
                  "stroke": {"value": "#999999"},
                  "strokeWidth": [
                    {
                      "test": "depto_select != null?datum.deptocode == depto_select: true",
                      "value": 1
                    },
                    {"value": 0.2}
                  ],
                  "fill": [
                    {
                      "test": "depto_select != null?datum.deptocode == depto_select: true",
                      "scale": "concat_0_concat_1_color",
                      "field": "vdep"
                    },
                    {"value": "#dddddd"}
                  ],
                  "tooltip": {
                    "signal": "{\"Votos\": format(datum[\"vdep\"], \",d\"), \"Departamento\": ''+datum[\"geo.properties.DEPARTAMEN\"]}"
                  }
                }
              },
              "transform": [
                {
                  "type": "geoshape",
                  "projection": "projection",
                  "field": "datum[\"geo\"]"
                }
              ]
            }
          ],
          "legends": [
            {
              "format": "~s",
              "fill": "concat_0_concat_1_color",
              "gradientLength": {
                "signal": "clamp(concat_0_concat_1_height, 64, 140)"
              },
              "symbolType": "circle",
              "title": "Votos"
            }
          ]
        }
      ]
    },
    {
      "type": "group",
      "name": "concat_1_group",
      "title": {"text": "Municipios", "frame": "group"},
      "style": "cell",
      "encode": {
        "update": {
          "width": {"signal": "concat_1_width"},
          "height": {"signal": "height"}
        }
      },
      "marks": [
        {
          "name": "concat_1_marks",
          "type": "shape",
          "style": ["geoshape"],
          "from": {"data": "data_3"},
          "encode": {
            "update": {
              "fill": {"scale": "concat_1_color", "field": "Emitidos"},
              "tooltip": {
                "signal": "{\"Nulos\": format(datum[\"Nulos\"], \",d\"), \"Blancos\": format(datum[\"Blancos\"], \",d\"), \"Emitidos\": format(datum[\"Emitidos\"], \",d\"), \"Departamento\": ''+datum[\"geo.properties.DEPTO__\"], \"Municipio\": ''+datum[\"geo.properties.NOMBRE__\"], \"Código\": ''+datum[\"municode\"]}"
              }
            }
          },
          "transform": [
            {
              "type": "geoshape",
              "projection": "concat_1_projection",
              "field": "datum[\"geo\"]"
            }
          ]
        }
      ],
      "legends": [
        {
          "format": "~s",
          "title": "Votos",
          "fill": "concat_1_color",
          "gradientLength": {"signal": "clamp(height, 40, 200)"},
          "symbolType": "circle"
        }
      ]
    }
  ],
  "scales": [
    {
      "name": "concat_0_concat_0_x",
      "type": "linear",
      "domain": {"data": "data_0", "field": "sum_Emitidos"},
      "range": [0, {"signal": "concat_0_width"}],
      "nice": true,
      "zero": true
    },
    {
      "name": "concat_0_concat_0_y",
      "type": "band",
      "domain": {"data": "data_0", "field": "Vuelta", "sort": true},
      "range": [0, {"signal": "concat_0_concat_0_height"}],
      "paddingInner": 0.1,
      "paddingOuter": 0.05
    },
    {
      "name": "concat_0_concat_1_color",
      "type": "linear",
      "domain": {"data": "data_1", "field": "vdep"},
      "range": {"scheme": "goldgreen"},
      "interpolate": "hcl",
      "zero": false
    },
    {
      "name": "concat_1_color",
      "type": "linear",
      "domain": {"data": "data_3", "field": "Emitidos"},
      "range": {"scheme": "goldgreen"},
      "interpolate": "hcl",
      "zero": false
    }
  ],
  "config": {"style": {"cell": {"stroke": "transparent"}}}
}