Customizing the CartoLayer style
The rendering options available to specify the style for a CartoLayer depend on the way the spatial information is stored. The CARTO platform supports spatial data defined using two different methods:
Data stored as traditional geometries defined by longitude-latitude coordinate pairs
Data stored using geospatial indices from a discrete global grid system like H3 or Quadbin
When working with traditional geometries, the CartoLayer uses deck.gl GeoJsonLayer for rendering. All the rendering options from the GeoJsonLayer can be used to customize the styling properties of your
When working with data using geospatial indices, the layer used for rendering depends on the discrete global grid system used:
If you are using the
CartoLayerwith data stored as [H3 indices]((https://docs.carto.com/analytics-toolbox-bigquery/overview/spatial-indexes/#h3), the H3HexagonLayer is used.
This guide mainly focus on working with traditional geometries but most of the rendering properties used are also available in the spatial indices layers and most of the content is applicable to them.
In this guide you will learn about the main options available and how to use them to create great visualizations. We have added links to the properties documentation in the main deck.gl docs site that includes useful information like data type or default values.
Basic rendering options
These options are used to indicate basic styling properties and the availability of some of them depends on the type of feature geometry:
This option controls the feature opacity. By default features are opaque but you can control the layer translucency through this option.
With this option you indicate if you want to draw filled polygons. It is also used to indicate if you want to draw filled circles when you have point features and the
'circle'. It is not applicable to line features.
getFillColor accessor to understand how to specify the color for your features.
This option is used to indicate if you want to draw the outline for polygon features. If is also used to indicate if you want to draw the circle outline when you have point features and the
'circle'. Line features are stroked by default and this option is not applicable to them.
This option is used to indicate if you want to extrude the polygon features. It is not applicable to point or line features.
See the Extrusions section for additional guidelines.
Accessors are properties that allow us to have fine grain control of the visual configuration applied to features. They are a powerful instrument to create advanced visualizations.
We can set the accessor property to a function and this function will be executed for each one of the features. This function must return a data type compatible with the property: for instance if you are specifying a color (
getLineColor), you must return an RGB[A] array; if you are specifying the circle radius or the line width, you must return a number.
For most of the accessors we can also specify a constant value (an array, a number…) and the same value will be applied to all the features. The performance is better if you use constant values because deck.gl does not need to evaluate a function for each feature.
In this section we are going to describe the most common accessors but you can find the complete list of accessor supported by the
GeoJsonLayer in the deck.gl docs site.
You can use these accessors to create advanced visualizations, including choropleth maps, like the ones available with the style helpers, and proportional symbol maps. You can also use them to apply different styles depending on the current zoom level.
This accessor is used to specify the fill color in RGBA format for polygon features. It can be used also with point features when the
This accessor is used to specify the color for line features. If the
stroked property is set to
true, it can be used also to specify the circle outline color with point features when the
'circle' and the polygon outline color with polygon features.
This accessor is used to indicate the line width for line features. If the
stroked property is set to
true, it can be used also to specify the circle outline width with point features when the
'circle' and the polygon outline width with polygon features.
This accessor is used to indicate the elevation of polygon features when
extruded is set to
The CartoLayer uses vector rendering. This means the feature geometry is available client-side so we can easily know if the user is hovering over a feature and highlight it.
The color to be used for highlighting is specified using the
highlightColor property. This property is an accessor: you can specify a color to be used always or you can decide which color to use depending on the feature and current visualization properties.
If you set the
autoHighlight property to
true, the feature hovered will be highlighted with the color specified by the
We can also manually highlight a feature using the
When working with point features, the
GeoJsonLayer allows to render the points using circles, icons, and texts, or a combination of them, using the
The actual property names might be different in the
GeoJsonLayer when comparing with the names in the layer used for rendering: for instance, the
getPointRadius accessor is called
getRadius in the
ScatterplotLayer. In this section, we are using the
GeoJsonLayer property names and we are linking to the specific property documentation in the deck.gl docs site.
There are different properties available to control the visual configuration depending on the render mode; here we describe the most important ones.
When using circles for visualizing point features you need the use the
getPointRadius accessor to set the radius for the circle (by default in meters) or you can just set the
pointRadiusMinPixels property. There are also additional properties to specify the units, scale or maximum radius.
This accessor is used to indicate the radius for point features. It can be used to create proportional symbol maps as shown below.
This property allows to specify the minimum radius in pixels to use for circles. By default is 0, so you need to set it to some positive value or the circles won’t be visible.
If you set the
pointType property to
'icon', you can then use icons to style your point features. If you have multiple icons, the most efficient approach is to use an icon atlas with pre-packed icons and the corresponding mapping with icon positions in the atlas. You can also specify individual URLs to fetch icons.
Please check the Icon Layer example to see how you can use pre-packed icons.
You can use this accessor to specify the icon to use. If you use an icon atlas with icon mappings, you will specify here the icon name in the mapping. If you don’t use an icon atlas, you should return an object with the URL to fetch. Please refer to the documentation for the complete specification.
This is the accessor used to specify the icon height in pixels, unless you specify a different unit. By default the value is 1, so you want to set it to the actual height size. It can be used also to create a proportional symbol map where the icon size varies according to the value of some feature property or to implement zoom based styling where the icon size is adapted to the current zoom level.
This property lets you specify the icon atlas to use when using pre-packed icons. You will usually specify the URL to the atlas resource, but you have also other options that you can check in the documentation.
You will use this property to specify the icon mapping in the atlas when using pre-packed icons. You can specify an object with the required properties or the URL to fetch a JSON file with this information.
The third option to style point features is to render text labels. We can specify many properties such as the color, angle, font family or font size.
This accessor is used to retrieve the text to use in the label.
Extruded polygons in a 3D visualization can help the users to understand better the information they are exploring. Using deck.gl is straightforward to extrude polygon features. You just need to set the
extruded property to
true and use the
getElevation accessor to specify the height for each feature. This accessor expects a value in meters if you are using the default
You can provide the same
getElevation value for all features but you will usually want to make the
getElevation accessor dependent on some feature property. For instance, if we have a layer with polygon features representing building footprints and we have a property indicating the building height, we can use the value of this property to extrude buildings according to their heights.
Depending on the feature property values, you might want to scale them to visualize the information in a more meaningful way. You can use the
elevationScale property to achieve that.
Please check the extrusion example to see how you can extrude polygon features.
If you want to create a choropleth map or a proportional symbol map, you can use absolute scaling or distribute the features in classes. In the first case, the color and/or size of a feature in the map is proportional to the value of some property or combination of properties. In the second case, values are classified according to a classification rule.
There are many classification rules that can be used like equal intervals, jenks natural breaks or classification by quantiles. The choice of classification rule depends on the data and has a great impact on the visualization. These rules can be implemented using accessors like
getPointRadius but you need to be able to calculate the thresholds for each class.
The CartoLayer only works with vector tiles so only the information corresponding to the current viewport and zoom level is downloaded to the client. You can only determine the information needed to calculate the thresholds (min, max, quantiles…) for the whole dataset if the server provides them.
If you already have the information you need to calculate thresholds, you can do this client-side. You can perform the threshold calculations yourself but our recommendation is to use a library that already implements this functionality such as d3-scale. This library includes support for many different scales such as linear, threshold, quantile or quantize scales.
These scales map the domain of values into a range. The range can be an array of colors in RGB[A] format if you want to create a choropleth map or an array of numbers if you want to create a proportional symbol map.
For example, if you want to create a choropleth map with a quantize (equal intervals) scale with five different classes, you must specify an array with five colors and the domain for your values. In this case we are going to apply the colors to places with a population between 1 million (1e6) and 1 billion (1e9). We need to use the
getFillColor accessor to retrieve the corresponding color for each feature property value:
CartoLayer you are using vector tiles, so you just have in the client the data for the current viewport. You cannot calculate thresholds taking into account the whole dataset. In this case, you have only two options: use the statistics provided by the map server (if available) or implement your own calculations using the data from the source table.
If you are going to visualize a static tileset created with the CARTO Analytics Toolbox, the tileset metadata includes information about quantiles for each property. You can retrieve this information using the
onDataLoad handler that receives the tileset metadata in TileJSON format as the argument.
If you are using dynamic tiles, you can use the Stats API. You can make a request with the table or query that you are going to use and it is going to return some statistics useful for calculating scales and defining classes.
Choropleth maps are created assigning different colors to features representing geographic areas such as countries or neighborhoods. Color assignment depends on the value of some property or a combination of two properties (bivariate choropleth map).
If you have a numeric property, you have two options: you can apply a classification rule as shown above to create classes or bins for your data or you can use absolute scaling and map the values to a color ramp.
If you already have a string property that represents a categorical or qualitative variable, you can use this property as the class and assign a color to each of the possible property values.
It is important to choose a color palette adequate to the type of choropleth map / variable you are using. We have defined a set of data-driven color schemes called CARTO Colors that you can use in your choropleth maps.
There is a set of schemes appropriate to represent numeric values from low to high (sequential schemes). We provide another set suitable for visualizing categorical differences in qualitative data (qualitative schemes). Finally, we also have defined diverging schemes for those cases where we have an interesting mid-point when using quantitative data.
But you can also take advantage of the style helpers provided in the CARTO for deck.gl module. These helpers make it really easy to implement a choropleth map using numeric bins (colorBins helper), qualitative data (colorCategories helper), or using a color ramp to map numeric values (colorContinuous helper).
These style helpers allow you to specify the feature property you want to use to create the choropleth, the domain of values for that property and the colors you want to use. The colors can be specified using an array or using a string with the CARTO colors palette name.
Take a look at the Styling examples section to see how you can use these style helpers.
Proportional symbol maps
Proportional symbol maps assign a larger or smaller symbol to features depending on the value of some property. If you use a circle as the symbol, they are sometimes known as bubble maps.
You can also combine proportional symbol maps with style helpers that symbolize the features using different colors. For example, we are going to create a map where we represent the population of each country using a bubble map and then assign a different color to each circle depending on the country continent.
In this case we are going to use absolute scaling (no classes/bins) and we are going to assing a different circle radius to each feature based on the
pop_2015 property. In the
getPointRadius accessor we need to define the formula for calculating the radius for each feature. The maximum symbol size (radius in pixels) is going to be 30 pixels and the radius for each country is going to be proportional to the square root of the population, so we scale it between 0 and 1 using the square root (~27620) of the country with the biggest population (China). We are going to have fixed size symbols that do not scale with the zoom level so we need to define the
pointRadiusUnits as pixels (by default is meters).
Please check the complete example here.
Zoom based styling
When creating visualizations, sometimes we need to define different styling properties like symbol sizes depending on the zoom level. With deck.gl it is easy to apply zoom-based styling using the available accessors.
We need to listen to the onViewStateChange event and re-render our layer when it is fired. We can store the zoom level in a variable so we can use it later in the layer accessors:
Then, in the
renderLayer function we define our layer and update the
layers property in the DeckGL object. The process is the following:
- Define the accessors that will depend on the current zoom level
- Set the updateTriggers property so the radius is recalculated when the zoom level changes
- Update the
For instance, in the previous example that shows how to create a proportional symbol map, we can make the radius size for points depend on the zoom level:
You can check a complete example using zoom-based styling here.