I have a set of 1000 coordinates, with each representing the urban centres of a particular state. These towns belong to one of 20 counties and I know which towns belong to which county. I wish to shade a map based on data I have for each county. For example, if a county has a value of 100% then I wish to color this county dark red, if a county is associated with 0% then I will color this part of the map white.
I don’t have the boundaries for each county since these are old counties and it would involve a huge amount of work to trace the boundaries from old maps. I have the boundaries of the state including islands and lakes etc.
So here is the data I have:
Town1 50.1,4.89 County1
Town2 49.9,4.78 County1
Town3 50.3,4.59 County1
Town4 50.2,4.99 County1
Town5 50.0,4.99 County1
...
Town1000 57.0,8.33 County20
and
County1 100%
County2 100%
County3 68%
...
County20 0%
as well as the state boundaries.
Solution1: So, one approach to create my desired map might be to create polygons around each coordinate (town), with this polygon representing all the area on the map closest to this town, and closer to no other town. Then I color this polygon according to the data of its county.
Solution2: Perhaps a better approach would be to blend colors between towns. So if I have two adjacent towns in different counties, one with 100% and one with 0%, then the half way point between them would be coloured pink (half way between dark red and white).
So I wish to programatically produce this map in the form of an image file where this file is easily scalable and where I can import it into the likes of Photoshop in order to add other elements. Would you recommend SVG in this case?
What library or algorithm might I use to produce the polygons as required in Solution 1?
Is there a library I can use to produce an SVG document with a gradient like mesh as required by Solution 2?
I wish to use Python3 if possible but I am open to other languages. I am also open to other solutions and alternatives to SVG.
I am using MacOS.
3
Answers
Your first approach is called a Voronoi diagramm
See the description in wikipedia
There is a solution for this kind of diagramms using D3 library for javascipt
D3 approach
Just to make this solution complete, I am pasting here the code from M.Bostock example
Your second solution is easily achievable with OpenGL and Gouraud shading, but then it’s not easy to export it to SVG (or to anything else beyond a bitmap). I will think about any alternative to it.
While there are powerful frameworks for generic data representation, the proper tool for this particular task is GIS. I’ll try explain how to do this in QGIS.
Create a CSV file with your data in the following format:
Add it as a CSV (Delimited Text) layer
Customize the style of created layer to get a heatmap like you describe in your second variant.
Create a Voronoi polygons from this layer
Customize the style of newly created layer to get regions of each county colored by the different colors.
To create an SVG from current map:
Project -> New Print Layout
Click the “Add a new map to the layout” button on the tool panel, draw the large rectangle of map to place it on the layout.
Click “Export as SVG”
That’s all.
Black-to-transparent heatmap over Voronoi polygons – https://svgshare.com/s/5MZ.
Heatmap only – https://svgshare.com/s/5ND.
Script which I used to generate data – https://gist.github.com/ei-grad/1355223cd8a3c6ba16deb454ddef50b4.
For Solution1 in python, you can use Voronoi Diagrams in scipy. The following code (a modified version of this SO post) creates a voronoi diagram, draws it using different alphas according to the values of each country and saves it to image
Map.png
:Your points should be loaded in the
points
variable in line 7 and the country’s percentages in thevalues
variable in line 8.