X/Y coordinates in pandas dataframe to map

9189
12
07-25-2017 07:20 AM
DavidRalston
New Contributor II

Is there a way to add x/y coordinate columns in a pandas dataframe to a map using the arcgis python api in jupyter notebook?

0 Kudos
12 Replies
RohitSingh2
Esri Contributor

Yes, an example is below:

locations = []
path = r'C:\xc\Presentations\GeoPython\Watson\insulators'
# find locations of broken insulators
for file in listdir(path):
    filepath = path + '\\' + file
    if is_broken(filepath):
        locations.append(get_location(filepath))    

# import into ArcGIS as a layer
df = pd.DataFrame.from_records(locations)
df.columns = ['x', 'y']
broken_insulators = gis.content.import_data(df)

m.add_layer(broken_insulators)

I have defined get_locations to return longitude, latitude:

def get_location(filename):    #...         return lon, lat
DavidRalston
New Contributor II

Awesome! My code looks like this: 

gis = GIS()
data[['Longitude_X', 'Latitude_Y']]
layer = gis.content.import_data(x)
print (layer)
map = gis.map('UK')
map.add_layer('layer')
map

data is a pandas dataframe

<FeatureCollection>

The layer is a feature collection, but the lat long data doesn't show on the map. Possible reasons why?

0 Kudos
RohitSingh2
Esri Contributor

Try setting the columns of your dataframe to x and y. The following works:

from arcgis.gis import *
import pandas as pd

gis = GIS()
m = gis.map('UK')

locations = [(52.47867, -1.90848), 
 (51.50642, -0.12721),
 (53.79480, -1.54653),
 (53.47959, -2.24874)]

df = pd.DataFrame.from_records(locations)
df.columns = ['y', 'x']
cities = gis.content.import_data(df)
m.add_layer(cities)
m

I get the following output:
ManushiMajumdar
Esri Contributor

Is there a way to do this with a df that has more than 1000 rows? This script throws an error for that case..

0 Kudos
IonutAlixandroae4
Occasional Contributor

If it`s something that deals with memory you should give it a try with increasing the iopub_data_rate_limit; i had this kind of problem with viewing more that a few pictures.

iopub rate limits are too low by default, for visualization-heavy projects · Issue #2287 · jupyter/n...  

jupyter notebook --NotebookApp.iopub_data_rate_limit=10000000000 

Ionut

0 Kudos
ManushiMajumdar
Esri Contributor

Thanks Ionut!
It still gives me the error (Error Code: 401): UnAuthorized

RohitSingh2
Esri Contributor

If there are more than 1000 rows, you should convert it to a SpatialDataFrame. You can do it like this:

df['SHAPE'] = df.apply(lambda row : arcgis.geometry.Geometry({'x': row['x'], 'y': row['y']}), axis=1 )

sdf = SpatialDataFrame(df)

layer = gis.content.import_data(sdf, title='My Data')

 

m.add_layer(layer) # add to map

find_nearest(layer, ...) # use for analysis

ManushiMajumdar
Esri Contributor

Thanks Rohit!
The exact same code snippet is giving me an error -

RuntimeError: Service name 'a' already exists for 'bkrWlSKcjUDFDtgw'

I don't know how to debug it since I don't have services with that name/id..

0 Kudos
RohitSingh2
Esri Contributor

There's a bug in import_data that creates a service by the name 'a' the first time it runs... the fix will be in the next update, but as a workaround you should be able to search for that service and delete it each time you're calling import_data with a spatial dataframe.