block by michalskop 8550970

Senate Elections 2014, Zlín; Ecological Inference using Regression

Full Screen

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<title>Senate Elections 2014, Zlín (80)</title>
<style>

#chart {
  height: 700px;
}

.node rect {
  cursor: move;
  fill-opacity: .9;
  shape-rendering: crispEdges;
}

.node text {
  pointer-events: none;
  text-shadow: 0 1px 0 #fff;
}

.link {
  fill: none;
  stroke: #000;
  stroke-opacity: .1;
}

.kuncar {
  stroke: #FEDC35;
  stroke-opacity: .4;
}

.lukas {
  stroke: #008;
  stroke-opacity: .2;
}

.link:hover {
  stroke-opacity: .5;
}

</style>
<body>

<h1>Senate Elections 2014, Zlín (80)</h1>

<p id="chart"></p>

<p>The values are estimated by regression from polling station-level results.</p>
<p>The analysis flow:
<ol><li>round1.csv, round2.csv</li>
<li>ei_regression.r</li>
<li>zlin4sanky.csv -> zlin4sankey.py -> sankey_zlin_2014.json</li>
</ol>
</p>
<p>Data available on <a href="//ovolby.cz">OtevřenéVolby.cz</a></p>

<script src="//d3js.org/d3.v2.min.js?2.9.1"></script>
<script src="sankey.js"></script>
<script>

var margin = {top: 1, right: 1, bottom: 6, left: 1},
    width = 960 - margin.left - margin.right,
    height = 700 - margin.top - margin.bottom;

var formatNumber = d3.format(",.0f"),
    format = function(d) { return formatNumber(d); },
    color = function(d){ return d.color; };//d3.scale.category20();

var svg = d3.select("#chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var sankey = d3.sankey()
    .nodeWidth(15)
    .nodePadding(10)
    .size([width, height]);

var path = sankey.link();

d3.json("sankey_zlin_2014.json", function(energy) {

  sankey
      .nodes(energy.nodes)
      .links(energy.links)
      .layout(32);

  var link = svg.append("g").selectAll(".link")
      .data(energy.links)
    .enter().append("path")
      .attr("class", function (d) {
        if (d.target.j == 10) return "kuncar link"; 
        else if (d.target.j == 11) return "lukas link"; 
        else return "link"
      })
      .attr("d", path)
      .style("stroke-width", function(d) { return Math.max(1, d.dy); })
      .sort(function(a, b) { return b.dy - a.dy; });

  link.append("title")
      .text(function(d) { return d.source.name + " → " + d.target.name + "\n" + format(d.value); });

  var node = svg.append("g").selectAll(".node")
      .data(energy.nodes)
    .enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
    .call(d3.behavior.drag()
      .origin(function(d) { return d; })
      .on("dragstart", function() { this.parentNode.appendChild(this); })
      .on("drag", dragmove));

  node.append("rect")
      .attr("height", function(d) { return d.dy; })
      .attr("width", sankey.nodeWidth())
      .style("fill", function(d) { return d.color; })
      .style("stroke", function(d) { return d3.rgb(d.color).darker(2); })
    .append("title")
      .text(function(d) { return d.name + "\n" + format(d.value); });

  node.append("text")
      .attr("x", -6)
      .attr("y", function(d) { return d.dy / 2; })
      .attr("dy", ".35em")
      .attr("text-anchor", "end")
      .attr("transform", null)
      .text(function(d) { return d.name; })
    .filter(function(d) { return d.x < width / 2; })
      .attr("x", 6 + sankey.nodeWidth())
      .attr("text-anchor", "start");

  function dragmove(d) {
    d3.select(this).attr("transform", "translate(" + d.x + "," + (d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))) + ")");
    sankey.relayout();
    link.attr("d", path);
  }
});

</script>
<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-8592359-13', 'ocks.org');
  ga('send', 'pageview');

</script>

csv2json_sankey.py

# -*- coding: utf-8 -*-

# creates json for sankey from matrix row->column
# 10 -> 3

