The way I’ve typically seen mapboxgl fill properties work on choropleth maps is something like this:
map.on('load', function () {
map.addSource('bb', { type: 'geojson', data: data, generateId: true});
map.addLayer({
'id': 'berlin',
'type': 'fill',
'source': 'bb',
'paint': {
'fill-color': {
'property': some_numeric_val,
'stops': [[4, '#feebe2'], [8, '#fbb4b9'], [12, '#f768a1'], [16, '#c51b8a'], [20, '#7a0177']]
},
'fill-opacity': .65
}
});
map.addLayer({
'id': 'berlin-stroke',
'type': 'line',
'source': 'bb',
'paint': {
'line-color': '#000',
'line-width': [
'case',
['boolean', ['feature-state', 'hover'], false],
2,
.5
]
}
});
});
i.e. the colors are created based on a property that the user selects. However, it seems like mapboxgl’s default behavior is to interpolate colors. For example, if one of my geographic units has a value is somewhere between the breakpoints, mapboxgl will interpolate the color, resulting in a gradient of colors.
Is there a way to make the colors distinct (non-interpolated)? i.e. if value is 4 or less, the color is #feebe2, if the value is 8 or less, the color is ‘#fbb4b9’, for a total of 5 discrete colors in the example I have here.
I have not been able to find an answer to this anywhere. Thanks.
2
Answers
Instead of
stops
, you can usematch
.In the example provided above,
match
comparessome_numeric_val
to each value and returns the color if there’s a match. If there isn’t, it returns a default color that you can set.EDIT: To also include a value between the specified range of values you have to preprocess the data first.
Here’s an example of how:
You can use step expressions.
Syntax
Reference : Sample example from mapbox which demonstrate similar requirement as mentioned in question.
You can try updating your code like below.