Choroplethmapbox with discrete colors (in clientside Dash callback)


I am attempting to plot a choropleth chart using mapbox… and I am actually able to, but it is a heatmap and I wanted it to be a discrete color map. The way I implemented it is working, but I wanted to have a legend and not a colorscale.

The two alternatives I think make sense are:

  1. actually figure out how to create a streets-style choroplethmapbox with discrete colors;
  2. Draw the legend over the map.

Alternative 2 could work, but the legend becomes awkward when the user pans about the map. So, if there is no way to fix a drawing on the plot window, the only real alternative is 1.

For a reduced example of what I have now, all inside a Dash callback:

    quality_map: {
        'Bad': 0.0,
        'Normal': 0.5,
        'Good': 1.0,
    color_map: [
        [0.0, '#ec4035'],
        [0.5, '#f8cf32'],
        [1.0, '#55b848'],
    color_code: {
        'Bad': '#ec4035',
        'Normal': '#f8cf32',
        'Good': '#55b848',
    create_plot: function (data_cache) {
        const cache = JSON.parse(data_cache);
        let colors = [];
        for (const q of cache.quality){
        var Figure = {'data': [], 'layout': {}};
        Figure['layout'] = {
            'mapbox': {
                'accesstoken':'my access token',
        Figure['data'] = [{
            'marker':{'opacity': 0.5},
            'hovertemplate': '%{location}<br>Value: %{customdata}<extra></extra>',
            'showscale':false, // Don't show colorscale. I need a discrete legend!
        Figure.layout['title'] = {
            'text':'My map',
            'x': .5,
            'y': .95,
            'xanchor': 'center',
            'yanchor': 'top'
        Figure.layout['titlefont'] = {
            'size': 24
        return [Figure];

data_cache is a stringified JSON containing:

*geoJSON, array of geoJSONs to determine each region’s poligon;
*locations, array with the locations’s names;
*quality, array with the tags for determining the colors;
*value, array with values for the hover;
*center, JSON with lat and lon values;

I wanted to use color_code instead, following what I understood from plotly’s documentation, but it just fails to draw the polygons or uses a default colorscale whenever I do anything different from the code above.

Any help would be appreciated! :slight_smile:

Just found out that Choropleth charts with discrete color should have a data element for each value, so you have to push to your array the good, the normal and the bad objects, something like:

for (var color in color_code) {
            'marker':{'opacity': 0.5},
            'colorscale': [[0.0, color_code[color]], [1.0, color_code[color]]],
            'locations': filter(cache.locations, color), // FILTER THE LOCATIONS
            'z': [1, 1, ..., 1], // AS MANY 1 AS THE SIZE OF THE LOCATIONS

in this snipper im assuming that there is a function filter(array, string) that filters from the locations array the elements that doesn’t belong to the color

1 Like