import json
import csv

# read into data
out = {}
out["nodes"] = []
out["links"] = []
j = 0
with open("zlin4sankey.csv","r") as fin:
  finreader = csv.reader(fin)
  for row in finreader:
    item = {
      'name':row[0] + ' (' + row[1] + ')',
      'color':row[2],
      'j':j,
      'value': int(row[3]+row[4]+row[5])
    }
    out["nodes"].append(item)
    if int(row[3]) > 0:
      out['links'].append({'source':j,'target':10,'value':row[3]})
    if int(row[4]) > 0:
      out['links'].append({'source':j,'target':11,'value':row[4]})
    if int(row[5]) > 0:
      out['links'].append({'source':j,'target':12,'value':row[5]})
    j = j + 1
out["nodes"].append({'name':'Kunčar Patrik Bc. (KDU-ČSL)','color':'#fedc35','j':10,'value':10161})
out["nodes"].append({'name':'Lukáš Libor (ODS)','color':'#008','j':11,'value':5925})
out["nodes"].append({'name':'neúčast','color':'#888','j':12,'value':82931})

with open('sankey_zlin_2014.json', 'w') as outfile:
  json.dump(out, outfile) 

ei_regression.r

A = read.table("round1.csv")
B = read.table("round2.csv")
A = as.matrix(A)
B = as.matrix(B)

# loss functions A -> B, norms L2, L1
fn2 = function(p1) {
     sum((A %*% cbind(matrix(p1,nrow=10),1-apply(matrix(p1,nrow=10),1,sum)) - B)^2) + 10000*(max(apply(matrix(apply(matrix(p1,nrow=10),1,sum),nrow=10),1,max),1)-1)
}
fn1 = function(p1) {
     sum(abs(A %*% cbind(matrix(p1,nrow=10),1-apply(matrix(p1,nrow=10),1,sum)) - B)) + 10000*(max(apply(matrix(apply(matrix(p1,nrow=10),1,sum),nrow=10),1,max),1)-1)
}
# running model A -> B
o1b = optim(p1b,fn1b,control=list(maxit=20000),lower=rep(0,20),upper=rep(1,20),method="L-BFGS-B")
#estimates A -> B
res = cbind(o1$par,1-apply(o1$par,1,sum))
# analytical charts
resid = B - A %*% res
pairs(resid)


#loss function B -> A
fn1b = function(p1) {
     sum(abs(B %*% cbind(matrix(p1,nrow=3),1-apply(matrix(p1,nrow=3),1,sum)) - A)) + 10000*(max(apply(matrix(apply(matrix(p1,nrow=3),1,sum),nrow=3),1,max),1)-1)
}
# running model B -> A
o1b = optim(p1b,fn1b,control=list(maxit=20000),lower=rep(0,20),upper=rep(1,20),method="L-BFGS-B")
#estimates B -> A
resb = cbind(o1b$par,1-apply(o1b$par,1,sum))
# analytical chart:
pairs(A - B %*% resb)

round1.csv

8	8	23	2	0	0	1	5	0	125
24	22	39	5	17	11	3	24	37	836
48	38	79	58	5	7	4	31	8	704
3	5	16	9	3	17	1	22	11	201
7	4	17	3	3	5	0	20	11	239
24	23	37	31	6	14	2	28	26	500
20	12	48	11	6	12	4	17	29	894
11	5	23	45	1	4	3	9	2	91
32	11	6	16	1	3	1	9	3	204
97	15	17	48	0	2	0	20	9	226
19	5	0	1	0	0	0	0	1	30
30	22	7	6	2	3	0	5	1	252
31	16	72	5	2	6	0	14	15	502
11	28	26	9	0	12	2	14	6	468
21	3	26	3	2	16	1	19	13	559
30	192	50	33	1	9	1	10	8	865
50	300	95	45	6	17	5	12	10	1170
33	199	99	21	2	11	1	8	6	905
12	35	9	11	0	2	0	2	3	199
8	23	6	0	0	2	0	3	1	180
7	8	26	6	6	6	1	30	9	466
4	4	24	2	0	2	0	11	2	185
8	16	78	7	1	7	2	5	1	365
3	7	9	19	1	6	0	18	11	344
51	22	52	13	6	43	14	74	35	1161
8	13	2	1	0	2	0	1	0	47
14	15	47	25	1	11	1	5	4	325
15	18	26	6	2	9	0	13	11	362
19	26	8	11	1	4	1	5	4	170
21	3	11	1	0	8	1	5	5	167
36	23	39	19	0	7	1	9	9	306
21	7	12	12	1	7	2	7	8	500
18	24	54	38	10	20	10	27	18	1010
27	44	50	57	5	28	4	39	21	880
26	48	41	55	7	17	5	13	30	900
8	11	18	15	0	5	1	10	7	155
5	9	12	11	1	3	0	10	0	126
4	11	12	7	0	7	1	6	4	189
4	2	15	1	0	1	0	8	0	150
23	49	38	23	4	26	6	90	50	720
14	28	47	27	0	29	9	91	36	875
17	23	19	17	2	18	7	36	27	856
20	36	27	25	6	29	8	53	19	850
22	22	13	13	1	20	2	32	25	902
9	25	15	12	3	17	1	38	8	629
11	67	23	13	3	27	14	38	25	920
29	44	23	8	3	24	55	32	34	850
29	42	6	25	5	37	31	56	19	719
14	51	11	10	2	13	30	18	12	733
15	29	22	26	8	18	13	31	21	725
21	58	26	23	6	15	16	32	9	756
7	44	25	7	6	27	14	26	15	856
15	45	40	9	10	31	8	34	19	957
13	38	17	15	4	16	11	29	26	1269
21	40	29	16	8	26	12	41	21	1707
26	46	34	22	9	15	8	30	22	985
25	44	30	15	7	17	8	41	12	914
18	43	20	14	8	13	38	26	19	1055
17	11	73	8	1	6	1	18	17	488
50	20	46	5	1	0	1	13	4	461
123	28	32	34	5	9	2	17	6	652
90	43	38	32	2	10	2	15	5	820
45	36	9	38	1	20	4	18	3	531
70	32	14	28	2	12	0	20	7	496
67	43	8	26	6	28	1	24	11	667
75	21	23	35	2	6	8	9	5	524
31	6	4	4	0	2	0	2	1	215
19	5	31	7	0	2	1	11	0	345
22	14	65	19	3	8	1	11	11	309
36	32	77	36	9	28	5	56	22	1110
12	11	8	45	0	12	0	6	4	294
22	4	3	0	0	3	0	9	2	157
61	139	91	46	6	7	0	18	6	1045
31	47	21	6	0	1	2	2	12	253
11	37	28	13	5	13	7	50	4	1000
11	29	19	12	2	10	8	38	8	749
9	15	54	10	2	19	2	31	9	463
30	33	42	23	2	6	2	12	34	733
22	6	20	8	0	14	0	12	6	210
207	114	39	69	3	39	6	90	69	258
23	9	24	4	2	2	0	18	8	187
32	2	10	11	0	0	0	9	3	136
8	6	7	1	0	3	2	5	7	162
2	9	5	0	0	5	3	8	8	201
45	17	59	18	6	28	6	37	24	1243
18	14	44	42	1	5	2	13	10	676
18	13	63	31	3	4	0	15	12	728
17	19	72	26	3	24	8	21	29	945
8	5	35	6	1	6	2	10	8	210
25	41	48	199	2	19	1	18	12	677
23	19	30	176	1	25	1	21	6	667
32	42	66	222	3	23	2	43	4	668
1	7	6	18	1	10	0	10	0	208
2	2	4	19	0	11	0	3	0	191
0	3	7	28	0	1	0	11	1	71
18	10	23	15	2	17	2	28	17	456
21	17	29	16	6	9	0	11	11	661
14	18	33	37	1	7	0	38	4	523
9	10	15	5	1	5	0	22	7	242
2	6	80	15	0	5	2	19	7	305
12	14	73	9	0	6	0	17	15	416
2	2	51	9	0	0	1	6	7	183
3	7	5	13	0	21	1	30	11	306
0	5	13	13	0	4	0	10	5	90
97	11	14	40	1	18	0	14	5	259
4	11	9	3	0	11	1	16	6	289
22	12	5	9	2	5	2	28	11	684
1	2	8	25	2	0	0	3	2	128
14	8	92	10	4	13	2	19	11	501
17	29	31	65	2	52	3	31	6	424
14	8	36	12	3	8	1	20	7	489
12	15	57	242	1	22	1	17	13	370
12	12	78	13	0	6	0	29	5	641
3	5	9	132	0	2	1	6	0	212
10	16	20	75	0	6	0	19	1	520
30	8	15	2	1	5	0	16	7	403
1	4	17	11	0	7	0	13	6	153
8	17	54	74	1	4	2	4	8	548
10	7	60	59	0	9	0	11	3	528
32	19	90	15	5	32	6	20	128	979
14	19	35	17	5	11	7	31	14	797
15	28	102	39	6	17	4	38	20	733
13	45	57	32	1	21	10	34	12	706
28	33	98	49	2	11	1	34	8	715
8	19	187	21	1	13	1	16	7	484
8	17	161	21	0	10	1	17	4	583
5	26	153	19	2	11	2	24	2	607
20	33	105	50	8	25	3	43	38	773
17	32	102	45	6	24	13	34	8	1069
9	45	80	38	0	7	1	28	9	809
25	28	110	35	8	11	4	44	12	784
8	27	81	59	5	21	3	26	3	985
16	39	41	24	1	22	2	14	6	624
20	30	79	22	2	15	2	38	6	731
12	46	68	30	2	15	6	29	12	799
2	8	9	14	0	6	2	6	0	114
3	9	2	0	0	0	0	8	0	94
13	19	60	97	5	12	1	28	6	658
1	7	8	2	5	0	1	17	12	198
0	3	13	12	1	1	0	5	1	98

