# Mapping parliamentary results (categorical data) by share of polygon in QGIS

I'm trying to recreate the fill effect in this map: Where each polygon is filled based on the percentage of vote each parliamentary party gained. The author wrote "I converted the inner polygons into raster data format and applied a pixel-counting technique to create subdivisions of accurate size." Source

I'm hoping to do this with QGIS, I have polygons with the number of votes each party has gotten in a different election. I can convert them to raster polygons, but I'm not sure how to color them and achieve the "stripe" effect.

Also I believe this data is "categorical" but correct me if there is a different term I should be using.

• You are correct: the data would be considered categorical (also called nominal) because there is no intrinsic ordering to the categories (we can't say Party A > Party B). With categorical data you have limited options for meaningful numerical operations - probably the most common being to compute the proportions compared to the whole dataset (like you have here). – Dave G Jun 12 '18 at 22:55
• While the technique must be super interesting, that map is hideous. Legibility of the results for each riding is not great. – Gabriel C. Jun 13 '18 at 0:42
• I kind of like the look of the map. This should be possible as data defined symbology. But I think there will be quite a lot of conditional statements... Lots of work. – HeikkiVesanto Jun 13 '18 at 0:47
• Might be more legible kept to 3: elected party, opposition party, other parties – Dave G Jun 13 '18 at 0:49

## 1 Answer

My first cut at an algorithm in (mostly) pseudocode; pretty rough, but hopefully illustrates an idea on how you might approach it.

Essentially, you generate your raster polygons where each electoral region has a different integer value starting at 1. You determine the number of pixels in each region for each party. Then you iterate over the polygons.

For each polygon, use index slicing to get the subset according to its bounding box and unravel it into one dimension. Then iterate on the values, replacing+ the ones that are part of the polygon with different values according to the election results. Then you reshape it back to the bounding box and replace+ the subset back into the original raster.

+Actually, rather than replacement I use separate arrays for the input and output.

Caveat -> this approach would result in horizontal lines that do not extend fully across the polygons:

``````000000000001111111
111111111111111122
222222222222222222
``````

Note that you'll need to set the raster resolution according to the precision you want to display (e.g., if you want to be able to show to the nearest percent, you'll need a minimum of 100 pixels in the smallest polygon).

``````; import vector polygons
; get num_polygons
; perform inward-oriented buffer as mentioned in the paper (?)
; compute polygon bounding boxes (bbox_coords)
; rasterize polygons (vary raster cell values by polygon: 1, 2, ... num_polygons)
; get histogram of raster polygons (i.e., num pixels in each)
; compute num pixels for each party for each raster polygon (pixel_values)
; convert raster into numpy ndarray (unlabled_polygons)
party_polygons = np.zeros((unlabled_polygons.shape), dtype=int); array to hold output
for polygon_n in num_polygons:
; get pixel_values list and bbox_coords for given polygon
; use bbox_coords & slicing to subset given polygon (subset_array)
unraveled = np.ravel(subset_array, order='C')
party_subset = np.zeros((unraveled.shape), dtype=int)
for UR, PS in zip(np.nditer(unraveled), np.nditer(party_subset)):
ind = 0
if UR == polygon_n: ; if pixel is part of current polygon
PS == pixel_values[ind] ; write party code to unravelled party_subset
ind = ind + 1 ; advance index
; otherwise pixel is other polygon, outside map, or part
of inner buffer, so leave unravelled party_subset as 0
and do not advance index
party_subset.reshape((subset_array.shape))
; element-wise addition of party_subset to full party_polygons array
(any values in party_subset not part of current polygon will be 0,
so won't affect their neighbours) use slicing (see reference)
; convert party_polygons ndarray into a raster
``````

Adding different sized/shaped displaced NumPy matrices

• I think you'll want to perform the inward-oriented buffer (also called a negative buffer) before rasterizing the polygons. – csk Jun 13 '18 at 16:31
• @csk; good call - edited accordingly – Dave G Jun 13 '18 at 21:06