4

I have created a map using GeoPandas with a few markers that represent some coordinates on the map. I want to do draw a circle around each marker with the marker placed in the center of the circle.

This is what the map looks like: enter image description here

This is pretty much what I am trying to do (a circle around each yellow marker): enter image description here

This is my code so far:

#I have a pandas DataFrame called address_df that has a long and a lat column

address_df['geometry'] = address_df.apply(
lambda x: Point((x.long, x.lat)), axis = 1)

#changing to geopandas
geo_df = gpd.GeoDataFrame(address_df, crs=crs, geometry= address_df.geometry)

#the in_cou is a geoDataFrame that I read_file from a .shp file
in_cou.geometry = in_cou.geometry.to_crs(epsg = 3857)
geo_df.geometry = geo_df.geometry.to_crs(epsg = 3857)

#Joining datasets
cou_hos = gpd.sjoin(in_cou, geo_df, how="inner", op='intersects')

#The figure is create using matplotlib 
fig, ax = plt.subplots(figsize=(15,15))
minx, miny, maxx, maxy = in_cou.total_bounds

ax.set_xlim(auto=True)
ax.set_ylim(auto=True)
ax.set_aspect('auto')
#Thicks left empty for cosmetic reasons 
plt.xticks([])
plt.yticks([])
plt.title("Providers",fontsize=40,y=1.04, x= .55)

plt.rcParams['font.size'] = 20
cmap1 = ListedColormap(['#2f7d50'], name='allred')
cmap2 = ListedColormap(['#a0a8a3'], name='allblue')

#Plot the first layer of the map. 
in_cou.plot(ax=ax, edgecolor='black',cmap = cmap1, legend = False, alpha =0.9)
cou_hos.plot(ax=ax, edgecolor='black',cmap = cmap2, legend = False,alpha = 0.9)

#Plot the second layer of the map. The yellow plus markers. 
geo_df.plot(ax=ax, marker="P",edgecolor='k', markersize=150,alpha= 0.8, c= '#ffff00', label= "Providers" ) #geo_df['Type'].apply(lambda x: colors[x]))
plt.legend(prop={"size": 19},bbox_to_anchor=(0.56, -.09), loc='lower center', ncol=3)

plt.show()

I have created this function based on what I found in a previous question (https://gis.stackexchange.com/a/359748/166972). It creates a circular polygon based on a given latitude, longitude, and a radius (The radius is also a column with int values) :

def max_poly(lat, long, dist):
    lon, lat = long, lat # lon lat for San Francisco
    radius = dist  # in m

    local_azimuthal_projection = "+proj=aeqd +R=6371000 +units=m +lat_0={} +lon_0={}".format(lat, lon)
    
    wgs84_to_aeqd = partial(
        pyproj.transform,
        pyproj.Proj("+proj=longlat +datum=WGS84 +no_defs"),
        pyproj.Proj(local_azimuthal_projection))
    

    aeqd_to_wgs84 = partial(
        pyproj.transform,
        pyproj.Proj(local_azimuthal_projection),
        pyproj.Proj("+proj=longlat +datum=WGS84 +no_defs"))

    center = Point(float(lon), float(lat))
    point_transformed = transform(wgs84_to_aeqd, center)
    buffer = point_transformed.buffer(radius)
    

    circle_poly = transform(aeqd_to_wgs84, buffer)
    return circle_poly

Then I create a new geoDataFrame with polygons created by max_poly

crs = {'init':  'epsg:3857'}
new_df = gpd.GeoDataFrame(crs=crs, geometry=geo_df.apply(
    lambda x: max_poly(x.lat, x.long, x.max_dis_trav), axis = 1))

But plotting new_df does not work.

3
  • Welcome to Geographic Information Systems! Welcome to GIS SE! We're a little different from other sites; this isn't a discussion forum but a Q&A site. Your questions should as much as possible describe not just what you want to do, but precisely what you have tried and where you are stuck trying that. Please check out our short tour for more about how the site works.
    – Ian Turton
    Jul 12, 2020 at 10:01
  • can you tell us more about why and how "plotting new_df does not work"?
    – Ian Turton
    Jul 12, 2020 at 10:01
  • Thanks Ian! I am reviewing the tour and will update my question accordingly. Meanwhile, @Urban87's answer workes well for my need! Jul 13, 2020 at 15:12

1 Answer 1

6

What you want: Create a circle from the center of each marker

This can be easily solved with geopandas buffer functions.

You can see the description here.

#make circle from point
new_df = geo_df.copy()
new_df['geometry'] = new_df['geometry'].buffer(size)
3
  • This works pretty well! I am not very familiar with mapping systems in general. What is the unit for the buffer size? Is it meter? Thanks btw! Jul 13, 2020 at 15:10
  • @ArashZakeresfahani It depends on the CRS(new_df.crs). Usually it will be a meter.
    – Urban87
    Jul 14, 2020 at 0:05
  • @ArashZakeresfahani you have defined your CRS as EPSG:3857, and yes: the unit of this projected coordinate system is the metre, see epsg.io/3857
    – marianoju
    Mar 7, 2023 at 20:47

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.