round2.csv

38	5	127
119	9	891
140	79	766
33	12	243
33	3	273
84	38	569
108	17	927
33	61	100
28	42	216
44	66	324
8	7	42
16	13	299
104	15	543
60	11	505
48	8	606
81	60	1062
150	80	1478
153	44	1088
24	21	228
8	3	212
52	11	501
30	0	203
87	24	379
28	32	358
131	25	1316
8	7	59
64	34	349
61	13	388
33	11	205
33	8	181
81	35	330
30	11	536
126	58	1048
116	83	955
109	75	955
42	17	172
15	13	148
28	10	203
19	5	157
86	44	901
113	49	992
64	32	926
91	48	935
52	23	977
36	20	703
95	42	1003
99	21	982
84	37	848
59	9	826
79	21	808
79	32	851
74	15	938
96	21	1051
67	25	1346
105	19	1794
115	39	1044
82	17	1013
75	23	1155
114	19	507
89	7	504
108	73	729
91	71	894
35	74	596
39	77	565
52	81	748
48	65	594
17	23	224
54	11	356
108	27	327
138	60	1210
30	61	300
26	1	174
176	77	1165
46	15	313
80	22	1056
43	18	824
79	35	500
83	37	795
30	16	251
177	147	570
41	28	208
27	36	140
26	2	173
23	9	209
99	37	1341
64	79	691
72	53	768
101	36	1026
45	8	248
92	261	690
63	223	684
108	299	699
24	26	211
11	23	199
6	46	70
40	15	533
54	21	706
61	60	555
36	10	269
108	24	310
88	24	450
65	13	183
11	20	366
16	14	110
63	75	325
25	14	310
50	26	702
14	14	127
97	22	554
77	102	482
59	25	516
95	292	363
97	28	671
15	154	203
28	84	557
38	23	427
33	8	171
67	92	563
58	77	554
155	25	1148
61	18	869
147	72	783
114	47	772
158	61	760
270	46	440
190	39	593
204	21	625
179	93	830
163	79	1109
112	50	860
165	70	823
117	74	1025
89	45	654
121	46	777
139	44	836
23	8	130
4	11	101
113	125	660
17	17	217
22	9	102

