简体   繁体   中英

Upgrading from bokeh==2.1.1 to bokeh==2.2.0 breaks figure.image_rgba()

This snippet of code renders an image (albeit upside-down) when using bokeh==2.1.1 :

from PIL import Image
import numpy as np
import requests

from bokeh.plotting import figure
from bokeh.io import output_notebook
from bokeh.plotting import show
output_notebook()

response = requests.get('https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg', stream=True)
rgba_img = Image.open(response.raw).convert("RGBA")
numpy_img = np.array(rgba_img)

fig = figure()
plotted_image = fig.image_rgba(image=[np_img], x=50, y=50, dw=50, dh=50)
show(fig)

Running the exact same code in bokeh==2.2.0 (as well as later versions) outputs nothing, and doesn't raise any errors.

bokeh's release notes does not mention any changes to image_rgba()

The error is in the JS console in the browser (because the error actually occurs in the browser, not on the "python side"):

Unhandled Promise Rejection: Error: expected a 2D array

And if you look at np_img , you can see it is not a 2D array:

In [3]: np_img.shape
Out[3]: (297, 275, 4)

In [4]: np_img.dtype
Out[4]: dtype('uint8')

Bokeh expects a 2D array of uint32, not a 3D array of uint8, and this has always been the case, and what has been demonstrated in the docs. It's possible this a 3D array was accepted accidentally or unintentionally in the past (which is why no change would be noted in the release notes), or it's possible that something has changed on either the NumPy or PIL side with conversions to NumPy arrays. Regardless, you will need to create a 2D view:

np_img = np.array(rgba_img)

np_img2d = np_img.view("uint32").reshape(np_img.shape[:2])

fig = figure()
plotted_image = fig.image_rgba(image=[np_img2d], x=50, y=50, dw=50, dh=50)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM