I am using ArcMap 10.4.1.

I have several point shapefiles containing different occurrence data for two different species of flower (from multiple sources, hence the multiple shapefiles). I want to create a buffer from a central point that includes a quantity of at least 50 each of each species. I'm familiar with the general buffer tool, so for example, I can create a buffer of a certain size and clip to it, but what I'm hoping to do is create a buffer that contains at least 50 occurrences of each species regardless of the size, from a certain point (i.e. a city).

I'm hoping this can actually be done in ArcMap? I've been searching Stack Exchange and elsewhere, and can't find this anywhere.

I've attached a screenshot of what the occurrence distribution looks like. Attribute tables consist simply of long/lat values. One of the species I am studying is protected, so I can't get more detailed than that. The primary study site is a natural area just outside of a major city, so we chose the city as an arbitrary "central point" to create the buffer from.

As of now, I have eight sources providing occurrence data, so eight different point shapefiles, that I created - so they should all be the same. I have an "Advanced" license, and the following extensions: 3D Analyst, ArcScan, Geostatistical Analyst, Network Analyst, Publisher, Schematics, Spatial Analyst, Tracking Analyst.

Screenshot of occurrence distribution

  • @PolyGeo, Thanks for the suggestion, I edited the original post to include additional information and italicized my edits. I did search through the past Q&As but also couldn't find anything relevant to what I'm looking to do. Commented Feb 9, 2018 at 6:08
  • @PolyGeo, on an unrelated note, I recognize that I am new to this forum, but why did you choose the edits that you performed on my post? The edits seem to be based on your own personal style choice, and very minor, I don't even see how they improved readability. Commented Feb 9, 2018 at 6:10
  • Do you have an example of your data? Just a screen shot of the attribute table / distribution of the points. There are a number of variables in your question which may influence the answers you are given. Do you have an idea / link between the distribution of flowers and the central point you want to buffer from? What license / extensions for ArcMap do you have? Are your different shapefiles set up the same? Commented Feb 9, 2018 at 6:55
  • 1
    Those changes were more than personal style because most of them involved Esri and Stack Overflow brand names. Unlike a discussion forum our focused Q&A site is more akin to a wiki of Q&As about GIS so I think making them look professional is important.
    – PolyGeo
    Commented Feb 9, 2018 at 10:02
  • 1
    Please don't italicize edits because they are already evident in the question's revision history.
    – PolyGeo
    Commented Feb 9, 2018 at 11:04

3 Answers 3


I created a Tool a while back which I was using to find people in proximity to boreholes. Tweaking it I have something you can use.

Create a text file and save it as "Species.py", copy the code below into it. The code is messy, as it has been butchered from my old code.

import arcpy
import os

arcpy.env.overwriteOutput = True
arcpy.env.workspace = "in_memory"

source = arcpy.GetParameterAsText(0)
PopPoint1 = arcpy.GetParameterAsText(1)
PopPoint2 = arcpy.GetParameterAsText(2)
OutPutFolder = arcpy.GetParameterAsText(3)
SPP1 =arcpy.GetParameterAsText(4)
SPP2 =arcpy.GetParameterAsText(5)
Interval = arcpy.GetParameterAsText(6)
Distance = 1

x = 1

arcpy.AddMessage('Population Difference ' + str(x))

# SPP 1

while x <= int(SPP1):
    arcpy.SelectLayerByLocation_management(PopPoint1, "WITHIN_A_DISTANCE",source, Distance , "NEW_SELECTION")
    pop = int(arcpy.GetCount_management(PopPoint1).getOutput(0))

    arcpy.AddMessage("Selected " + str(pop) + "Looking for Spp1:  " + str(SPP1))
    arcpy.AddMessage("Increasing buffer to " + str(Distance))
    Distance += int(Interval)
    x = int(pop)

    arcpy.AddMessage("x is: " + str(x))
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]

Out1 = "in_memory" + "\\Spp1Final"