sankey.js

d3.sankey = function() {
  var sankey = {},
      nodeWidth = 24,
      nodePadding = 8,
      size = [1, 1],
      nodes = [],
      links = [];

  sankey.nodeWidth = function(_) {
    if (!arguments.length) return nodeWidth;
    nodeWidth = +_;
    return sankey;
  };

  sankey.nodePadding = function(_) {
    if (!arguments.length) return nodePadding;
    nodePadding = +_;
    return sankey;
  };

  sankey.nodes = function(_) {
    if (!arguments.length) return nodes;
    nodes = _;
    return sankey;
  };

  sankey.links = function(_) {
    if (!arguments.length) return links;
    links = _;
    return sankey;
  };

  sankey.size = function(_) {
    if (!arguments.length) return size;
    size = _;
    return sankey;
  };

  sankey.layout = function(iterations) {
    computeNodeLinks();
    computeNodeValues();
    computeNodeBreadths();
    computeNodeDepths(iterations);
    computeLinkDepths();
    return sankey;
  };

  sankey.relayout = function() {
    computeLinkDepths();
    return sankey;
  };

  sankey.link = function() {
    var curvature = .5;

    function link(d) {
      var x0 = d.source.x + d.source.dx,
          x1 = d.target.x,
          xi = d3.interpolateNumber(x0, x1),
          x2 = xi(curvature),
          x3 = xi(1 - curvature),
          y0 = d.source.y + d.sy + d.dy / 2,
          y1 = d.target.y + d.ty + d.dy / 2;
      return "M" + x0 + "," + y0
           + "C" + x2 + "," + y0
           + " " + x3 + "," + y1
           + " " + x1 + "," + y1;
    }

    link.curvature = function(_) {
      if (!arguments.length) return curvature;
      curvature = +_;
      return link;
    };

    return link;
  };

  // Populate the sourceLinks and targetLinks for each node.
  // Also, if the source and target are not objects, assume they are indices.
  function computeNodeLinks() {
    nodes.forEach(function(node) {
      node.sourceLinks = [];
      node.targetLinks = [];
    });
    links.forEach(function(link) {
      var source = link.source,
          target = link.target;
      if (typeof source === "number") source = link.source = nodes[link.source];
      if (typeof target === "number") target = link.target = nodes[link.target];
      source.sourceLinks.push(link);
      target.targetLinks.push(link);
    });
  }

  // Compute the value (size) of each node by summing the associated links.
  function computeNodeValues() {
    nodes.forEach(function(node) {
      node.value = Math.max(
        d3.sum(node.sourceLinks, value),
        d3.sum(node.targetLinks, value)
      );
    });
  }

  // Iteratively assign the breadth (x-position) for each node.
  // Nodes are assigned the maximum breadth of incoming neighbors plus one;
  // nodes with no incoming links are assigned breadth zero, while
  // nodes with no outgoing links are assigned the maximum breadth.
  function computeNodeBreadths() {
    var remainingNodes = nodes,
        nextNodes,
        x = 0;

    while (remainingNodes.length) {
      nextNodes = [];
      remainingNodes.forEach(function(node) {
        node.x = x;
        node.dx = nodeWidth;
        node.sourceLinks.forEach(function(link) {
          nextNodes.push(link.target);
        });
      });
      remainingNodes = nextNodes;
      ++x;
    }

    //
    moveSinksRight(x);
    scaleNodeBreadths((width - nodeWidth) / (x - 1));
  }

  function moveSourcesRight() {
    nodes.forEach(function(node) {
      if (!node.targetLinks.length) {
        node.x = d3.min(node.sourceLinks, function(d) { return d.target.x; }) - 1;
      }
    });
  }

  function moveSinksRight(x) {
    nodes.forEach(function(node) {
      if (!node.sourceLinks.length) {
        node.x = x - 1;
      }
    });
  }

  function scaleNodeBreadths(kx) {
    nodes.forEach(function(node) {
      node.x *= kx;
    });
  }

  function computeNodeDepths(iterations) {
    var nodesByBreadth = d3.nest()
        .key(function(d) { return d.x; })
        .sortKeys(d3.ascending)
        .entries(nodes)
        .map(function(d) { return d.values; });

    //
    initializeNodeDepth();
    resolveCollisions();
    for (var alpha = 1; iterations > 0; --iterations) {
      relaxRightToLeft(alpha *= .99);
      resolveCollisions();
      relaxLeftToRight(alpha);
      resolveCollisions();
    }

    function initializeNodeDepth() {
      var ky = d3.min(nodesByBreadth, function(nodes) {
        return (size[1] - (nodes.length - 1) * nodePadding) / d3.sum(nodes, value);
      });

      nodesByBreadth.forEach(function(nodes) {
        nodes.forEach(function(node, i) {
          node.y = i;
          node.dy = node.value * ky;
        });
      });

      links.forEach(function(link) {
        link.dy = link.value * ky;
      });
    }

    function relaxLeftToRight(alpha) {
      nodesByBreadth.forEach(function(nodes, breadth) {
        nodes.forEach(function(node) {
          if (node.targetLinks.length) {
            var y = d3.sum(node.targetLinks, weightedSource) / d3.sum(node.targetLinks, value);
            node.y += (y - center(node)) * alpha;
          }
        });
      });

      function weightedSource(link) {
        return center(link.source) * link.value;
      }
    }

    function relaxRightToLeft(alpha) {
      nodesByBreadth.slice().reverse().forEach(function(nodes) {
        nodes.forEach(function(node) {
          if (node.sourceLinks.length) {
            var y = d3.sum(node.sourceLinks, weightedTarget) / d3.sum(node.sourceLinks, value);
            node.y += (y - center(node)) * alpha;
          }
        });
      });

      function weightedTarget(link) {
        return center(link.target) * link.value;
      }
    }

    function resolveCollisions() {
      nodesByBreadth.forEach(function(nodes) {
        var node,
            dy,
            y0 = 0,
            n = nodes.length,
            i;

        // Push any overlapping nodes down.
        nodes.sort(ascendingDepth);
        for (i = 0; i < n; ++i) {
          node = nodes[i];
          dy = y0 - node.y;
          if (dy > 0) node.y += dy;
          y0 = node.y + node.dy + nodePadding;
        }

        // If the bottommost node goes outside the bounds, push it back up.
        dy = y0 - nodePadding - size[1];
        if (dy > 0) {
          y0 = node.y -= dy;

          // Push any overlapping nodes back up.
          for (i = n - 2; i >= 0; --i) {
            node = nodes[i];
            dy = node.y + node.dy + nodePadding - y0;
            if (dy > 0) node.y -= dy;
            y0 = node.y;
          }
        }
      });
    }

    function ascendingDepth(a, b) {
      return a.y - b.y;
    }
  }

  function computeLinkDepths() {
    nodes.forEach(function(node) {
      node.sourceLinks.sort(ascendingTargetDepth);
      node.targetLinks.sort(ascendingSourceDepth);
    });
    nodes.forEach(function(node) {
      var sy = 0, ty = 0;
      node.sourceLinks.forEach(function(link) {
        link.sy = sy;
        sy += link.dy;
      });
      node.targetLinks.forEach(function(link) {
        link.ty = ty;
        ty += link.dy;
      });
    });

    function ascendingSourceDepth(a, b) {
      return a.source.y - b.source.y;
    }

    function ascendingTargetDepth(a, b) {
      return a.target.y - b.target.y;
    }
  }

  function center(node) {
    return node.y + node.dy / 2;
  }

  function value(link) {
    return link.value;
  }

  return sankey;
};

