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:
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
; 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