Search code examples
pythonmatplotlibscatter-plotshapefilematplotlib-basemap

How to convert the information from a shapefile from polygon to lat/lon


I need to make a scatter plot over a map. I have the shapefile to plot the map but I need to convert the information of shapefile (polygon) to lon and lat coordinates. This is my code:

borough = gpd.read_file('London_Borough_Excluding_MHW.shp')
borough.crs #{'init': 'epsg:27700'}
crs = {'init': 'epsg:27700'}
gdf = gpd.GeoDataFrame(
    df2, crs=crs, geometry=gpd.points_from_xy(df2.lat, df2.lon))

ax = gdf.plot(marker='*', markersize=0.2)
borough.plot(ax=ax)
plt.show

Now I get this plot: plot

My df2 looks like this: $type additionalProperties children childrenUrls commonName id lat lon placeType url

0   Tfl.Api.Presentation.Entities.Place, Tfl.Api.P...   [{'$type': 'Tfl.Api.Presentation.Entities.Addi...   []  []  River Street , Clerkenwell  BikePoints_1    51.529163   -0.109970   BikePoint   /Place/BikePoints_1
1   Tfl.Api.Presentation.Entities.Place, Tfl.Api.P...   [{'$type': 'Tfl.Api.Presentation.Entities.Addi...   []  []  Phillimore Gardens, Kensington  BikePoints_2    51.499606   -0.197574   BikePoint   /Place/BikePoints_2

My shapefile look like this:

NAME    GSS_CODE    HECTARES    NONLD_AREA  ONS_INNER   SUB_2009    SUB_2006    geometry
0   Kingston upon Thames    E09000021   3726.117    0.000   F   None    None    POLYGON ((516401.6 160201.8, 516407.3 160210.5...
1   Croydon E09000008   8649.441    0.000   F   None    None    POLYGON ((535009.2 159504.7, 535005.5 159502, ...
2   Bromley E09000006   15013.487   0.000   F   None    None    POLYGON ((540373.6 157530.4, 540361.2 157551.9...

Solution

  • I just downloaded the shpfile and scatter data..you just need to properly convert the CRS

    FYI the data source states that the scatter data is in WGS1984 (EPSG 4326)

    import geopandas as gp
    import pandas as pd
    
    s = gp.read_file('London_Borough_Excluding_MHW.shp')
    s['geometry']=s['geometry'].to_crs({'init':'epsg:4326'})
    
    df2 = gp.GeoDataFrame(df, crs = {'init':'epsg:4326'}, geometry = gp.points_from_xy(df['lon'],df['lat'])) #where df is your df with the scatter data
    
    
    ax = s.plot()
    df2.plot(ax=ax,color='red')
    

    result (I didn't plot all points, needed an API key so I just copied your snippet of the data)

    enter image description here

    EDIT - labelling boroughs (you'll have to format to make it prettier)

    X = s['geometry'].representative_point().x 
    Y = s['geometry'].representative_point().y 
    L = s['NAME'] 
    for x,y,l in zip(X,Y,L): 
        plt.text(x,y,l)