# SPP 2
x = 0
Distance = 1
pop = 0
while x <= int(SPP2):
    arcpy.SelectLayerByLocation_management(PopPoint2, "WITHIN_A_DISTANCE",source, Distance , "NEW_SELECTION")
    pop = int(arcpy.GetCount_management(PopPoint2).getOutput(0))

    arcpy.AddMessage("Selected " + str(pop)+ "Looking for Spp2: " + str(SPP2))
    arcpy.AddMessage("Increasing buffer to " + str(Distance))
    Distance += int(Interval)
    x = int(pop)

    arcpy.AddMessage("x is: " + str(x))

Out2 = "in_memory" +"\\Spp2Final"
Out3 = OutPutFolder

inMerge = Out1 + " ; " + Out2
arcpy.Merge_management(inMerge, Out3)

Once copied into the *.py file, save it.

Open ArcMap and Open your "Catalog" window. Scroll to your working directory and right-click on a folder where you can save a Toolbox. From the right click menu select "New" then "Toolbox". Give it a name. Then in this newly created Toolbox, right click and "Add a script".

Give the script a name and fill in the details as you wish. Click next. Where it asks for a script file, choose the *.py you just saved.

The next screen is VERY important. See below:

enter image description here

From line 1 to 7

  1. Input City: Data Type - Feature Layer ; Type - Required ; Direction - Input
  2. Species 1: Data Type - Feature Layer ; Type - Required ; Direction - Input
  3. Species 2: Data Type - Feature Layer ; Type - Required ; Direction - Input
  4. Output File: Data Type - Shapefile ; Type - Required ; Direction - Output
  5. Lines 5 6 are the number of species you are looking for. The Data Type are all Double. This lets you change the number of species you want per species type (in case you need to later on).
  6. Line 7 is how much you want to increease the search distance by on each iteration. Data Type is Double ; Type - Required ; Direction - Input

Running the Tool

Once you have set up the Toolbox, double click the Tool. Select your input point (the point from which you want the buffer drawn). This can only be a single point, do not use a point file with more than 1 point. I haven't tested it on a selection, but there is no harm in trying.

Select your 1st Species Select your 2nd Species

Select where you want the output buffer saved

select the number of Species 1 you want to find Select the number of Species 2 you want to find Select the increment in distance you want the buffer to grow (the search distance). Bearing in mind the smaller the increment the more accurate the final counts will be, but the longer the tool will take. The final output is a combined buffer of the maximum distance required to meet the species count you have identified.

Notes The dataframe and all data within the map must be the same projection. The units of the project must be a distance unit - I use the metric system, so I have only tested this with metres. The final output may be off by 1 or 5 counts. This is due to the increment of the search distance.

Use this as a starting point at least.

  • Thanks for this, @KeaganAllan. I will start working with this and see where I get. Commented Feb 9, 2018 at 19:20

One option could be using spatial analysis toolset. You can first convert your points to a binary raster where there is any occurrence of species it gets 1 and you can use Focal Statistics tools by SUM operator. Then you can test your proximity definition (i.e., neighbourhood), which would be circle until you find the maximum value of 50.

  • Thanks for this suggestion. I'm not familiar with these processes, so I will have to do some reading before trying this. Commented Feb 9, 2018 at 7:38

I assume you'd like to pick minimum distance from town that will contain at least 50 birds of each specie. I suggest using NEAR (analysis) tool for that.


enter image description here


arcpy.Near_analysis("merged_species", "TOWN")
arcpy.Sort_management("merged_species","./species_sorted.shp", "NEAR_DIST ASCENDING")
arcpy.AddField_management("species_sorted", "GROUP_NO", "LONG")

Use field calculator from here to populate above field by sequential number for indiv.specie.

arcpy.SelectLayerByAttribute_management("species_sorted","NEW_SELECTION",""""GROUP_NO" = 5""")

This is your answer (5 birds at least in below example): enter image description here

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.