# Creating buffer rings of equal population size using ArcMap

I am trying to create a shapefile of equal population size buffer rings. Similar to the procedure of creating multi-ring buffers of distance around a point, find the intersects of the buffers with a polygonal layer, and then dissolve with the required statistics (e.g. https://support.esri.com/en/technical-article/000010582).

I have a point layer (Atlanta) and a polygon layer (Atlanta metropolitan area census block groups). I want to create a new polygon layer of equal population size (say 5% of total population) rings around the point layer, using population attribute from the census block groups. So a total of 20 rings around the city, each equal of 5% of population. Distance and area of each ring obviously differs.

So far I have tried to use ArcMap Grouping Analysis and modifying the process in the link above.

Any suggestions on how to implement this?

I can use Python for this if needed.

I expect to have an output similar to this:

• Population equality is significantly more complex than travel time, each census tract has a set population, including it adds that value to the cluster but there will be a point where the population accumulation is exceeded which then onflows to the next and next.. until the last band has way less than 5%. Finding the seed location is also a challenge, do you take town hall, geographic centre or mean feature? You could start from the outside and work in, iterating an inside buffer which will lead to a central point that may not be what you'd pick... not a trivial task by any means! Commented Oct 7, 2020 at 7:51
• Thanks for your quick reply @MichaelStimson. Indeed not a trivial task, though I was sure someone did it before me. Just for clarification, city centre will be city hall. From there I want to create buffers of block groups with equal population (5% of total pop). I was thinking on creating multi-ring buffer of DISTANCE every 500m. Then, using intersect and dissolve, calculate the population in each ring, and then aggregate adjacent rings hold 5% of population (or as close to it). The cons of this methods that it required strong computational capabilities, which I don't have access to. Thanks.
– ALCZ
Commented Oct 7, 2020 at 9:04
• If you're going to do it that way you need to express the population as an area, population per square unit (ppsu) then intersect/union multiple ring buffer (~25m should be suitable), calculating the intersecting area and then expanding ppsu * area to estimate the population of the fragment then dissolve the rings using estimated population as a statistic field then interactively select the dissolved rings from the centre in an edit session and dissolve as soon as you get within tolerance of the 5% threshold. It will require some processing power but should process over a weekend. Commented Oct 8, 2020 at 0:08
• Yes, exactly what I had in mind, though I hoped someone will come up with a better (faster) solution.
– ALCZ
Commented Oct 8, 2020 at 5:15

Reasonably accurate results can be achieved without much iterations. Create 100 travel polygons with same small step to cover entire area. I did it via computing travel raster:

and raster calculator `Int(travel/1499.816772)`

Assuming that population spreads evenly over Census meshblock area:

Intersect it with travel polygons and summarize population in intersection bits pro-rata their area vs meshblock area. Accumulate population in travel belts into new column and convert to percentage of total:

Next step is to find intersection points on the TravelDistance(Percentage) curve for given break points, e.g. 5,10,15...100:

and draw relevant contours on travel distance raster:

I used following script to derive contour values, although they can be computed using paper and pen from values in travel belts table:

``````import arcpy
import numpy as np
tbl = arcpy.da.TableToNumPyArray("BELTS",("PERCENT","TRAVEL"))
breaks = np.linspace(10, 100, 10)
contourList =[]
for breakValue in breaks:
level=np.interp(breakValue,tbl["PERCENT"],tbl["TRAVEL"])
contourList.append(level)
arcpy.gp.ContourList_sa(arcpy.Raster("TRAVEL"), "C:/SCRATCH/Contours", contourList)
``````
• That is an awesome metric, combining main roads network and population for a visually appealing result, more interesting than concentric circles radiating out from a centre point. Hopefully this meets the OP's needs and they don't need concentric circles for some sort of modelling. +1 from me and I'll tuck this away into my box of tricks, I'll whip it out when needed and look like a genius. Commented Oct 8, 2020 at 7:20
• Wow, thanks a lot @FelixIP, it looks great and much simple than what I intended to do. I got it all right, except your first fig. Could you please elaborate on how you created the travel raster?
– ALCZ
Commented Oct 8, 2020 at 8:10
• Are you dealing with travel distance of straight crow fly? Commented Oct 8, 2020 at 8:50
• Hi, yes I am. road network is not required.
– ALCZ
Commented Oct 8, 2020 at 8:56
• Use euclidean distance to point. Commented Oct 8, 2020 at 8:58