Skip to content

Issue using branca colormap with folium.raster_layers.ImageOverlay #1571

@ipritchard

Description

@ipritchard

Describe the bug
Exhausted my troubleshooting - I believe this is in fact a bug, hopefully I'm not wrong!

I think there is a bug attempting to use a branca colormap (of type branca.colormap.LinearColormap) with an ImageOverlay raster layer. Here is the error I receive when running the code below:

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_26316/1517857374.py in <module>
     13 
     14 # Add the raster overlay to the map
---> 15 image = folium.raster_layers.ImageOverlay(
     16         name="Random Image",
     17         image = rand_img,

c:\users\ianmp\git_repos\ce-api-endpoint-tests\venv\lib\site-packages\folium\raster_layers.py in __init__(self, image, bounds, origin, colormap, mercator_project, pixelated, name, overlay, control, show, **kwargs)
    258             )
    259 
--> 260         self.url = image_to_url(image, origin=origin, colormap=colormap)
    261 
    262     def render(self, **kwargs):

c:\users\ianmp\git_repos\ce-api-endpoint-tests\venv\lib\site-packages\folium\utilities.py in image_to_url(image, colormap, origin)
    137         url = 'data:image/{};base64,{}'.format(fileformat, b64encoded)
    138     elif 'ndarray' in image.__class__.__name__:
--> 139         img = write_png(image, origin=origin, colormap=colormap)
    140         b64encoded = base64.b64encode(img).decode('utf-8')
    141         url = 'data:image/png;base64,{}'.format(b64encoded)

c:\users\ianmp\git_repos\ce-api-endpoint-tests\venv\lib\site-packages\folium\utilities.py in write_png(data, origin, colormap)
    200     if nblayers == 1:
    201         arr = np.array(list(map(colormap, arr.ravel())))
--> 202         nblayers = arr.shape[1]
    203         if nblayers not in [3, 4]:
    204             raise ValueError('colormap must provide colors of r'

IndexError: tuple index out of range

To Reproduce

Below is a self-contained code snippet which reproduces the issue. I have substituted in a random numpy array (of a particular size) to replace a raster image I was using so that you can easily reproduce this. The error is the same using either the raster or the random array.

import branca
import branca.colormap as cm
import folium
from folium import plugins
import numpy as np

# Create an array of random values to simulate a raster image array
rand_img = np.random.rand(333, 443)

# Set the image bounds (WGS84 lon/lats)
bbox = [-128.5831, 31.3986, -112.7140, 43.0319]

# Create a folium map object
m = folium.Map(location=[39.3, -118.4], zoom_start=5, height=500)

# Define a Branca colormap for the colorbar
vmin = 0.2
vmax = 0.8
palette = ['red', 'orange', 'yellow', 'cyan', 'blue', 'darkblue'][::-1]  
cmap = cm.LinearColormap(colors=palette,
                         vmin=vmin,
                         vmax=vmax,
                         caption='Image Colormap')

# Add the raster overlay to the map 
image = folium.raster_layers.ImageOverlay(
        name="Random Image",
        image = rand_img, 
        bounds=[[bbox[1], bbox[0]], [bbox[3], bbox[2]]],
        interactive=True,
        colormap=cmap,
        overlay=True)

image.add_to(m)

# Add a layer control panel to the map
m.add_child(folium.LayerControl())
m.add_child(cmap)

# Add fullscreen button
plugins.Fullscreen().add_to(m)

# Display the map
display(m)

Expected behavior
I expected the image to appear on the folium map, with a color palette as specified (dark blue values for 0.2 and below, red values for 0.8 and above, and other values linearly spaced in between).

Environment (please complete the following information):

  • Jupyter Notebook
  • Python version 3.9.5
  • folium version 0.12.1.post1 (also experienced on 0.12.1)
  • branca version 0.4.2

Additional context
If you remove the colormap from the folium.raster_layers.ImageOverlay() call, the image plots just fine on the map, and the colormap will appear as a colorbar, but the image will just be in greyscale.

Possible solutions
No solutions yet, but I think the error lies in the line identified in the stack trace (l212 in utilities.py).

If nblayers is already known to be 1 (mono/singleband image, i.e. a NxM array), I am not sure why it grabs the array shape (which at this point is single-dimensional) and tries to reset the nblayers value.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugAn issue describing unexpected or malicious behaviourwork in progressWork is in progress on a PR, check the PR to see its status

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions