#!/usr/bin/env python # coding: utf-8 # # Shapely, Geopandas, and CARTOframes # # This notebook demonstrates how to use `cartoframes` with [GeoPandas](http://geopandas.org/), a popular Python package for working with geospatial data in a local environment. It's built on some of the same robust libraries as PostGIS which underlies CARTO's spatial analysis, so compliments CARTO extremely well. # Get started by creating a `CartoContext` that allows you to interact with CARTO in the notebook enviroment. # In[2]: get_ipython().run_line_magic('matplotlib', 'inline') from cartoframes import CartoContext, Credentials import geopandas as gpd import pandas as pd # In[3]: # set carto credentials creds = Credentials(key='abcdefg', username='cartoframes') creds.save() cxn = CartoContext() # ## Reading and writing data from/to CARTO # # To get started, let's use the `nat` dataset which contains county-level criminology data for the United States from 1960 onwards. # In[4]: # load data into your account from cartoframes.examples import read_nat # write `nat` to your CARTO account cxn.write(read_nat(), 'nat') # download it and decode geometries df = cxn.read('nat', decode_geom=True) # In[5]: df.head() # By default, CARTO uses Well-known-binary (WKB) serialization for geometries that come out of PostGIS. # In[5]: df.head(2)[['fipsno', 'the_geom']] # These strings can be deserialized into `shapely` objects that work with GeoPandas. # In[6]: df.head(2)[['fipsno', 'geometry']] # This allows you to do GIS operations locally in Geopandas. To send a DataFrame with shapely geometries into a Geopandas DataFrame, you only need to call the constructor directly on the DataFrame: # In[7]: gdf = gpd.GeoDataFrame(df) gdf.plot('hr90', linewidth=0.1) # to prove we're in geopandas # The nice thing with having the code to serialize/deserialize `shapely` objects is that you can publish directly to CARTO (and make CARTO maps) directly from (geo)pandas: # In[8]: from cartoframes import Layer, styling cxn.map(layers=Layer('nat', color={'column': 'hr90', 'scheme': styling.sunset(7)}), interactive=False) # You can also create interactive versions of the above map by setting `interactive=True`. # # **Note:** If viewing this notebook on GitHub, the interactive map will not display. Checkout this same [notebook rendered on nbviewer](https://nbviewer.jupyter.org/github/CartoDB/cartoframes/blob/master/examples/Shapely%2C%20Geopandas%2C%20and%20Cartoframes.ipynb) instead. # In[10]: from cartoframes import Layer, styling cxn.map(layers=Layer('nat', color={'column': 'hr90', 'scheme': styling.sunset(7)}), interactive=True) # GeoPandas DataFrames can be written to CARTO just like pandas DataFrames. # In[11]: cxn.write(gdf, encode_geom=True, table_name='cartoframes_geopandas', overwrite=True) # If you change the geometries locally, the changes propagate back to CARTO: # In[12]: gdf['geometry'] = gdf.geometry.apply(lambda x: x.buffer(2)) df['geometry'] = df.geometry.apply(lambda x: x.buffer(2)) # In[13]: cxn.write(gdf, encode_geom=True, table_name='cartoframes_geopandas_buffered', overwrite=True) # In[14]: gdf.head() # In[16]: from cartoframes import BaseMap, Layer cxn.map(layers=[BaseMap('light'), Layer('cartoframes_geopandas_buffered', color='gi69')], interactive=False)