sankey_zlin_2014.json

{"nodes": [{"color": "#444", "j": 0, "name": "Ju\u0159en\u010d\u00e1kov\u00e1 Jana Ing. (Nez.)", "value": 10678381182}, {"color": "#f54200", "j": 1, "name": "Kova\u0159\u00edkov\u00e1 Milena Mgr. (\u010cSSD)", "value": 3501953225}, {"color": "#fedc35", "j": 2, "name": "Kun\u010dar Patrik Bc. (KDU-\u010cSL)", "value": 538900}, {"color": "#008", "j": 3, "name": "Luk\u00e1\u0161 Libor (ODS)", "value": 38380}, {"color": "#000", "j": 4, "name": "Mad\u011bra Lud\u011bk Ing. (Pir\u00e1ti)", "value": 343324}, {"color": "#800", "j": 5, "name": "Rafaja Radom\u00edr (KS\u010cM)", "value": 3712351106}, {"color": "#080", "j": 6, "name": "Reme\u0161 Ji\u0159\u00ed (Svobodn\u00ed)", "value": 820451}, {"color": "#0ff", "j": 7, "name": "Tala\u0161 Pavel MUDr. (\u00dasvit)", "value": 9583471722}, {"color": "#808", "j": 8, "name": "Zdr\u00e1halov\u00e1 Lap\u010d\u00edkov\u00e1 Zuzana Mgr. (STAN)", "value": 27701382}, {"color": "#888", "j": 9, "name": "ne\u00fa\u010dast", "value": 168818573784}, {"color": "#fedc35", "j": 10, "name": "Kun\u010dar Patrik Bc. (KDU-\u010cSL)", "value": 10161}, {"color": "#008", "j": 11, "name": "Luk\u00e1\u0161 Libor (ODS)", "value": 5925}, {"color": "#888", "j": 12, "name": "ne\u00fa\u010dast", "value": 82931}], "links": [{"source": 0, "target": 10, "value": "1067"}, {"source": 0, "target": 11, "value": "838"}, {"source": 0, "target": 12, "value": "1182"}, {"source": 1, "target": 10, "value": "350"}, {"source": 1, "target": 11, "value": "195"}, {"source": 1, "target": 12, "value": "3225"}, {"source": 2, "target": 10, "value": "5389"}, {"source": 3, "target": 11, "value": "3838"}, {"source": 4, "target": 10, "value": "34"}, {"source": 4, "target": 11, "value": "3"}, {"source": 4, "target": 12, "value": "324"}, {"source": 5, "target": 10, "value": "371"}, {"source": 5, "target": 11, "value": "235"}, {"source": 5, "target": 12, "value": "1106"}, {"source": 6, "target": 10, "value": "82"}, {"source": 6, "target": 12, "value": "451"}, {"source": 7, "target": 10, "value": "958"}, {"source": 7, "target": 11, "value": "347"}, {"source": 7, "target": 12, "value": "1722"}, {"source": 8, "target": 10, "value": "277"}, {"source": 8, "target": 12, "value": "1382"}, {"source": 9, "target": 10, "value": "1688"}, {"source": 9, "target": 11, "value": "185"}, {"source": 9, "target": 12, "value": "73784"}]}

zlin4sankey.csv

Juřenčáková Jana Ing.,Nez.,#444,1067,838,1182
Kovaříková Milena Mgr.,ČSSD,#f54200,350,195,3225
Kunčar Patrik Bc.,KDU-ČSL,#fedc35,5389,0,0
Lukáš Libor,ODS,#008,0,3838,0
Maděra Luděk Ing.,Piráti,#000,34,3,324
Rafaja Radomír,KSČM,#800,371,235,1106
Remeš Jiří,Svobodní,#080,82,0,451
Talaš Pavel MUDr.,Úsvit,#0ff,958,347,1722
Zdráhalová Lapčíková Zuzana Mgr.,STAN,#808,277,0,1382
neúčast,,#888,1688,185,73784