A Python package for integrating CARTO maps, analysis, and data services into data science workflows.
We will no longer support Data Observatory within this version of CARTOframes from the 1st of January 2021. We strongly recommend using the latest version of CARTOframes for the best experience.
Map creation in cartoframes happens through the CartoContext.map
method. This method takes a list of map layers, each with independent styling options. The layers can be a base map (BaseMap
), table layer (Layer
), or a query against data in the user’s CARTO account (QueryLayer
). Each of the layers is styled independently and appear on the map in the order listed. Basemaps are an exception to this ordering rule: they always appear on the bottom regardless of its order in the list.
To create a map with only the BaseMap
, do the following:
1
2
3
4
5
6
from cartoframes import CartoContext, BaseMap
cc = CartoContext(
base_url='<your_base_url>',
api_key='<your_api_key>'
)
cc.map(layers=BaseMap())
Or more simply, the last line can be made simpler because a base map is added by default if one is not provided:
1
cc.map()
This produces the following output:
To get a custom view, pass the longitude, latitude, and zoom as arguments to cc.map
:
1
cc.map(lat=34.7982209, lng=113.6489703, zoom=11)
To change the base map style to CARTO’s ‘dark matter’, pass 'dark'
to the BaseMap
class:
1
cc.map(layers=BaseMap('dark'))
For a light base map, change the source to 'light'
.
Remove labels with labels=None
or put them in back with labels='back'
.
To add a data layer to your map, first find a table you want to visualize.
We’re going to use the NYC Taxi dataset from cartoframes examples, which you can put into your account with this snippet:
1
2
3
4
5
6
7
from cartoframes.examples import read_taxi
# write taxi data to your account, setting the geometry as pickup location
cc.write(
read_taxi(),
'taxi_50k',
lnglat=('pickup_longitude', 'pickup_latitude')
)
See the cartoframes Quickstart to cover basics used here.
1
2
3
4
cc.map(layers=[
BaseMap('dark'),
Layer('taxi_50k', color='fare_amount')
])
Maps can be created from arbitrary queries of tables you have in your account. With our example taxi dataset, you may have noticed that there are two sets of long/lat coordinates: one for pickup location, another for dropoff location. We can use this information to draw a straight-line path and get this length. Of course, the real route would be more useful, but this isn’t in the data. We could simulate it with CARTO’s routing functions, but we’ll stick with the simpler example of straight-line paths for demonstration.
In this example, you’ll notice a few features:
ST_MakeLine
from points created with the cartodb-postgresql helper function CDB_LatLng
](https://github.com/CartoDB/cartodb-postgresql/blob/master/scripts-available/CDB_LatLng.sql)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from cartoframes import QueryLayer
cc.map(
QueryLayer('''
SELECT
ST_Transform(the_geom, 3857) AS the_geom_webmercator,
the_geom,
cartodb_id,
ST_Length(the_geom::geography) AS distance
FROM (
SELECT
ST_MakeLine(
CDB_LatLng(pickup_latitude, pickup_longitude),
CDB_LatLng(dropoff_latitude, dropoff_longitude)
) AS the_geom,
cartodb_id
FROM taxi_50k
WHERE pickup_latitude <> 0 AND dropoff_latitude <> 0
) AS _w
ORDER BY 4 DESC''',
color='distance'),
zoom=11, lng=-73.9442, lat=40.7473,
interactive=False)
QueryLayer
s are a great way to take advantage of the relational database underlying CARTO without creating new datasets. For resource-intensive operations, it is recommended to first create a new dataset for visualization with Layer
as it will offer better performance and be less likely to hit platform limits. To create new tables from queries, use CartoContext.query('<query>', table_name='<new_table_name>')
.
To add more than one layer to your map, add them in the order you want the layers to display. Here we’re adding a base map using a light styling, a polygon layer of poverty rates in Brooklyn, and the taxi data for fares above $50 sized by the amount.
1
2
3
4
5
6
7
8
cc.map(layers=[
BaseMap('light'),
Layer('brooklyn_poverty', color='poverty_per_pop'),
QueryLayer(
'SELECT * FROM taxi_50k WHERE fare_amount > 50',
size='fare_amount'
)
])
To style by size variable, use the size
keyword at the layer level for each layer passed. This only work for point data.
This sizes each point the same size (3 pixels wide):
1
cc.map(layers=Layer('taxi_50k', size=3))
To size by a variable, pass a column name instead of a number:
1
2
3
4
5
cc.map(
layers=Layer(
'taxi_50k',
size='fare_amount'
))
Just like the color
keyword, the size option can take a dictionary.
1
2
3
4
5
6
7
8
9
10
11
cc.map(
layers=Layer(
'taxi_50k',
size={
'column': 'fare_amount',
'min': 2,
'max': 10,
'bin_method': 'headtails'
}
)
)
Your results will look as follows:
Styling values by color is similar to styling by size but using the color
keyword in the Layer object instead. Color by value works for points, lines, and polygons.
Using the brooklyn_poverty
dataset, we can style by poverty_per_pop
:
1
2
from cartofrmaes import Layer
cc.map(Layer('brooklyn_poverty', color='poverty_per_pop'))
To specify a specific color scheme, we can expand the argument to color and using some of the color utility functions in the styling
module:
1
2
3
4
5
6
7
8
from cartoframes import Layer, styling
cc.map(
Layer(
'brooklyn_poverty',
color={'column': 'poverty_per_pop',
'scheme': styling.sunset(7)}
)
)
To style a map with time, use the time
keyword on a numeric or time field in your dataset. Here we use the US Geological Survey data feed on earthquakes which has a time
column.
To get this data into your CARTO account with CARTOframes, do the following:
1
2
3
import pandas as pd
eq_url = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.csv'
cc.write(pd.read_csv(eq_url), 'usgs_all_month')
To visualize the data in time, specify the column that has the time information (in this case time
). We can also style by color. Here we’re using the net
column which is a category.
1
cc.map(Layer('usgs_all_month', time='time', color='net'))